---
# System prepended metadata

title: MCMAScript 文章

---

# MCMAScript 文章

- Ref: http://dmitrysoshnikov.com/
---
章節
- ECMA-262-3 in detail
Chapter 1. Execution Contexts
Chapter 2. Variable object
Chapter 3. This
Chapter 4. Scope chain
Chapter 5. Functions
Chapter 6. Closures
Chapter 7.1. OOP: The general theory
Chapter 7.2. OOP: ECMAScript implementation
Chapter 8. Evaluation strategy
- ECMA-262-5 in detail
Chapter 1. Properties and Property Descriptors
Chapter 2. Strict Mode
Chapter 3.1. Lexical environments: Common Theory
Chapter 3.2. Lexical environments: ECMAScript implementation

---

這部分是 JavaScript 比較底層的部分，作者的文章也稍為貼近規格書的內容，算是還不錯的規格書導讀，第一次看還不是很懂，之後再回來看看，底下筆記列出文章中的一些名詞，方便之後對照查閱


筆記 : 

#### ECMA-262-3 in detail
- Variable Object : 
  - VO, AO
    ```javascript
    AbstractVO (generic behavior of the variable instantiation process)
      ║
      ╠══> GlobalContextVO
      ║        (VO === this === global)
      ║
      ╚══> FunctionContextVO
            (VO === AO, <arguments> object and <formal parameters> are added)
    ```
- AO : 
   -  Regarding the execution context of functions — there VO is inaccessible directly, and its role plays so-called an activation object (in abbreviated form — AO).
  ```javascript
  VO(functionContext) === AO;
  ```
- Global context : 
  - Global object is the object which is created before entering any execution context
  ```javascript
  global = {
    Math: <...>,
    String: <...>
    ...
    ...
    window: global
  };
  ```
- \_\_parent\_\_
  - which is the reference to the activation object (or the global variable object) in which these functions have been created.
  ```javascript
  var global = this;
  var a = 10;

  function foo() {}

  alert(foo.__parent__); // global

  var VO = foo.__parent__;

  alert(VO.a); // 10
  alert(VO === global); // true
  ```
- This : Function call and non-Reference type
  - when on the left hand side of call parentheses there is a value not of Reference type but any another type, this value is automatically set to null and, as consequence, to the global object.
  ```javascript
  (function () {
    console.log(this); // null => global
  })();
  ```
  ```javascript
  var foo = {
    bar: function () {
      console.log(this);
    }
  };
  foo.bar(); // Reference, OK => foo
  (foo.bar)(); // Reference, OK => foo
  // ----------------------------------
  (foo.bar = foo.bar)(); // global?
  (false || foo.bar)(); // global?
  (foo.bar, foo.bar)(); // global?
  ```
  - In the third case, assignment operator, unlike the grouping operator, calls ==GetValue== method (see step 3 of 11.13.1). As a result at return there is already function object (but not a value of Reference type) which means that this value set to null and, as consequence, to global.
  - Similarly with the fourth and fifth cases — the comma operator and logical OR expression ==call the GetValue method and accordingly we lose value of type Reference== and get value of type function; and again this value is set to global.
- 早期的瀏覽器 : SpiderMonkey, JScript
- Algorithm of function creation
  ```javascript
  F = new NativeObject();

  // property [[Class]] is "Function"
  F.[[Class]] = "Function"

  // a prototype of a function object
  F.[[Prototype]] = Function.prototype

  // reference to function itself
  // [[Call]] is activated by call expression F()
  // and creates a new execution context
  F.[[Call]] = <reference to function>

  // built in general constructor of objects
  // [[Construct]] is activated via "new" keyword
  // and it is the one who allocates memory for new
  // objects; then it calls F.[[Call]]
  // to initialize created objects passing as
  // "this" value newly created object 
  F.[[Construct]] = internalConstructor

  // scope chain of the current context
  // i.e. context which creates function F
  F.[[Scope]] = activeContext.Scope
  // if this functions is created 
  // via new Function(...), then
  F.[[Scope]] = globalContext.Scope

  // number of formal parameters
  F.length = countParameters

  // a prototype of created by F objects
  __objectPrototype = new Object();
  __objectPrototype.constructor = F // {DontEnum}, is not enumerable in loops
  F.prototype = __objectPrototype

  return F
  ```
  - ==F.[[Prototype]] is a prototype of the function (constructor) and F.prototype is a prototype of objects created by this function== (because often there is a mess in terminology, and F.prototype in some articles is named as a “prototype of the constructor” that is incorrect).
