Tuesday, December 27, 2022

Function.prototype.bind

Function.prototype.bind( boundThis, ...boundArgs )

Example

const person = {
    getFullName: function () {
        return this.firstName + " " + this.lastName;
    }
}

const thisPerson = {
	firstName   :   "John",
	lastName    :   "Xu",
}

let getFullName = person.getFullName.bind(thisPerson);

console.log( getFullName() )

Function.prototype.bind( boundThis, ...boundArgs )

  1. Let targetFunction be the this value. // for our example, person.getFullName
  2. If IsCallable(targetFunction) is false, throw a TypeError exception.
  3. Let boundArgs be a new List consisting of all of the argument values provided after boundThis(for our example, empty) .
  4. Let F be ?BoundFunctionCreate(targetFunction, boundThis, boundArgs)
            return {
                [[BoundTargetFunction]]: targetFunction,
                [[BoundThis]]: boundThis,
                [[BoundArguments]]: boundArgs,
                [[Prototype]]:targetFunction.[[Prototype]],
            }
        
  5. Perform SetFunctionName(F, name = Get(Target, "name"), prefix = "bound").

NewTarget and new.target

NewTarget

example 01


base_obj = {
    "constructor" : my_constructor,
}

function my_constr_stub()
{
    console.log("in constructor stub:new.target=" + new.target);//undefined
}

function my_constructor()
{
    console.log("in constructor:new.target=" + new.target);// function my_constructor(){...
    my_constr_stub();
}

my_constructor.prototype = base_obj;

new my_constructor()

Object [[Construct]](a List of any, newTarget)

The second argument is the object to which the new operator was initially applied. For example, in following code, the new operator is initially applied to the Square object:

class Rectangle {
  constructor(height, width) {
    console.log("in Rectangle:new.target=" + new.target);
    this.name = 'Rectangle';
    this.height = height;
    this.width = width;
  }
}

class Square extends Rectangle {
  constructor(length) {
    console.log("in Square:new.target=" + new.target);
    super(length, length);

    this.name = 'Square';
  }
}

aS = new Square(2);
console.log(
    "name=" + aS.name +
    ";height=" + aS.height
);

Friday, December 23, 2022

function expression

function expression
factit = function factorial(n) {
    console.log(n)
    if (n < 2) {
      return 1;
    }
    return n * factorial(n - 1);
}

non_recursive = function(){}

/*
can't visit factorial here:
as is indicated in `Runtime Semantics: Evaluation` of NAMED function expression,
we will NewDeclarativeEnvironment(scope) as a middle env to recv factorial

from ecma:
The BindingIdentifier in a FunctionExpression can be referenced
 from inside the FunctionExpression's
FunctionBody to allow the function to call itself recursively.

However, unlike in a FunctionDeclaration, the BindingIdentifier in
a FunctionExpression cannot be referenced from and does
not affect the scope enclosing the FunctionExpression.
*/

Thursday, December 22, 2022

TopLevelVarScopedDeclarations

TopLevelVarScopedDeclarations

Block

  1. Block : { }
        Return a new empty List.
    
  2. StatementList : StatementList StatementListItem //StatementListItem can be Statement or Declaration
        Let declarations be TopLevelVarScopedDeclarations of StatementList.
        Append to declarations the elements of the TopLevelVarScopedDeclarations of StatementListItem.
        Return declarations.
    
  3. StatementListItem : Declaration
        if is function Declaration, return a list contains the Declaration// function is not taken as Lex but top level Var!
    

Label Statement

LabelledStatement : LabelIdentifier : LabelledItem

    Return the TopLevelVarScopedDeclarations of LabelledItem.

LabelledItem : Statement

    // recursive to the last non-labelled Statement
    If Statement is Statement : LabelledStatement , return TopLevelVarScopedDeclarations of Statement
    Return VarScopedDeclarations of Statement.

Others

not documented in ecma documents

TopLevelLexicallyScopedDeclarations

TopLevelLexicallyScopedDeclarations

Block

  1. Block : { }
        Return a new empty List.
    
  2. StatementList : StatementList StatementListItem //StatementListItem can be Statement or Declaration
        Let declarations be TopLevelLexicallyScopedDeclarations of StatementList.
        Append to declarations the elements of the TopLevelLexicallyScopedDeclarations of StatementListItem.
        Return declarations.
    
  3. StatementListItem : Statement
        Return a new empty List.//VariableStatement contribute to Var instead of Lex
    
  4. StatementListItem : Declaration
        if Declaration is `let ` or `const `, return a new List containing Declaration;
        else Return a new empty List// TopLevel functions are taken as Var instead
    

Labelled Statements

Return a new empty List

Others

not documented in ecma documents

LexicallyScopedDeclarations

LexicallyScopedDeclarations

Block

  1. StatementList : StatementList StatementListItem //StatementListItem can be Statement or Declaration
        Let declarations be LexicallyScopedDeclarations of StatementList.
        Append to declarations the elements of the LexicallyScopedDeclarations of StatementListItem.
        Return declarations.
    
  2. StatementListItem : Declaration
        Return a new List containing the Declaration
    

FunctionStatementList : StatementList or Script

    Return the TopLevelLexicallyScopedDeclarations of StatementList.

LabelledItem : FunctionDeclaration

Return a new List containing FunctionDeclaration.

Others

not documented in ecma documents

`catch ( CatchParameter ) Block` is not mentioned, but according to "Runtime Semantics: CatchClauseEvaluation", CatchParameter should be Lexically Declared

VarScopedDeclarations

VarScopedDeclarations

Block

  1. Block : { }
        Return a new empty List.
    
  2. StatementList : StatementList StatementListItem //StatementListItem can be Statement or Declaration
        Let declarations be VarScopedDeclarations of StatementList.
        Append to declarations the elements of the VarScopedDeclarations of StatementListItem.
        Return declarations.
    
  3. StatementListItem : Declaration
        Return a new empty List// `let ` or `const ` Declaration is Lex, funct decl is top Var
    

Variable Statement

Return a new List contains all VariableDeclaration

FunctionStatementList : StatementList or Script

    Return the TopLevelVarScopedDeclarations of StatementList.

Statements contains subs

if/while/for/with/switch/label/try Statement, return a new List contains all VariableDeclaration of the sub(s)

for the case of `for(var `, the new List is pre-feed.

note in `catch ( CatchParameter ) Block`, CatchParameter is not included.

note in label Statement, `LabelledItem : FunctionDeclaration` Return a new empty List.

Others

not documented in ecma documents