2016-06-13 125 views
3

任何人都可以請解釋第一個例子和第二個例子有什麼區別嗎?聲明的「未定義」值和未聲明的「未定義」值之間有什麼區別?

聲明的「未定義」值和未聲明的「未定義」值之間有什麼區別?

代碼

var arr = new Array(4); 
arr[0] = "a"; 
arr[1] = "b"; 
arr[2] = undefined; //insert undefined here! 
arr[3] = "d"; 
console.log("arr[2] is " + arr[2]); //yes, it is undefined! 

arr.forEach(function(value, index) { 
    console.log(index + ":" + value); 
}) 

console.log("====================") 

var arr = new Array(4); 
arr[0] = "a"; 
arr[1] = "b"; 
//I don't insert undefined to arr[2] in this case. 
arr[3] = "d"; 
console.log("arr[2] is " + arr[2]); //yes, it is undefined! 

arr.forEach(function(value, index) { 
    console.log(index + ":" + value); 
}) 

登錄

arr[2] is undefined 
0:a 
1:b 
2:undefined 
3:d 
==================== 
arr[2] is undefined 
0:a 
1:b 
3:d 

附加實施例

var arr = new Array(4); 
arr[0] = "a"; 
arr[1] = "b"; 
arr[2] = undefined; //insert undefined here! 
arr[3] = "d"; 
console.log("arr[2] is " + arr[2]); //yes, it is undefined! 

var i = 0; 
var max = arr.length; 
for(i; i < max; i++) { 
console.log(i + ":" + arr[i]); 
} 

console.log("====================") 

var arr = new Array(4); 
arr[0] = "a"; 
arr[1] = "b"; 
//I don't insert undefined to arr[2] in this case. 
arr[3] = "d"; 
console.log("arr[2] is " + arr[2]); //yes, it is undefined! 

var i = 0; 
var max = arr.length; 
for(i; i < max; i++) { 
console.log(i + ":" + arr[i]); 
} 

日誌

arr[2] is undefined 
0:a 
1:b 
2:undefined 
3:d 
==================== 
arr[2] is undefined 
0:a 
1:b 
2:undefined 
3:d 
+2

一個被初始化(在JS中我們說'聲明')但未定義;一個是不初始化和undefined – jeremy

+0

可能重複[是JavaScript數組稀疏?](http://stackoverflow.com/questions/1510778/are-javascript-arys-sparse) – Ramanlfc

+1

@Ramanlfc這不是重複的那個問題。 OP很清楚這方面的內容 – jeremy

回答

0

JavaScript數組不是常規數組。在大多數語言中,陣列(又名向量)是內存中連續的區域。但在JS中,它們相當稀疏的容器 - 有些元素可能不存在。

在JS其實陣列只是對象(鍵/值映射),差別在於整數鍵被允許:

var arr = {}; // object (key/value map), not array, sic! 
arr[0] = "a"; 
arr[1] = "b"; 
// arr[2] deliberately omitted 
arr[3] = "d"; 
console.log("arr[2] is " + arr[2]); // it is undefined 

您甚至可以添加非整數鍵JS數組:

var arr = []; 
arr[0] = 0; 
arr["zero"] = "zero"; 

這證明數組是引擎蓋下的對象。

當您嘗試從某個容器(對象或數組)的值中獲取不存在的鍵值時,它會返回undefined值。按ECMAScript規範。

arr[2] = undefined將該值分配給鍵2.

delete arr[2]刪除該密鑰和它的值。

+1

「,區別在於允許使用整數鍵」---這是模糊的(而不是100%正確的):1.它們仍然被轉換爲字符串2.對象也可以保存「數字」鍵。 – zerkms

+0

數組是否「在內存中連續」或不相關。所有對象都允許使用整數鍵,而不僅僅是數組(如你所說,它只是具有特殊長度*屬性的對象和一些大部分通用的方便的繼承方法,並且也可以應用於其他對象)。 – RobG

+0

@RobG「所有對象都允許使用整數鍵」。在ES5中爲負面,請嘗試https://jsfiddle.net/ok3b4tg8/。對象中的索引是嚴格的字符串。即使你將使用數值,它將被轉換爲字符串。 'Object.keys()'不能返回任何東西,除了字符串的矢量。 –

3

請問誰能解釋第一個例子和第二個例子有什麼區別?

在第一個例子:

var arr = new Array(4); 

創建具有長度爲4的陣列,它沒有元素。

然後,值被分配給使用直接分配索引0到3:

arr[0] = "a"; 
arr[1] = "b"; 
arr[2] = undefined; //insert undefined here! 
arr[3] = "d"; 

這產生0至3 未定義被分配給arr[2]性質。 for each遍歷存在的元素,因此您可以看到所有4個元素的結果,每個元素都有一個值。

在第二個示例中,您不要將值分配給arr[2]。當訪問一個對象的不存在的屬性(注意到數組是對象)時,返回未定義的值,例如,

var obj = {}; 
console.log(obj.foo) // undefined 

的forEach遍歷性質,不存在性能沒有到過,所以沒有輸出arr[2]。這與對於循環形成對比,其通常被編寫爲訪問從0到length - 1的所有屬性,因此返回該範圍內的所有屬性的值,無論它們是否存在。

+0

感謝您指出了foreach和for之間的區別。現在我很清楚! – hytm

+0

@ Hayatomo - 您可能希望查看MDN上的[* forEach * polyfil](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Polyfill),它遵循ECMA-262中的步驟並且在步驟7.b處具有自己的特性測試(這是[* ECMAScript 2015 *]中的步驟8.b.(http://www.ecma-international.org/ecma-262 /6.0/#sec-array.prototype.foreach)和6.b [* ECMAScript 2017 *](https://tc39.github.io/ecma262/#sec-array.prototype.foreach))。 – RobG