- first-class functions
  - Functions which can participate as normal data, i.e. be passed as arguments, receive functional arguments or be returned as functional values, are called first-class functions. In ECMAScript ==all functions are first-class==.
- In ECMAScript all functions are first-class.
  - A ==free variable== is a variable which is used by a function, but is neither a parameter, nor a local variable of the function.
  ```javascript
  function testFn() {

    let localVar = 10;

    function innerFn(innerParam) {
      console.log(innerParam + localVar);
    }

    return innerFn;
  }

  let someFn = testFn();
  someFn(20); // 30
  ```
  ```javascript
  let z = 10;
  function foo() {
    console.log(z);
  }

  foo(); // 10 – with using both static and dynamic scope

  (function () {

    let z = 20;
    // NOTE: always 10 in JS!
    foo(); // 10 – with static scope, 20 – with dynamic scope

  })();

  // the same with passing foo
  // as an arguments

  (function (funArg) {

    let z = 30;
    funArg(); // 10 – with static scope, 30 – with dynamic scope

  })(foo);
  ```
- Closure
  - A closure is a combination of a code block and data of a context in which this code block is created.
  - [[Scope]] : all inner functions share the same parent environment.
  ```javascript
  var data = [];

  for (var k = 0; k < 3; k++) {
    data[k] = function () {
      console.log(k);
    };
  }

  data[0](); // 3, but not 0
  data[1](); // 3, but not 1
  data[2](); // 3, but not 2
  ```
  ```javascript
  activeContext.Scope = [
    ... // higher variable objects
    {data: [...], k: 3} // activation object
  ];

  data[0].[[Scope]] === Scope;
  data[1].[[Scope]] === Scope;
  data[2].[[Scope]] === Scope;
  ```
  - Creation of additional enclosing context
  ```javascript
  var data = [];

  for (var k = 0; k < 3; k++) {
    data[k] = (function _helper(x) {
      return function () {
        console.log(x);
      };
    })(k); // pass "k" value
  }

  // now it is correct
  data[0](); // 0
  data[1](); // 1
  data[2](); // 2
  ```
  ```javascript
  data[0].[[Scope]] === [
    ... // higher variable objects
    AO of the parent context: {data: [...], k: 3},
    AO of the _helper context: {x: 0}
  ];

  data[1].[[Scope]] === [
    ... // higher variable objects
    AO of the parent context: {data: [...], k: 3},
    AO of the _helper context: {x: 1}
  ];

  data[2].[[Scope]] === [
    ... // higher variable objects
    AO of the parent context: {data: [...], k: 3},
    AO of the _helper context: {x: 2}
  ];
  ```
- OOP
  - ECMAScript is the object-oriented programming language with the ==prototype== based implementation.
- Polymorphism
  - one function can be applied to different objects, just like it would be the native characteristic of an object (because this value determinate on entering the execution context)
  ```javascript
  function test() {
    alert([this.a, this.b]);
  }

  test.call({a: 10, b: 20}); // 10, 20
  test.call({a: 100, b: 200}); // 100, 200

  var a = 1;
  var b = 2;

  test(); // 1, 2
  ```
- Encapsulation
  - well known modifiers: private, protected and public which also are called as access levels (or access modifiers) to characteristics of objects.
  - encapsulation is an increasing of abstraction, but ==not a paranoid hiding from “malicious hackers”== which, “want to write something directly into fields of your classes”.
  ```javascript
  function A() {

    var _a; // "private" a

    this.getA = function _getA() {
      return _a;
    };

    this.setA = function _setA(a) {
      _a = a;
    };

  }

  var a = new A();

  a.setA(10);
  alert(a._a); // undefined, "private"
  alert(a.getA()); // 10
  ```
