再探JS数组原生方法—没想到你是这样的数组

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

第一题:
javascript

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

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

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

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

   

在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)app

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

       

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

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 变态题解析 (下)

     




相关文章
相关标签/搜索