Scope: Is responsible for collecting and maintaining a series of queries made up of all declared identifiers (variables) and enforcing a very strict set of rules that determine access to these identifiers by currently executing code.

The environment in which the code is currently running, accessible variables, and variable environment objects on the scope chain.

Identifier interpretation

An identifier is the name of a variable, function, attribute, or function parameter. An identifier can consist of one or more of the following characters:

  • The first character must be a letter, underscore (_), or dollar sign ($);
  • The remaining characters can be letters, underscores, dollar signs, or numbers.

The letters in the identifier can be Extended ASCII, or Unicode alphabetic characters, such as A and æ is not recommended.

Execution context

Each execution context corresponds to three objects, divided into two distinct phases:

create

  • this
  • 【 Variable object】

perform

  • this
  • Variable object = “activation Object”
  • 【scope chain】


The scope chain

var color = "blue";

function changeColor() {
  let anotherColor = "red";

  function swapColors() {
    let tempColor = anotherColor;
    anotherColor = color;
    color = tempColor;
  }
  
  swapColors();
}

changeColor();

Copy the code

Global context execution

GlobalContext: { ... window,color: 'blue'.changeColor: fn
}
Copy the code

Meanwhile: The execution context of the changeColor function is the GlobalContext.

ChangeColor call

The current execution context is:

changeColorContext: {
  'activation object': {
      anotherColor: 'blue'.swapColors: fn
  },
  'scope chain': [changeColorContext= > GlobalContext]
}
Copy the code

SwapColors call

The current execution context is:

swapColorsContext: {
  'activation object': {
      tempColor: 'blue'
  },
  'scope chain': [swapColorsContext= > changeColorContext= > GlobalContext]
}
Copy the code

Here color does not belong to the active object of the current execution context, but to the value of the GlobalContext in the scope chain. AnotherColor belongs to changeColorContext. Identifier resolution at code execution is done by searching identifier names down the scope chain. The search process always starts at the very top of the scope chain and moves down until the identifier is found


An interview question

Compare the following two pieces of code and describe the differences between them// A--------------------------
var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
      debugger
        return scope;
    }
    return f();
}
checkscope();

// B---------------------------
var scope = "global scope";

function checkscope(){
    var scope = "local scope";
  
    function f(){
        return scope;
    }
    return f;
}
checkscope()();
Copy the code

A. the ECS

  1. Main process: [GlobalContext]
  2. Checkscope executes: [checkscopeContext => GlobalContext]
  3. Line 9: fContext => checkscopeContext => GlobalContext
  4. Line 9 return statement: [checkscopeContext => GlobalContext]
  5. [GlobalContext]


B the ECS

  1. Main process: [GlobalContext]
  2. Checkscope executes: [checkscopeContext => GlobalContext]
  3. Line 9 return statement: [checkscopeContext => GlobalContext]
  4. Checkscope performs method calls: fContext => GlobalContext
  5. [GlobalContext]

The result is “local scope”, because js is a static scope, and because the scope inside the variable object when f is created is “local scope”.

Dmitrysoshnikov.com/ecmascript/…

In the further explanation we’ll mainly use the concept of an environment, rather than scope,

Scope is replaced by the concept of environment. How does scope correspond to environment variables? My personal understanding is as follows:



Scope refers to variables outer points to the parent environment, all the way to global. The execution stack ECS is not necessarily related to the current execution context, the only thing that matters is that this points to.




The context concept replaces the execution context under scope

Execution context (more on that in the next article)

  1. The determination of the this value, known as the This binding.
  2. Create the lexical environment component.
  3. Create the variable environment component.


The scope chain is enhanced

  • The catch block of a try/catch statement
  • With statement

In both cases, a variable object is added to the front of the scope chain. For the with statement, the specified object is added to the front of the scope chain; For a catch statement, a new variable object is created that contains the declaration of the error object to be thrown.

let name = 'rod';
let name1 = 'rod';

function testWith() {
  let withObject = {
    name: 'rodchen'.age: '15'
  }

  with(withObject) {
    console.log(name)
    console.log(name1)
  }
}

testWith()
Copy the code





The with statement uses var to create variables that belong to the owning function. Let/const is in block scope.

let name = 'rod';
var name1 = 'rod';

function testWith() {
	let withObject = {
    name: 'rodchen'.age: '15'
  }

  with(withObject) {
    let test = 'test'
    console.log(name)
    console.log(name1)
  }

  console.log(test)
}

testWith()
Copy the code







Block-level scope





The differences in question are:

  • Block-level scope
  • Whether it can be accessed before being declared
  • Whether the global property will be created
  • Whether it can be redirected
  • Can I redeclare it

When const/let is defined in a function, these two types of variables are stored in the execution context of the current function. If created within {} within a function, a new block-level variable object is created for the current {}.

let name = 'rod';
var name1 = 'rod';

function testWith() {
  let withObject = {
    name: 'rodchen'.age: '15'
  }

  if(1) {
    let a = 1
    console.log(a)
  }

  console.log(withObject)
}

testWith()
Copy the code


chorme





firefox



graphic

This is a function that does not create let/const inside {}







This is a function inside {} that creates let/const







Conclusion:

What is a scope chain?

When a variable is searched, it is first searched from the variable object of the current context. If it is not found, it is searched from the variable object of the execution context of the parent (lexical level parent) until it finds the variable object of the global context, that is, the global object. Thus a linked list of variable objects in multiple execution contexts is called a scoped chain