再探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 變態題解析 (下)

     




相關文章
相關標籤/搜索