- Data type ( ES3rd )
  - Undefined
  - Null
  - Boolean
  - String
  - Number
  - Object
  - Reference ( implementation level )
  - List ( implementation level )
  - Completion ( implementation level )
- Dynamic nature
  ```javascript
  var foo = {x: 10};

  // add new property
  foo.y = 20;
  console.log(foo); // {x: 10, y: 20}

  // change property value to function
  foo.x = function () {
    console.log('foo.x');
  };

  foo.x(); // 'foo.x'

  // delete property
  delete foo.x;
  console.log(foo); // {y: 20}
  ```
  - freeze ( ES5 )
  ```javascript
  var foo = {x: 10};

  // freeze the object
  Object.freeze(foo);
  console.log(Object.isFrozen(foo)); // true

  // can't modify
  foo.x = 100;

  // can't extend
  foo.y = 200;

  // can't delete
  delete foo.x;

  console.log(foo); // {x: 10}
  ```
- Boolean, String and Number objects
  - Such objects are created with corresponding built in constructors and contain primitive value as one of internal properties. Object representation can be converted into primitive values and vice-versa.
  ```javascript
  var c = new Boolean(true);
  var d = new String('test');
  var e = new Number(10);

  // converting to primitive
  // conversion: ToPrimitive
  // applying as a function, without "new" keyword
  с = Boolean(c);
  d = String(d);
  e = Number(e);

  // back to Object
  // conversion: ToObject
  с = Object(c);
  d = Object(d);
  e = Object(e);
  ```
  - there are also objects created by special built in constructors: 
    - Function (function objects constructor) Array (arrays constructor)
    - RegExp (regular expressions constructor)
    - Math (the mathematical module)
    - Date (the constructor of dates)
- Associative arrays? ( Hash table )
  - Really, they are similar enough, and in respect of ==“key-value”== pairs storage completely correspond to the theoretical “associative array” or “hash tables” data structures.
  - there is no separated special term (hash or other) for that. Because any object regardless its internal properties can store these pairs:
  ```javascript
  var a = {x: 10};
  a['y'] = 20;
  a.z = 30;

  var b = new Number(1);
  b.x = 10;
  b.y = 20;
  b['z'] = 30;

  var c = new Function('');
  c.x = 10;
  c.y = 20;
  c['z'] = 30;

  // etc. – with any object "subtype"
  ```
  - objects in ECMAScript because of ==delegation can be nonempty==, therefore the term “hash” also can be improper:
  ```javascript
  Object.prototype.x = 10;

  var a = {}; // create "empty" "hash"

  console.log(a["x"]); // 10, but it's not empty
  console.log(a.toString); // function

  a["y"] = 20; // add new pair to "hash"
  console.log(a["y"]); // 20

  Object.prototype.y = 20; // and property into the prototype

  delete a["y"]; // remove
  console.log(a["y"]); // but key and value are still here – 20
  ```
  - Also in ECMAScript concept of a “property” semantically is not separated into a ==“key”, “array index”, “method” or “property”==
- Type conversion
  - To convert an object into a primitive value the method ==valueOf== can be used. As we noted, the call of the constructor (for certain types) as a function
  - aaa
  - ==valueOf== method allows objects to participate in various operations, for example, in addition:
  ```javascript
  var a = new Number(1);
  var b = new Number(2);

  console.log(a + b); // 3

  // or even so

  var c = {
    x: 10,
    y: 20,
    valueOf: function () {
      return this.x + this.y;
    }
  };

  var d = {
    x: 30,
    y: 40,
    // the same .valueOf
    // functionality as "с" object has,
    // borrow it:
    valueOf: c.valueOf
  };

  console.log(c + d); // 100
  ```
  -  For this ==toString== method is responsible, which in some operations is also applied automatically:
  ```javascript
  var a = {
    valueOf: function () {
      return 100;
    },
    toString: function () {
      return '__test';
    }
  };

  // in this operation
  // toString method is
  // called automatically
  console.log(a); // "__test" ( 實測會映出 "a" 這個物件 )

  // but here - the .valueOf() method
  console.log(a + 10); // 110

  // but if there is no
  // valueOf method, it
  // will be replaced with the
  //toString method
  delete a.valueOf;
  console.log(a + 10); // "_test10"
  ```
