前端开发

作用域、作用域链、执行上下文、预编译

2019-04-11  本文已影响7人  李轻舟

1、作用域
作用域是在运行时代码中的特定变量的有效范围。作用域决定了代码区块中变量和其他资源的可见性。作用域内层可以看见作用域外层,作用域外层不能看见作用域外层,所以作用域在不同作用域中声明的变量不会造成污染和命名冲突。

定义在最外层的函数和变量,未经声明就赋值的变量,window的属性。这里需要注意的是var声明的全局变量以及未经声明就赋值的变量会挂载到window属性上,但是var声明的变量不能删除,未经声明的变量可以删除。

当函数执行的时候就会在内部创建一个函数作用域,当函数执行完成就会销毁该作用域。

在ES6之前是没有块级作用域的,ES6引入了let、const关键字就可以创建块级作用域。

2、作用域链
当在一个函数内部搜索一个变量的时候,如果该函数没有声明该变量,那么就会顺着代码执行环境创建的作用域逐层向外搜索,一直搜索到全局作用域。

3、执行上下文
解释阶段:

执行阶段:

JavaScript在解释阶段便会确定作用域规则,但是执行上下文是在函数执行的前一刻。
执行上下文最明显的就是this指向是在执行的时候确定的。

区别:执行上下文在运行时确定,随时可以改变;作用域在定义时就确定,并且不会改变。同一作用域下,不同的调用会产生不同的执行上下文,从而产生不同的结果。

4、预编译

  1. 创建AO对象
  2. 寻找形参和变量声明
  3. 形参实参相统一
  4. 找函数声明,函数名作为属性名,函数体作为属性值

5、闭包
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域外执行。简单讲,闭包就是指有权访问另一个函数作用域中的变量的函数。

创建闭包:

  1. 在函数内部引用外部函数
let a = 1
function foo() {
  console.log(a)
}
function bar() {
  let a = 2
  foo()
}
bar() // 1

在函数内部返回函数

let a = 'window'
function foo() {
    let a = 'foo'
    return function() {
        console.log(a)
    }
}
let bar = foo()
bar() // foo

闭包的应用和缺陷

  1. 设计私有的方法和变量。
  2. 容易造成内存泄露。
上一篇下一篇

猜你喜欢

热点阅读