zoukankan      html  css  js  c++  java
  • 再探JS数组原生方法—没想到你是这样的数组

    最近作死又去做了一遍javascript-puzzlers上的44道变态题,这些题号称“JS语言专业八级”的水准,建议可以去试试,这里我不去解析这44道题了,网上已经有很多的答案了。我只介绍让我意想不到的几种特殊情况下的数组操作方法结果。关于数组原生方法的基本操作我在另一篇博客里已经做了简介:吃透Javascript数组操作的正确姿势—再读《Js高程》.....下面的输出结果,未做特殊说明是在Node环境中运行的结果。

    第一题:

    What is the result of this expression? (or multiple ones)

       [ [3,2,1].reduce(Math.pow), [].reduce(Math.pow) ]        

     an error[9, 0][9, NaN][9, undefined]

    Per spec: reduce on an empty array without an initial value throws TypeError

       

    在Node环境中可以自行执行上面的表达式,结果会产生TypeError: Reduce of empty array with no initial value

    也就是说在不能在空数组上调用不带初始参数的reduce方法,可以像下面这样调用,增加一个初始参数

    1
    console.log([ [3,2,1].reduce(Math.pow), [].reduce(Math.pow,1)])//输出[9,1]


    第二题:

    What is the result of this expression? (or multiple ones)

      var ary = [0,1,2];ary[10] = 10;ary.filter(function(x) { return x === undefined;}); 

           

    [undefined × 7][0, 1, 2, 10][][undefined]

    Array.prototype.filter is not invoked for the missing elements.

     由上面的结果可以得知,“稀疏数组”中丢失的元素并不会唤起filter方法的调用,但是如果你打印出稀疏元素

    1
    console.log(ary[5]);//undefined

    结果确实是undefined。打印整个数组看一下:

    1
    console.log(ary)//[ 0, 1, 2, , , undefined, , , , , 10 ]

    所以这种通过直接给ary[10]赋值的方式产生的数组并不将未赋值的地方变成真正的undefined。

    创建“稀疏数组”的方法也不只这一种,那么其他方法会不会也是这种情况呢。

    1
    2
    3
    4
    var ary = [0,1,2];
    ary.length = 10;
    console.log(ary)//[ 0, 1, 2, , , , , , ,  ]
    console.log(ary.filter(function(x) { return x === undefined;})); //[]

    从上例可以看到使用设置arr.length的方法创建的稀疏数组也是一样的情况。

    1
    2
    3
    4
    5
    6
    var ary = Array(10);
    ary[0]=0;
    ary[1]=1;
    ary[2]=2;
    console.log(ary)//[ 0, 1, 2, , , , , , ,  ]
    console.log(ary.filter(function(x) { return x === undefined;})); //[]

    从上可以看出通过ary = Array(10);创建的稀疏数组同样出现这样情况。

    接下来拓展一下,直接将undefined赋值给ary[5]

    1
    2
    3
    4
    5
    var ary = [0,1,2];
    ary[5]=undefined;//直接将undefined赋值给ary[5]
    ary[10] = 10;
    console.log(ary)//[ 0, 1, 2, , , undefined, , , , , 10 ]
    console.log(ary.filter(function(x) { return x === undefined;})); //[ undefined ]

    从结果中可以看出只有ary[5]通过了筛选。
    稀疏数组的这种特性在数组的map方法中是否存在呢,接着看第三题。

    第三题:

    What is the result of this expression? (or multiple ones)

        var ary = Array(3);ary[0]=2;ary.map(function(elem) { return '1'; });

    [2, 1, 1]["1", "1", "1"][2, "1", "1"]other The result is ["1", undefined × 2], as map is only invoked for elements of the Array which have been initialized.

    官网给出了上面的 解析,在浏览器中运行就是上面的结果,我在Node环境中显示的结果是[ '1', ,  ]。不管怎么样都说明了在稀疏元素上并没有唤起调用map的回调函数。

    2016-7-20补充:那么有没有办法让稀疏数组唤起调用map或者上一题的filter方法呢?看完下面的例子大概就清楚了

    1
    2
    3
    4
    5
    var a = Array(10).join(",").split(",").map(function(item, index) {
      return index;
    });
     
    console.log(a);

    通过join方法把它转成字符串,然后,再通过split方法把字符串转成数组,这时候,它就拥有10个值为空的元素了,然后,再通过map函数,改变这些元素的值即可。



    第四题:

    What is the result of this expression? (or multiple ones)

              var x = [].reverse;x();        

    []undefinederrorwindow

    [].reverse will return this and when invoked without an explicit receiver object it will default to the default this AKA window

    reverse 方法颠倒数组中元素的位置,并返回该数组的引用。出题者的意图是该方法会返回this,然后在全局环境中这个this就是window,而实际上经过我测试,在谷歌浏览器上显示错误:

         Uncaught TypeError: Array.prototype.reverse called on null or undefined(…)

    在Node环境中显示
    TypeError: Array.prototype.reverse called on null or undefined

     可以看出实际上 var x = [].reverse返回的是对数组reverse方法的引用,直接调用的话会出错。可以使用call方法调用

    1
    2
    3
    4
    var x = [].reverse;
    var arr=[1,2,3];
     
    console.log( x.call(arr)); //[ 3, 2, 1 ]




     第五题:

    What is the result of this expression? (or multiple ones)

              [,,,].join(", ")        

    JavaScript allows a trailing comma when defining arrays, so that turns out to be an array of three undefined.

    因为javascript 在定义数组的时候允许最后一个元素后跟一个,, 所以这是个长度为三的稀疏数组(这是长度为三, 并没有 0, 1, 2三个属性哦),同理

    1
    2
    var arr=Array(3);
    console.log(arr.join(", ") )//, ,

       



    参考:

    

    javascript-puzzlers

    44个 Javascript 变态题解析 (上)

    44个 Javascript 变态题解析 (下)

    






  • 相关阅读:
    Safe Path(bfs+一维数组存图)
    一维树状数组入门
    Ancient Go(简单DFS)
    Sudoku(简单DFS)
    Strategic game(树形DP入门)
    多线程源码分析
    Navicat premium12的破解方法,无需注册码
    MySQL和Oracle的区别
    java Web项目中什么场景中会用到java多线程?
    TCP协议三次握手、四次断开 过程分析
  • 原文地址:https://www.cnblogs.com/star91/p/5682989.html
Copyright © 2011-2022 走看看