[ECMAScript] This-Binding Syntax

1. “::” 操作符

this綁定語法,提供了一種新的操作符::,用于進(jìn)行便捷的this綁定。

主要有以下兩種用法:
(1)串聯(lián)

import { map, takeWhile, forEach } from "iterlib";

getPlayers()
::map(x => x.character())
::takeWhile(x => x.strength > 100)
::forEach(x => console.log(x));

(2)單獨(dú)使用

Promise.resolve(123).then(::console.log);

單獨(dú)使用時(shí),::后面必須是x.y,x[y]super.x,super[x]的形式,
否則會(huì)報(bào)Syntax Error,以下語法規(guī)則說明了這一點(diǎn)。

BindExpression :
<i>????</i>:: MemberExpression

  • It is a Syntax Error if the derived MemberExpression is not
    MemberExpression : MemberExpression . Identifier,
    MemberExpression : MemberExpression [ Expression ],
    or SuperProperty
  • It is a Syntax Error if the derived NewExpression is PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList and CoverParenthesizedExpressionAndArrowParameterList ultimately derives a phrase that, if used in place of NewExpression, would produce a Syntax Error according to these rules. This rule is recursively applied.

<u></u>

SuperProperty :
super [ Expression ]
super . IdentifierName


2. The Reference Specification Type

The Reference Specification Type,是一個(gè)語言規(guī)范內(nèi)置的類型(ECMAScript Specification Types)。

Reference Specification Type包含兩種值,ReferenceSuper Reference
(1)Reference是一種數(shù)據(jù)結(jié)構(gòu),包括base value,referenced name,
以及strict reference flag三個(gè)組成部分。

(2)Super Reference,多了一個(gè)thisValue字段,
用于處理super()以及super.method()調(diào)用過程。

The base value component is either undefined, an Object, a Boolean, a String, a Symbol, a Number, or an Environment Record.
The referenced name component is a String or Symbol value.

與之相關(guān)聯(lián)有幾個(gè)函數(shù),下文會(huì)用到:
(1)GetBase(V)會(huì)返回一個(gè)Reference的base value。

(2)GetValue用于獲取詞法環(huán)境中綁定的值,或者對象的屬性值。

(3)GetThisValue,對于Reference則返回base value,
否則對于Super Reference則返回它的thisValue字段。


2. 綁定規(guī)則

(1)串聯(lián)

BindExpression :
<i>????</i>LeftHandSideExpression :: [lookahead ≠ new] MemberExpression

  • Let baseReference be the result of evaluating LeftHandSideExpression.
  • Let baseValue be GetValue(baseReference).
  • Let targetReference be the result of evaluating MemberExpression.
  • Let target be GetValue(targetReference).
  • If IsCallable(target) is false, throw a TypeError exception.
  • Let F be ? BoundFunctionCreate(target, baseValue, ??).
  • Return InitializeBoundFunctionProperties(F, target).

<u></u>

根據(jù)BoundFunctionCreate (targetFunction, boundThis, boundArgs)的定義,我們知道,
BoundFunctionCreate的第二個(gè)參數(shù)就是所創(chuàng)建函數(shù)的this值,
因此GetValue(baseReference)的值就是this。

根據(jù)GetValue的定義可知,
如果baseReference是一個(gè)詞法變量,則返回它的綁定值,
如果它是一個(gè)對象屬性,就返回這個(gè)屬性值。

結(jié)論:
如果::是串聯(lián)使用,那么this會(huì)被綁定為::左邊的值,
無論左邊是一個(gè)變量(例如,x::y,y中的this綁定為x的值),
還是對象的屬性(例如,a.b::y,y中的this綁定為a.b的值)。

(2)單獨(dú)使用

BindExpression :
<i>????</i>:: MemberExpression

  • Let targetReference be the result of evaluating MemberExpression.
  • Assert: IsPropertyReference(targetReference) is true.
  • Let thisValue be GetThisValue(targetReference).
  • Let target be GetValue(targetReference).
  • If IsCallable(target) is false, throw a TypeError exception.
  • Let F be ? BoundFunctionCreate(target, thisValue, ??).
  • Return ? InitializeBoundFunctionProperties(F, target).

<u></u>

同理,GetThisValue(targetReference)的值就是所創(chuàng)建函數(shù)的this值,
根據(jù)語法規(guī)則,MemberExpression必須是x.y,x[y]super.x,super[x]的形式,
x.yx[y]是Reference,base value都是x的值,
super.xsuper[x]是Super Reference,thisValue字段是父類對象。

結(jié)論:
::x.y,::x[y]this指向x的值,
::super.x::super[x]中的this指向父類對象。


參考

tc39/ecma262
proposals/stage-0-proposals.md
ECMAScript This-Binding Syntax
ECMAScript 2017 Language Specification

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容