首页 > 关于犀牛第7章的稀疏数组

关于犀牛第7章的稀疏数组

今天看犀牛学数组,看到么一个地方,不是很清楚,自己研究了好久,还是不懂,所以想在这里提问,请大神解答。下面我详说。
首先上一张图,犀牛7.6章:

有两句话我一直没听懂,总感觉相互是矛盾的,

注意:当在数组直接量中省略值时不会创建稀疏数组

当省略数组直接量中的值时(使用连续的逗号,比如[1,,3]),这时所得到的数组也是稀疏数组

这是我个人的疑问1,还有疑问2,我打代码如下。

window.onload=function(){
    var a1 = [,,,];
    var a2 = [,];
    console.log(a1);
    console.log(a2);
    console.log(a1 + '---' + a1.length);
    console.log(a2 + '---' + a2.length);
    console.log(a1[0]);
    console.log(a2[0]);
}

输出的是

[]
[]
,,---3
---1
undefined
undefined

首先都是打印a1和a2,怎么上下加了个别的东西,就变成不同的东西了呢,这部分关于JS是怎么转换的啊。
再者就是我本以为会看到[undefined,undefined,undefined]也没有。我感觉我理解的有问题,却又不知道问题出在哪,请大神帮帮忙。谢谢。


数组的本质还是对象,稀疏数组才是常态。

只不过length属性在内部特化了一下,你取到的值永远是最大的键加一。只要键的个数和length不匹配,它就是稀疏数组。

由此你可以测试:

var arr = [1,,,3];
console.log(arr.length); //4
for(var i in a) console.log(i); // 0 2

显然它是稀疏的。

js里面有太多的办法把一个东西变成稀疏数组了,除了上面的省略值和扩充行为,delete一个键也会让数组变成稀疏数组:

arr = [0,1,2];
delete arr[1];

尽信书不如无书!

我先指出书中一个错误(也可能是浏览器实现问题):

var a1 = [,,,];
0 in a1 // 输出false

跟你书中的结果不一样!

所以,你给出的图中,从第二个红框开始,下面的内容基本都是不正确的。

另外,你说的那个疑问,我觉得跟console.log的内部实现有关。这个东西本来就是浏览器附带的一个打印的辅助api,我觉得你没必要过分研究。比如同一个东西,在chrome和ie下用console.log打印出来经常不一样。

至于第三个console.log出来的两个逗号,是数组的toString方法被调用得来的。

建议一下题主,既然你想彻底弄懂,那么一可以自己多做实验,而是去看规范。规范表述的一定是最全面和精准的,如果你肯花时间把规范研究一下,书中的那些内容自然全都懂了。

https://es5.github.io/#x15.4


早上六点多睡醒的时候就看到题主这个问题,真是被这个题目折磨了一早上啊。
1、先来回答第一个,引用在CSDN上查到的一个答案:

英文原版里面只有楼主说的这段代码

var a1 = [,,,]; // This array is [undefined, undefined, undefined]
var a2 = new Array(3); // This array has no values at all
0 in a1 // => true: a1 has an element with index 0
0 in a2 // => false: a2 has no element with index 0

这个地方作者描述返回true。我在浏览器中测试的结果和你相同。

但是在中文版本中(淘宝团队翻译)加入了下面的话:
“需要注意的是,当省略数组直接量中的值时(使用连续的逗号,比如[1,,3]),这时所得到的数组也是稀疏数组,省略掉的值是不存在的:”
然后给出例子:

var a1 = [,]; // 此数组没有元素,长度是1
var a2 = [undefined]; //……
0 in a1 // => false: a1 在索引0处没有元素
0 in a2 // => true: a2 在索引0处有一个值为undefined的元素

然后还添加了下面这段话: “在一些旧版本的实现中(比如Firefox
3),在存在连续逗号的情况下,插入undefined值的操作则与此不同,在这些实现中,[1,,3]和[1,undefined,3]是一模一样的。”

其实,淘宝团队在翻译时貌似发现原作者给的示例执行可能会是false,所以添加了这段代码以铺垫说明“在旧版版中实现……[1,,3]和[1,undefined,3]是一模一样的”这个特例。
由此,原作者的测试环境是所谓的“旧版本”

我认为两处undefined没有什么区别,都是javascript中的特殊值undefined
答案原地址

2、回答楼主的第二个疑问
我也做了如下测试:

var a1 = [,,,,,,,,,,];//10个逗号,长度为10
var a3 =new Array(10);//长度为10的数组
var a2 = [1,undefined,,,,3];//5个逗号,长度为6
console.log(a1);//[]
console.log(a2);//[1, 5: 3]
console.log(a3);//[]
console.log(a1 + '---' + a1.length);//,,,,,,,,,---10(只有九个逗号)
console.log(a2 + '---' + a2.length);//1,,,,,3---6
console.log(a3 + '---' + a3.length);//,,,,,,,,,---10(输出和a1没区别)
console.log(a1[0]);//undefined
console.log(a2[0]);//1
console.log(a2[1]);/undefined
console.log(a3[3]);//undefined

数组的本质是对象,这个确实大家都知道,可是为什么输出以“,”表示,这个我也真是不懂,和题主一起期待大神的解答。 其实undefined也是一个值,把数组的某一项赋值为undefined,该值就存在,但是是undefined;但是不赋值,该值其实就不存在,输出undefined

【热门文章】
【热门文章】