首页  >  问答  >  正文

javascript - 关于犀牛第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]也没有。我感觉我理解的有问题,却又不知道问题出在哪,请大神帮帮忙。谢谢。

ringa_leeringa_lee2728 天前289

全部回复(3)我来回复

  • 黄舟

    黄舟2017-04-10 16:56:29

    尽信书不如无书!

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

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

    跟你书中的结果不一样!

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

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

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

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

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

    回复
    0
  • 巴扎黑

    巴扎黑2017-04-10 16:56:29

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

    只不过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];

    回复
    0
  • 迷茫

    迷茫2017-04-10 16:56:29

    早上六点多睡醒的时候就看到题主这个问题,真是被这个题目折磨了一早上啊。
    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

    回复
    0
  • 取消回复