- with the new and without new
  - ==Array or Function== constructors produce the same results when are called as a constructor (with new) and as a simple function (without new):
  ```javascript
  var a = Array(1, 2, 3); // [object Array]
  var b = new Array(1, 2, 3); // [object Array]
  var c = [1, 2, 3]; // [object Array]

  var d = Function(''); // [object Function]
  var e = new Function(''); // [object Function]
  ```
- Constructor
  - Constructor is a function that creates and initializes the newly created object.
  - Though, even from initialization we can return different object ignoring this object
  ```javascript
  function A() {
    // update newly created object
    this.x = 10;
    // but return different object
    return [1, 2, 3];
  }

  var a = new A();
  console.log(a.x, a); undefined, [1, 2, 3] 
  ```
- Algorithm of objects creation
  ```javascript
  F.[[Construct]](initialParameters):

  O = new NativeObject();

  // property [[Class]] is set to "Object", i.e. simple object
  O.[[Class]] = "Object"

  // get the object on which
  // at the moment references F.prototype
  var __objectPrototype = F.prototype;

  // if __objectPrototype is an object, then:
  O.[[Prototype]] = __objectPrototype
  // else:
  O.[[Prototype]] = Object.prototype;
  // where O.[[Prototype]] is the prototype of the object

  // initialization of the newly created object
  // applying the F.[[Call]]; pass:
  // as this value – newly created object - O,
  // arguments are the same as initialParameters for F
  R = F.[[Call]](initialParameters); this === O;
  // where R is the returned value of the [[Call]]
  // in JS view it looks like:
  // R = F.apply(O, initialParameters);

  // if R is an object
  return R
  // else
  return O
  ```
  - the prototype of the created object is taken from the prototype property of a function on the current moment
  - if at object initialization the [[Call]] has returned an object, exactly it is used as the result of the whole new expression:
  ```javascript
  function A() {}
  A.prototype.x = 10;

  var a = new A();
  console.log(a.x); // 10 – by delegation, from the prototype

  // set .prototype property of the
  // function to new object; why explicitly
  // to define the .constructor property,
  // will be described below
  A.prototype = {
    constructor: A,
    y: 100
  };

  var b = new A();
  // object "b" has new prototype
  console.log(b.x); // undefined
  console.log(b.y); // 100 – by delegation, from the prototype

  // however, prototype of the "a" object
  // is still old (why - we will see below)
  console.log(a.x); // 10 - by delegation, from the prototype

  function B() {
    this.x = 10;
    return new Array();
  }

  // if "B" constructor had not return
  // (or was return this), then this-object
  // would be used, but in this case – an array
  var b = new B();
  console.log(b.x); // undefined
  console.log(Object.prototype.toString.call(b)); // [object Array]
  ```
- Prototype
  - Communication with a prototype is organized via the internal, implicit and inaccessible directly [[Prototype]] property. A prototype can be either an object, or the null value.
  - Via the inherited constructor property instances can indirectly get the reference to the prototype object:
  ```javascript
  function A() {}
  A.prototype.x = new Number(10);

  var a = new A();
  console.log(a.constructor.prototype); // [object Object]

  console.log(a.x); // 10, via delegation
  // the same as a.[[Prototype]].x
  console.log(a.constructor.prototype.x); // 10

  console.log(a.constructor.prototype.x === a.x); // true
  ```
  - if we change function’s prototype property completely (via assigning a new object), the reference to the original constructor (as well as to the original prototype) is lost
  ```javascript
  function A() {}
  A.prototype = {
    x: 10
  };

  var a = new A();
  console.log(a.x); // 10
  console.log(a.constructor === A); // false!
  ```
  - Therefore, this reference should be restored manually:
  ```javascript
  function A() {}
  A.prototype = {
    constructor: A,
    x: 10
  };

  var a = new A();
  console.log(a.x); // 10
  console.log(a.constructor === A); // true
  ```
  - ES5 introduced Object.getPrototypeOf(O) method, which directly returns the [[Prototype]] property of an object — the original prototype of the instance. However, in contrast with __proto__, being only a getter, it does not allow to set the prototype.
  ```javascript
  var foo = {};
  Object.getPrototypeOf(foo) == Object.prototype; // true
  ```
