ECMAScript仕様の理解、パート2

こんにちは、Habr!私はあなたの注意に編集された記事の翻訳を提示しますxfides



原作者:MarjaHölttä

最初の部分の翻訳。





スペックをもう少し読んで練習しましょう。前の記事をまだ見たことがない場合は、それを見てみましょう。最初の部分では、単純なObject.prototype.hasOwnPropertyメソッドについて理解しましたまた、このメソッドの実行時に呼び出される抽象操作のリストも確認しましたまた、特定の略語「?」についても学びました 「!」エラー処理に関連します。最後に、言語タイプ、仕様タイプ、内部スロット、および内部メソッドに関する情報を取得しました 



パート2の準備はできましたか?



警告!このエピソードには、2020年2月のECMAScript仕様のアルゴリズムのコピーが含まれています。当然、時間の経過とともに、情報は古くなります。



 ,   :   , ,     ,   ,   ,     . :



const o1 = { foo: 99 };
const o2 = {};
Object.setPrototypeOf(o2, o1);
o2.foo;
// → 99


  ?



, .  —   .



[[GetOwnProperty]] [[Get]]. ,    — [[Get]].  ,   [[Get]], , , ,    .



[[Get]] . ( )   . [[Get]],    .       .



[[Get]] ( P, Receiver ). OrdinaryGet. , [[Get]]   «»   «»  ECMAScript Receiver, :



    1. Return ? OrdinaryGet(O, P, Receiver).


 , Receiver — , this , -.



OrdinaryGet(O, P, Receiver) :



1.  Assert: IsPropertyKey(P) is true.
2.  Let desc be ? O.[[GetOwnProperty]](P).
3.  If desc is undefined, then
        a. Let parent be ? O.[[GetPrototypeOf]]().
        b. If parent is null, return undefined.
        c. Return ? parent.[[Get]](P, Receiver).
4.  If IsDataDescriptor(desc) is true, return desc.[[Value]].
5.  Assert: IsAccessorDescriptor(desc) is true.
6.  Let getter be desc.[[Get]].
7.  If getter is undefined, return undefined.
8.  Return ? Call(getter, Receiver).


:    ,   [[Get]] , OrdinaryGet.     ,   [[Get]] ,   OrdinaryGet.   ,    ,     null.



, ,   o2.foo.   OrdinaryGet     «» «2»,    «» — «foo». , O.[[GetOwnProperty]](«foo») undefined,     if   3, «o2»   «foo».



  3.a,     «parent»   «o2» — «o1». «parent» null,    if   3.b.



  3.   [[Get]]   «foo»   . «o1» — ,   [[Get]] OrdinaryGet .   ,   «» «1»,   «» «foo».



  2  O.[[GetOwnProperty]](«foo»)   ,      desc.



 — .   [[Value]].   [[Get]] / [[Set]].   ,  «foo» — .



 ,   desc   2,    if   3.



  4. ,  99,   [[Value]]   4.    .



Receiver    ?



Receiver   -   8.   this, -.



OrdinaryGet Receiver ( 3.c). , Receiver.



 , [[Get]], GetValue,  Reference. Reference — , ,   strict.   o2.foo «o2»,  — «foo»,   strict — false.



: Reference   Record?



Reference   Record,   .   ,   .   , Reference   Record   .



 GetValue.



, GetValue ( V ) :



1.  ReturnIfAbrupt(V).
2.  If Type(V) is not Reference, return V.
3.  Let base be GetBase(V).
4.  If IsUnresolvableReference(V) is true, throw a ReferenceError exception.
5.  If IsPropertyReference(V) is true, then
     .If HasPrimitiveBase(V) is true, then
         i.Assert: In this case, base will never be undefined or null.
         ii.Set base to ! ToObject(base).
     b.Return ? base.[[Get]](GetReferencedName(V),   GetThisValue(V)).
6.  Else,
      a.Assert: base is an Environment Record.
      b.Return ? base.GetBindingValue(GetReferencedName(V), IsStrictReference(V))


Reference   o2.foo, property reference.



,    if   5.     5.a, «2»   (, , , BigInt, Boolean, Undefined, Null).



  [[Get]]   5.b. Receiver,   — , GetThisValue(V).   GetThisValue( V ) Reference:



1.  Assert: IsPropertyReference(V) is true.
2.  If IsSuperReference(V) is true, then
        a.Return the value of the thisValue component of the reference V.
3.  Return GetBase(V).


o2.foo,    if   2, o2.foo   Super Reference( super.foo), , 3   Reference, «o2».



,  ,   Receiver Reference, , ,       . ,  , ,  , -,   Receiver this.



  , this   ,   ,    ,       .



!



const o1 = { x: 10, get foo() { return this.x; } };
const o2 = { x: 50 };
Object.setPrototypeOf(o2, o1);
o2.foo;
// → 50


    - «foo»,    . «this.x.».



  o2.foo — ?



 , ,   , this ,     ,   ,     .   , this «2»,    «1».     , , : o2.x o1.x.     o2.x.



, !     ,    .



 —  — [[Get]]?



  , [[Get]] ,   o2.foo? , - .    !



 , [[Get]]   GetValue,  References.   GetValue?



  MemberExpression



.   ,  , .



      - ,   .



    ,   .  ,   (Yield, Await  ..)     .



, MemberExpression :



MemberExpression :
     PrimaryExpression
     MemberExpression [ Expression ]
     MemberExpression . IdentifierName
     MemberExpression TemplateLiteral
     SuperProperty
     MetaProperty
     new MemberExpression Arguments


MemberExpression.



MemberExpression PrimaryExpression. MemberExpression   MemberExpression Expression, : MemberExpression[Expression], o2[’foo’].   MemberExpression.IdentifierName, o2.foo — .



  Runtime Semantics: Evaluation for MemberExpression: MemberExpression. IdentifierName :



1.  Let baseReference be the result of evaluating MemberExpression.
2.  Let baseValue be ? GetValue(baseReference).
3.  If the code matched by this MemberExpression is strict mode code, let strict be true; else let strict be false.
4.  Return ? EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict).


  EvaluatePropertyAccessWithIdentifierKey,    . EvaluatePropertyAccessWithIdentifierKey(baseValue, identifierName, strict)   baseValue, identifierName,   strict   :



1.  Assert: identifierName is an IdentifierName
2.  Let bv be ? RequireObjectCoercible(baseValue).
3.  Let propertyNameString be StringValue of identifierName.
4.  Return a value of type Reference whose base value component is bv, whose referenced name component is propertyNameString, and whose strict reference flag is strict.


, EvaluatePropertyAccessWithIdentifierKey Reference, baseValue   base, identifierName ,  strict .



 , Reference GetValue.    ,    , Reference   .



MemberExpression



    :



console.log(o2.foo);


  , ArgumentList: AssignmentExpression.  ,   .   GetValue :



Runtime Semantics: ArgumentListEvaluation



1.  Let ref be the result of evaluating AssignmentExpression.
2.  Let arg be ? GetValue(ref).
3.  Return a List whose sole item is arg.


o2.foo   AssignmentExpression,    , . , ,  , ,    .



ステップ1は、o2.fooであるAssignmentExpressionアルゴリズムを評価します。refには計算結果が含まれます。



ステップ2では、そこからGetValueを呼び出しますしたがって、[[Get]]オブジェクトの内部メソッドが呼び出され、プロトタイプの連鎖が行われることがわかります



概要



このパートでは、仕様が言語機能をどのように定義するかを見てきました。私たちの場合、プロトタイプはすべての異なるレイヤーを検索します。アルゴリズムを実行する構文構造と、それらを定義するステップです。




All Articles