為什麼這樣也能執行? [ ].concat[1,2,3]

justjavac發表於2016-12-27

This is just for fun.

本文的宗旨是:This is just for fun。這段程式碼沒有任何實用的價值,但是通過這段程式碼,你可以瞭解 javascript 被忽略的知識點和語法。

1. 問題

下面的程式碼的執行結果是什麼?

[].concat[1,2,3]複製程式碼

2. 答案

先給出答案:undefined

大部分人可能會認為這段程式應該丟擲語法異常:

Uncaught SyntaxError: ....複製程式碼

3. 分析

這段程式和下面的程式碼很像:

[].concat([1,2,3])複製程式碼

concat() 方法將傳入的陣列或非陣列值與原陣列合並,組成一個新的陣列並返回。但是上面的程式碼沒有使用小括號,所以他們兩個並不是相同的。那麼我們來拆開分析一下 [].concat[1,2,3] 是怎麼執行的:

首先計算 [].concat,這個的結果是 Array.prototype.concat

第二步執行一個逗號操作符。逗號操作符對它的每個操作物件求值(從左至右),然後返回最後一個操作物件的值。

> 1,2,3
3複製程式碼

第三步執行一個陣列訪問運算屬性訪問運算。因為 [].concat 是一個函式,函式也是物件,所以這是一個屬性訪問運算。同理,知道了 [] 是陣列訪問運算或屬性訪問運算,你可以很快說出下面程式碼的結果:

[[]][0]
[[[1]]][0][0][0]
[[[1]]][[0][0]][0][0]複製程式碼

看似很複雜,你只需要按操作符的優先順序和結合性一步一步分解,就可以求出最後的結果。

那麼我們回到之前的問題,[].concat[1,2,3] 其實等價於:

Array.prototype.concat[3]複製程式碼

那麼結果自然就是 undefined

4. 番外篇

因為 javascript 的原型是可以修改的,因此我們可以定義:

Array.prototype.concat[3] = [1,2,3];複製程式碼

這時我們再呼叫 [].concat[1,2,3] 就會得到結果 [1,2,3]


每週推送原創高質量文章,歡迎關注我的公眾號

為什麼這樣也能執行? [ ].concat[1,2,3]
微信公眾號

相關文章