JavaScript中的作用域和闭包

作用域是什么

作用域:是代码中定义变量的区域。它规定了哪些区域存储了变量,以及如何去查找这些变量。比如说,下面这段代码,在输出a的时候,会在函数foo的作用域中去查找a的值,然后输出。

function foo() {
    var a = 1;
    console.log(a); // 1
}

词法作用域和动态作用域

作用域分为词法作用域和动态作用域。

  • 词法作用域
    词法作用域:在函数的定义时,函数作用域就已经确定了。JavaScript中使用的就是词法作用域。
  • 动态作用域
    动态作用域:函数的作用域是在运行时确定的。看个简单的栗子:
function foo() {
	console.log( a ); // 词法作用域输出的是 2,动态作用域输出的是 3
}
function bar() {
	var a = 3;
	foo();
}
var a = 2;
bar();

作用域链

先看段代码:

在全局作用域中:有 foo ;
在函数作用域 1 中:有 a、b、bar ;
在函数作用域 2 中:有 a、b、c ;
运行时,引擎会从当前变量引用处的作用域,一层一层向上查找变量。比如说,上面这段代码,引擎在执行console.log()时,首先在函数作用域 2 (bar)中查找变量a、b、c的值,在当前作用域中,没有发现a的值,会从上一层作用域(foo)中查找a的值,在这里找到了a的值,然后就使用了a的值。变量bc同理,也是一层一层向上查找,直到找到全局作用域为止。一旦找到第一个匹配,作用域查询就停止了。

闭包

闭包:有权访问另一个函数作用域内变量的函数;

function foo() {
    let a = 2
}

先看这段代码,在函数foo的作用域中有个变量a = 2,如果有个函数bar能够访问函数foo中的变量a,那函数bar就是个闭包。说的简单,怎么才能让函数bar能够访问到函数foo 中的变量a呢。确实很简单,在函数foo中我们返回一个函数,这个函数引用了变量a就可以了。

function foo() {
  let a = 2
  return () => {
    console.log(a)
  }
}
const bar = foo()
bar() // 2,bar是个闭包
posted @ 2019-03-24 18:30  yangrenmu  阅读(163)  评论(0编辑  收藏  举报