1. “::” 操作符
this綁定語(yǔ)法,提供了一種新的操作符::,用于進(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,以下語(yǔ)法規(guī)則說(shuō)明了這一點(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è)語(yǔ)言規(guī)范內(nèi)置的類(lèi)型(ECMAScript Specification Types)。
Reference Specification Type包含兩種值,Reference和Super 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)用過(guò)程。
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)境中綁定的值,或者對(duì)象的屬性值。

(3)GetThisValue,對(duì)于Reference則返回base value,
否則對(duì)于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è)對(duì)象屬性,就返回這個(gè)屬性值。
結(jié)論:
如果::是串聯(lián)使用,那么this會(huì)被綁定為::左邊的值,
無(wú)論左邊是一個(gè)變量(例如,x::y,y中的this綁定為x的值),
還是對(duì)象的屬性(例如,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ù)語(yǔ)法規(guī)則,MemberExpression必須是x.y,x[y]或super.x,super[x]的形式,
x.y和x[y]是Reference,base value都是x的值,
super.x和super[x]是Super Reference,thisValue字段是父類(lèi)對(duì)象。


結(jié)論:
::x.y,::x[y]的this指向x的值,
而::super.x與::super[x]中的this指向父類(lèi)對(duì)象。
參考
tc39/ecma262
proposals/stage-0-proposals.md
ECMAScript This-Binding Syntax
ECMAScript 2017 Language Specification