- instanceof operator
  - This operator works exactly with the prototype chain of an object but not with the constructor itself.
  - instanceof operator does is only ==takes the value of the Foo.prototype property== and checks its presence in the prototype chain of foo, starting from the foo.[[Prototype]].
  ```javascript
  function A() {}
  A.prototype.x = 10;

  var a = new A();
  console.log(a.x); // 10

  console.log(a instanceof A); // true

  // if set A.prototype
  // to null...
  A.prototype = null;

  // ...then "a" object still
  // has access to its
  // prototype - via a.[[Prototype]]
  console.log(a.x); // 10

  // however, instanceof operator
  // can't work anymore, because
  // starts its examination from the
  //prototype property of the constructor
  console.log(a instanceof A); // error, A.prototype is not an object
  ```
- Prototype as a storage for methods and shared properties
  - The most useful application of the prototype in ECMAScript is the storage of methods, default state and shared properties of objects.
  ```javascript
  function A(x) {
    this.x = x || 100;
  }

  A.prototype = (function () {

    // initializing context,
    // use additional object

    var _someSharedVar = 500;

    function _someHelper() {
      console.log('internal helper: ' + _someSharedVar);
    }

    function method1() {
      console.log('method1: ' + this.x);
    }

    function method2() {
      console.log('method2: ' + this.x);
      _someHelper();
    }

    // the prototype itself
    return {
      constructor: A,
      method1: method1,
      method2: method2
    };

  })();

  var a = new A(10);
  var b = new A(20);

  a.method1(); // method1: 10
  a.method2(); // method2: 10, internal helper: 500

  b.method1(); // method1: 20
  b.method2(); // method2: 20, internal helper: 500

  // both objects are use
  // the same methods from
  // the same prototype
  console.log(a.method1 === b.method1); // true
  console.log(a.method2 === b.method2); // true
  ```
- Reading and writing properties
  - As we mentioned, reading and writing of properties are managed by the internal methods ==[[Get]]== and ==[[Put]]==.
  ```javascript
  Object.prototype.x = 100;

  var foo = {};
  console.log(foo.x); // 100, inherited

  foo.x = 10; // [[Put]]
  console.log(foo.x); // 10, own , [[Get]]

  delete foo.x;
  console.log(foo.x); // again 100, inherited
  ```
- Property accessors
  - The ==dot notation== is used when the property name is a **valid identifier** name and in advance known, ==bracket notation== allows forming names of **properties dynamically**.
  ```javascript
  var a = {testProperty: 10};

  console.log(a.testProperty); // 10, dot notation
  console.log(a['testProperty']); // 10, bracket notation

  var propertyName = 'Property';
  console.log(a['test' + propertyName]); // 10, bracket notation with dynamic property
  ```
  - So, why in this example “primitive” value a has access to the toString method, but has no to the newly created test property?
  ```javascript
  var a = 10; // primitive value

  // but, it has access to methods,
  // just like it would be an object
  console.log(a.toString()); // "10"

  // moreover, we can even
  // (try) to create a new
  // property in the "а" primitive calling [[Put]]
  a.test = 100; // seems, it even works

  // but, [[Get]] doesn't return
  // value for this property, it returns
  // by algorithm - undefined
  console.log(a.test); // undefined
  ```
  - First, as we said, after the property accessor is applied, it is already not a primitive, but the intermediate object.
  ```javascript
  [[Put]]
  // Algorithm of evaluating a.toString():

  1. wrapper = new Number(a);
  2. wrapper.toString(); // "10"
  3. delete wrapper;

  // Algorithm of evaluating a.test = 100:

  1. wrapper = new Number(a);
  2. wrapper.test = 100;
  3. delete wrapper;
  ```
  - We see that in step 3 the wrapper is removed and its newly created test property is of course also — with removing the object itself.
  ```javascript
  [[Get]]
  // Algorithm of evaluating a.test:

  1. wrapper = new Number(a);
  2. wrapper.test; // undefined
  ```
