Grundlegendes zur ECMAScript-Spezifikation, Teil 2

Hallo Habr! Ich präsentiere Ihnen die Übersetzung des Artikels vonxfides



Originalautor: Marja Hölttä

Übersetzung des ersten Teils.





Lassen Sie uns das Lesen der Spezifikation noch etwas üben. Wenn Sie den vorherigen Artikel noch nicht gesehen haben, ist es Zeit, ihn sich anzusehen. Im ersten Teil haben wir die einfache Object.prototype.hasOwnProperty- Methode kennengelernt . Außerdem haben wir uns die Liste der abstrakten Operationen angesehen , die aufgerufen werden, wenn diese Methode ausgeführt wird. Wir haben auch etwas über die  spezifischen Abkürzungen "?" und "!" im Zusammenhang mit der Fehlerbehandlung. Schließlich erhielten wir Informationen zu  Sprachtypen, Spezifikationstypen, internen Slots und internen Methoden.



Bereit für Teil 2?



Warnung! Diese Episode enthält eine Kopie der Algorithmen aus der ECMAScript-Spezifikation vom Februar 2020. Natürlich werden die Informationen im Laufe der Zeit veraltet sein.



 ,   :   , ,     ,   ,   ,     . :



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,    , . , ,  , ,    .



Schritt 1 wertet den AssignmentExpression- Algorithmus aus , der o2.foo ist . Der Verweis enthält das Ergebnis der Berechnung.



In Schritt 2 rufen wir GetValue auf. Somit wissen wir, dass die interne Methode des [[Get]] - Objekts aufgerufen wird und die Prototypverkettung stattfindet.



Zusammenfassung



In diesem Teil haben wir uns angesehen, wie die Spezifikation die Merkmale der Sprache definiert. In unserem Fall durchsucht ein Prototyp alle verschiedenen Ebenen: syntaktische Konstrukte, die Algorithmen ausführen, und die Schritte, die sie definieren.




All Articles