JavaScript学习----------变量的声明和赋值、预编译、作用域链和闭包

变量的声明和赋值、预编译、作用域链和闭包

1.变量的声明和赋值

var x = 1   先声明,后赋值。

es6定义了let关键字。替代var声明一个块级作用域的变量。

常量:const来定义常量。const和let都有块级作用域的特点。

解构赋值:var [x,y,z] = ['a','b','c']

 

aa = 1      不会报错。和预编译那有关。其实是window.aa = 1。这个不参与预编译。预编译只找有var声明的。

例如:

console.log(xxx) -----------undefined

var xxx = 5

console.log(xxx) ------------ 5

 

console.log(xxx) -----------报错

xxx = 5 ------------------------未参与预编译

console.log(xxx) ------------ 5

 

 

 

2.预编译

JavaScript引擎的三大步骤:

预编译(第一次扫描)

解释执行(第二次扫描)

 

预编译----脚本

JavaScript学习----------变量的声明和赋值、预编译、作用域链和闭包

 

JavaScript学习----------变量的声明和赋值、预编译、作用域链和闭包

脚本的预编译:

1.没有var的变量,都不是变量声明,全部认为是window的全局变量,不参与预编译。

2.即使在函数中,aa = 5 也是全局变量,在运行时,而不是定义时。

3.脚本中,所有变量声明,在脚本预编译阶段完成,声明与实际的书写位置无关。

4.脚本中,所有函数声明,在脚本的预编译阶段完成,所有函数的声明与实际书写位置无关。

5.脚本中,如果函数和变量重名,那么函数将覆盖变量。

6.脚本中,只有函数能覆盖变量,变量无法覆盖函数。

7.脚本中,后面的函数声明会覆盖前边的函数声明,并且忽略参数。(忽略重载)

 

 

 

函数的预编译-----函数调用

预编译除了发生在脚本第一次运行以外,还发生在函数调用的阶段。 

 JavaScript学习----------变量的声明和赋值、预编译、作用域链和闭包

1.函数中,所有变量声明,在函数的预编译阶段完成,所有变量的声明与实际的书写位置无关。

2.函数中,所有函数声明,在函数的预编译阶段完成,所有函数的声明与实际的书写位置无关。

3.函数中,如果变量和函数重名,那么函数将覆盖变量。

4.函数中,只有函数能覆盖变量,变量无法覆盖函数。

5.函数中,后边的函数声明会覆盖前边的函数声明。

6.当函数预编译后,遇到需要访问的变量和函数,优先考虑自己AO中定义的函数和变量。如果找不到,才会在其定义的上一层AO中寻找,直到到达GO。

 

例题:

function test(x,x){

  console.log(x);

  x=5;

  console.log(arguments);

  function x(){}

}

test(12,13)

 

GO:

test:function

test-AO:

arguments:[12,5]

x-和arguments[1]绑定:5

 

输出:function、[12,5]

 

 

作用域链和闭包:

1.执行环境和作用域链:

执行环境:execution context 简称ec,它定义了执行期间可以访问的变量和函数。也就是说它是变量和函数的表。

      全局执行环境:global object----GO----window,从见到代码开始创建,到网页关闭销毁。 

      函数执行环境:activation object ------AO,从函数开始调用开始创建,到函数结束时销毁。

作用域链:函数被创建时作用域中对象的集合:scope chain,是AO和GO构成的链。每个函数都有。作用域是私有属性 ,只能有js引擎去访问。

生成作用域链:每个函数在定义(函数声明和函数表达式)时都会拷贝其父亲函数的作用域链。

          在函数被调用时,生成AO然后将AO压入作用链的栈顶。

JavaScript学习----------变量的声明和赋值、预编译、作用域链和闭包

 

JavaScript学习----------变量的声明和赋值、预编译、作用域链和闭包

 

闭包的作用:

模块化操作,避免污染共有变量。

 

闭包的习题:

JavaScript学习----------变量的声明和赋值、预编译、作用域链和闭包

 

 JavaScript学习----------变量的声明和赋值、预编译、作用域链和闭包