- Inheritance
  - If you completely understand the simple algorithm of the ==[[Get]]== method, the question on inheritance in JavaScript will disappear by itself and the answer to it will become clear.
  - we can do not create any constructors or objects but ==the whole language is already full of inheritance==. The line of code is very simple:
  ```javascript
  console.log(1..toString()); // "1"
  ```
  - Notice the subtle case of the syntax. Two dots in the example above is not an error. The first dot is used for **fractional part** of a number, and the second one is already a **property accessor**:
  ```javascript
  1.toString(); // SyntaxError!

  (1).toString(); // OK

  1 .toString(); // OK (space after 1)

  1..toString(); // OK

  1['toString'](); // OK
  ```
- Prototype chain
  ```javascript
  function A() {
    console.log('A.[[Call]] activated');
    this.x = 10;
  }
  A.prototype.y = 20;

  var a = new A();
  console.log([a.x, a.y]); // 10 (own), 20 (inherited)

  function B() {}

  // the easiest variant of prototypes
  // chaining is setting child
  // prototype to new object created,
  // by the parent constructor
  B.prototype = new A();

  // fix .constructor property, else it would be А
  B.prototype.constructor = B;

  var b = new B();
  console.log([b.x, b.y]); // 10, 20, both are inherited

  // [[Get]] b.x:
  // b.x (no) -->
  // b.[[Prototype]].x (yes) - 10

  // [[Get]] b.y
  // b.y (no) -->
  // b.[[Prototype]].y (no) -->
  // b.[[Prototype]].[[Prototype]].y (yes) - 20

  // where b.[[Prototype]] === B.prototype,
  // and b.[[Prototype]].[[Prototype]] === A.prototype
  ```
- class
  - In contrast, in the class based model, all properties are copied to the class-descendant.
  - ES3
  ```javascript
  Object.create ||
  Object.create = function (parent, properties) {
    function F() {}
    F.prototype = parent;
    var child = new F;
    for (var k in properties) {
      child[k] = properties[k].value;
    }
    return child;
  }
  ```
  - ES5
  ```javascript
  var foo = {x: 10};
  var bar = Object.create(foo, {y: {value: 20}});
  console.log(bar.x, bar.y); // 10, 20
  ```
  - ES6
  ```javascript
  class Foo {
    constructor(name) {
      this._name = name;
    }

    getName() {
      return this._name;
    }
  }

  class Bar extends Foo {
    getName() {
      return super.getName() + ' Doe';
    }
  }

  var bar = new Bar('John');
  console.log(bar.getName()); // John Doe
  ```
---
#### ECMA-262-5 in detail
- Named data property
  ```javascript
  var defaultDataPropertyAttributes = {
    [[Value]]: undefined,
    [[Writable]]: false,
    [[Enumerable]]: false,
    [[Configurable]]: false
  };
  ```
  - Unfortunately, in ES3 we had no control of property attributes what caused well known issues with augmentation of built-in prototypes.
  ```javascript
  // ES3
 
  Array.prototype.sum = function () {
    // sum implementation
  };

  var a = [10, 20, 30];

  // works fine
  console.log(a.sum()); // 60

  // but because of for-in examines the 
  // prototype chain as well, the new "sum"
  // property is also enumerated, because has
  // {DontEnum} == false

  // iterate over properties
  for (var k in a) {
    console.log(k); // 0, 1, 2, sum
  }
  ```
  ```javascript
  // ES5
  Object.defineProperty(Array.prototype, "sum", {
 
    value: function arraySum() {
      //  sum implementation
    },

    enumerable: false

  });

  // now with using the same example this "sum"
  // is no longer enumerable

  for (var k in a) {
    console.log(k); // 0, 1, 2
  }
  ```
