ECMAScript 的屬性訪問可能沒你想到那么簡單

前言

前段時間身邊有一個小伙伴問了一個關于 JavaScript 基礎的問題,題目如下:

const o = {
  m() { console.log(this === o) }
}

(o.m)()

當時我的理解是,根據語法分析首先執行 o.m 的取值操作,然后其結果進行調用。因為 o.m 的執行結果是一個函數,然后函數直接被調用,所以其 this 應該在嚴格模式下是 undefined,非嚴格模式下是global,結果為 false

但是實際執行結果為 true,也就是這種調用方式和 o.m() 行為表現是一致的。再簡單搜尋無果之后,我轉向了 ECMAScript 規范,并在其中找到了答案。

屬性訪問

o.m 這種操作在規范中稱為 Property Accessors 其返回的結果并不是對象 om 屬性所對應的值,而是返回一個 Reference 類型的值。

  1. Return a value of type Reference whose base value component is bv, whose referenced name component is propertyKey, and whose strict reference flag is strict.

Reference 類型的值對應著一個叫做 GetValue 的方法,該方法返回的結果才是對象 om 屬性所對應的值,也就是上面那個函數。就像上邊引用表述的那樣, Reference 類型的值其實保存了本次取值操作的對象 o 和字符串 'm'。其存在的目的是保證類似于 typeof o.mdelete o.mo.m = 'ooxx' 能夠按照預期執行。本質上是因為這些操作都需要依賴 o 這個對象,而不僅僅是其 m 屬性對應的值。

The Reference type is used to explain the behaviour of such operators as delete, typeof, the assignment operators, the super keyword and other language features. For example, the left-hand operand of an assignment is expected to produce a reference.

括號

然后,我們再簡單的看一下括號表達式(The Grouping Operator),其規范中有很重要的一點是:

Return the result of evaluating Expression. This may be of type Reference.

規范還解釋了為什么 :

This algorithm does not apply GetValue to the result of evaluating Expression. The principal motivation for this is so that operators such as delete and typeof may be applied to parenthesized expressions.

如上,官方解釋了為什么不對括號里面的表達式執行結果調用 getValue 方法之后再返回,其實希望保證 deletetypeof 這些操作符和括號表達式一起工作的時候能夠符合我們的預期。例如,delete (o.m)delete o.m 將會表現的一致。

結論

綜上,屬性訪問和括號表達式共同決定了 (o.m)() 的表現和 o.m() 表現是一致的。

引申

  1. 為何 (o.n = o.m)() 會打印 false ?

那是因為賦值操作的返回結果是對右側表達式的執行結果調用 getValue 方法,如下:

  1. Let rval be ? GetValue(rref).
  2. Perform ? DestructuringAssignmentEvaluation of assignmentPattern using rval as the argument.
  3. Return rval.

同理,你也應該知道為何 (null, o.m)() 也會打印 false

  1. 為何我在控制臺中輸入 o.m 顯示就是相應的函數而不是一個 Reference 類型的值?

那是因為此時表達式會被解釋成一條獨立的語句,因此有如下規范:

  1. Let exprRef be the result of evaluating Expression.
  2. Return ? GetValue(exprRef).

這里調用了 GetValue 方法。

參考

  1. https://www.ecma-international.org/ecma-262/
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,448評論 0 10
  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,905評論 0 38
  • 推開記憶的小窗 翻開流年的暢想 風起的時候我將遠航 故鄉的炊煙依然繚繞在我的夢鄉 在開滿野花的小路上 寫滿了牽掛的...
    西廂月閱讀 214評論 4 3
  • 生活就像打游戲,難度不斷升級。 積極的態度是工作或者說銷售工作所必備的素質。剛入職時候,我相信自己是心態積極的人。...
    不知道名字為什么違規閱讀 172評論 0 1
  • 將心注入,注入到哪里? 剛讀完我沒明白,做完筆記,寫完書評。 我懂了。 1.我喝星巴克 2013年,我第一次喝星巴...
    樹諾閱讀 1,392評論 0 11