描述 JavaScript 变量

在 JavaScript 中,变量是存储位置的名称。

它可用于存储好东西、访客或者其他数据。

我们可以使用诸如“var”、“let”和“const”之类的关键字来创建变量。

存在两种类型的 JavaScript 变量:局部变量和全局变量。

局部变量在函数内部声明,或者块只能在函数或者块内访问。

相反,全局变量可以从任何函数访问。
它们可以在函数外或者使用窗口对象声明。

JavaScript 闭包如何工作

在此教程中,我们将解释 JavaScript 闭包是如何工作的。

通常,闭包是函数与其外部词法环境之间的唯一链接。

闭包可以被认为是支持一流功能的一种方式。

它是一个表达式,能够在其范围内引用变量。

下面是一个闭包的例子:

function sayWelcome(siteName) {
  let message = 'Welcome to ' + siteName; //局部变量
  let welcome = function () {
    console.log(message);
  }
  return welcome;
}
let welcome1 = sayWelcome('onitroad');
welcome1(); //输出 "Welcome to onitroad"

上面提到的代码返回对函数的引用。

它有一个闭包,如匿名 function() { console.log(text); } 在另一个函数中声明。

因此,在 JavaScript 中,无论何时使用 function 关键字,都会创建一个闭包。

如果你在另一个函数中声明一个函数,那么外部函数的局部变量在从它返回后仍然可以访问。

之所以如上所示,是因为在从 sayWelcome() 返回之后调用了函数welcome1()。

被调用的代码引用了变量 message,它是 sayWelcome() 函数的局部变量:

function sayWelcome() {
  console.log(message);
} //Output of welcome1.toString();

如果我们查看welcome1.toString() 的输出,我们将看到代码引用了变量消息。

下一个示例演示了局部变量没有被复制而是通过引用保留:

function incrementFunc() {
  //结束于闭包中的局部变量
  let num = 5;
  let say = function () {
    console.log(num);
  }
  num++;
  return say;
}
let sayNumber = incrementFunc();
sayNumber(); //logs 6

下一个示例显示 JavaScript 闭包包含在其存在之前在外部函数中声明的任何局部变量。

请注意,变量 account 可能在匿名函数之后声明,因为 account 在同一范围内。
而且,sayWelcome()()可以直接调用sayWelcome()返回的函数引用:

function sayWelcome() {
  let welcome = function () {
    console.log(account);
  }
  //结束于闭包中的局部变量
  let account = 'Welcome to oir';
  return welcome;
}
sayWelcome()(); //输出 "Welcome to oir"

在最后一个例子中,我们演示了对 main 函数的每次调用如何创建一个单独的闭包:

function newClosure(someNumber, someReference) { //结束于闭包中的局部变量
  let num = someNumber;
  let array = [1, 2, 3];
  let ref = someReference;
  return function (x) {
    num += x;
    array.push(num);
    console.log('number: ' + num + '; array: ' + array.toString() + '; ref.someVar: ' + ref.someVar + ';');
  }
}
obj = {
  someVar: 4
};
func1 = newClosure(4, obj);
func2 = newClosure(5, obj); //注意这里:新闭包分配给一个新变量!
func1(1); //number: 5; array: 1,2,3,5; ref.someVar: 4; 
func2(1); //number: 6; array: 1,2,3,6; ref.someVar: 4; 
obj.someVar++;
func1(2); //number: 7; array: 1,2,3,5,7; ref.someVar: 5; 
func2(2); //number: 8; array: 1,2,3,6,8; ref.someVar: 5;

因此,可以假设每当我们在另一个函数中应用函数时,都会使用闭包。
还有另一种选择。
任何时候在函数内应用 eval() 时,都会使用闭包。
我们评估的文本可能会引用函数的局部变量。
在 eval 中,我们可以使用 eval ('var foo = …') 创建新的局部变量。

在 JavaScript 中,闭包就像保存函数存在时所有局部变量的副本。

最好认为闭包总是作为函数的入口,并且局部变量被添加到闭包中。

日期:2020-06-02 22:16:07 来源:oir作者:oir