- Named accessor property
  - A named accessor property associates a name (also — only a string) with one or two accessor functions: a getter and a setter.
  - An accessor property can be defined either using already mentioned above meta-method ==Object.defineProperty==:
  ```javascript
  var foo = {};
 
  Object.defineProperty(foo, "bar", {

    get: function getBar() {
      return 20;
    },

    set: function setBar(value) {
      // setting implementation
    }

  });

  foo.bar = 10; // calls foo.bar.[[Set]](10)

  // independently always 20
  console.log(foo.bar); // calls foo.bar.[[Get]]()
  ```
- Strict mode
  - Strict mode syntax and semantics of ECMAScript is explicitly made at the level of individual ECMAScript code units.
  ```javascript
  "use strict";
  // implementation of a module
  ```
  - Strictness scope
  ```javascript
  var eval = 10; // OK
 
  function foo() {
    "use strict";
    alert(eval); // 10
    eval = 20; // SyntaxError
  }

  foo();
  ```
- Assignment to an undeclared identifier
  ```javascript
  // non-strict mode
 
  (function foo() {
    // local vars
    var x = y = 20;
  })();

  // unfortunately, "y" wasn't local
  // for "foo" function
  alert(y); // 20
  alert(x); // "x" is not defined
  
  // ---------------
  
  "use strict";
  a = 10; // ReferenceError

  var x = y = 20; // also a ReferenceError
  ```
- Scope
  - Scope is an enclosing context in which a variable is associated with a value.
  ```javascript
  // global "x"
  int x = 10;

  void foo() {

    // local "x" of "foo" function
    int x = 20;

    if (true) {
      // local "x" of if-block
      int x = 30;
      printf("%d", x); // 30
    }

    printf("%d", x); // 20

  }

  foo();

  printf("%d", x); // 10
  ```
  - Previously the “block-scope” could be implemented as an immediately-invoked function expression (IIFE):
  ```javascript
  var x = 10;
 
  if (true) {
    (function (x) {
      console.log(x); // 20
    })(20);
  }

  console.log(x); // 10
  ```
- Static (lexical) scope
  ```javascript
  var x = 10;
  var y = 20;

  function foo() {
    console.log(x, y);
  }

  foo(); // 10, 20

  function bar() {
    var y = 30;
    console.log(x, y); // 10, 30
    foo(); // 10, 20
  }

  bar();
  ```
- Rebinding
  - Often (and in ECMAScript in particular) rebinding is implemented via a simple operation of assignment.
  ```javascript
  // bind "foo" to {x: 10} object
  var foo = {x: 10};

  console.log(foo.x); // 10

  // bind "bar" to the *same* object
  // as "foo" identifier is bound

  var bar = foo;

  console.log(foo === bar); // true
  console.log(bar.x); // OK, also 10

  // and now rebind "foo"
  // to the new object

  foo = {x: 20};

  console.log(foo.x); // 20

  // and "bar" still points
  // to the old object

  console.log(bar.x); // 10
  console.log(foo === bar); // false
  ```
- First-class functions
  - A first-class function is one that may participate as a normal data, i.e. be created literally at runtime, be passed as an argument, or be returned as a value from another function.
- Funargs and higher-order functions
  - In turn, a function which accepts the “funarg” is called a higher-order function (HOF) or, closely to mathematics, an operator.
- Free variable
  - A free variable is a variable which is used by a function, but is neither a parameter, nor a local variable of the function.
  ```javascript
  // Global environment (GE)
 
  var x = 10;

  function foo(y) {

    // environment of "foo" function (E1)

    var z = 30;

    function bar(q) {
      // environment of "bar" function (E2)
      return x + y + z + q;
    }

    // return "bar" to the outside
    return bar;

  }

  var bar = foo(20);

  bar(40); // 100
  ```