js上下文、作用域、闭包

84 阅读2分钟

1、介绍 javascript 的执行上下文

JavaScript 中有三种执行上下文类型。

  • 全局执行上下文: 这是默认或者说基础的上下文,任何不在函数内部的代码都在全局上下文中。它会执行两件事:创建一个全局的 window 对象(浏览器的情况下),并且设置 this 的值等于这个全局对象。一个程序中只会有一个全局执行上下文。
  • 函数执行上下文: 每当一个函数被调用时, 都会为该函数创建一个新的上下文。每个函数都有它自己的执行上下文,不过是在函数被调用时创建的。函数上下文可以有任意多个。每当一个新的执行上下文被创建,它会按定义的顺序执行一系列步骤。
  • Eval 函数执行上下文: 执行在 eval 函数内部的代码也会有它属于自己的执行上下文。(eval 是 Javascript 内置函数,用于计算字符串表达式的值。例如 eval("2+3") 返回的是 5。)

2、介绍 javascript 的作用域

作用域是指程序源代码中定义变量的区域。 作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。 JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。 因为 JavaScript 采用的是词法作用域,函数的作用域在函数定义的时候就决定了。 而与词法作用域相对的是动态作用域,函数的作用域是在函数调用的时候才决定的。 因为局部变量只作用于函数内,所以不同的函数可以使用相同名称的变量。 局部变量在函数开始执行时创建,函数执行完后局部变量会自动销毁。 让我们认真看个例子就能明白之间的区别:

var value = 1;
function foo() {
console.log(value);
}
function bar() {
var value = 2;
foo();
}
bar();

// 结果是 1

3、介绍 javascript 的闭包是什么,应用场景

闭包:JavaScript 的闭包是一个函数对象,它包含了函数体内定义的变量和函数。它们在其外层作用域不失效,即可以被返回并且执行。

  • 1.闭包可以捕获并保存其所在函数的作用域。

  • 2.闭包可以访问创建它的上下文的所有变量,即使它已经超出了作用域。

  • 3.闭包可以在其所在函数外部被调用,并且可以继续访问其作用域内的变量。

  • 4.闭包是动态的,因此它可以在运行时更改其内部状态。

例子

function createCounter() {
    var count = 0;
    return function() {
        count++;
        return count;
    }
}
var counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2