2016-06-13 124 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