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包含兩種值,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)用過程。
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.y和x[y]是Reference,base value都是x的值,
super.x和super[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