为什么在 IIFE 的情况下没有将值分配给变量?

Why is the value not assigned to the variable in case of an IIFE?

(function() {
    var a = b = 3;
})();

console.log(a, b);



(function() {
    var x = y = 3;
    console.log(x, y);    
})();

这些都是非常简单的程序。但是我很困惑为什么 a 未定义而 b 在第一个示例程序的输出中具有值 3 而 xy 在第一个示例程序中都具有值 3第二个示例程序?

(function() {
    var a = b = 3;
})();

console.log(a, b);

创建 IIFE 时,会创建一个函数 called.Here a 是局部变量,变量具有局部作用域,因此您无法在外部访问它

您没有在 b 前面使用 var,因此它成为全局变量,因此也反映在函数范围之外

基本上 var a = b = 3; 等同于 var a = (b = 3); 并且您可能知道在 JavaScript 中变量可以在没有 var 关键字的情况下定义,并且当您声明变量时没有 var 关键字那么变量将在全局范围内,所以在 IIFE 之外你记录 b 并且结果为 3 但是当你尝试记录 a 变量 a 是未定义的,因为变量声明 var 关键字具有局部作用域,不能在其作用域外访问。

所以,这告诉你:

var a = b = 3;
//b = 3; //global scope //first it assigns b = 3.
//var a = 3;//local scope //then assigns a = 3.

因为在第一个函数中你声明了局部变量 var a 并在函数外部打印,它不访问局部变量所以它是未定义的。

你在访问局部变量的函数中打印的第二个函数运行良好

所有给出的答案都是正确的。我只是想用你自己的代码来展示发生了什么,并让遇到这个问题的其他人非常清楚所涉及的一切。我做这件事几乎是为了好玩 ;D

这里发生了三件事:

  1. 关联性:当按照给定的代码进行赋值时,所有内容都是从右到左,而不是左向右。所以表达式被有效地重新排序。

  2. 范围变量: 如果您不为每个变量使用 var,则给定变量将被视为全局变量,泄漏到局部函数范围之外。可以同时设置多个变量,使用逗号(var a = 1, b = 2;)。这有效地将 var 复制到每个新变量,使每个变量都具有局部范围(相当于:var a = 1; var b = 2;)。

  3. 全局与局部作用域:同一作用域内的代码(在本例中是同一函数的局部)可以看到该作用域内的变量。该范围之外的代码(在本例中为函数之外)将只能看到未绑定在该函数内的全局变量。

让我们看一下原始代码,把事情搞清楚:

(function() {
    // var a = b = 3;
    b = 3; // no var, gets outside of the function's scope (known as global scope)
    var a = b; // with var, stays inside the function's scope (known as local scope)
})();

// we're outside of the function now
// we can't see any of the variables local to the function's scope, but we *can* see variables in the global scope

console.log(a, b);
// there is no `a` variable set in the global scope, so that value is given as `undefined`
// there is a `b` variable set in the global scope, so its value (3) is given

(function() {
    // var x = y = 3;
    y = 3; // global
    var x = y; // local

    // we're still inside the function, so we can still see its scoped variables
    console.log(x, y);
    // `x` is local, so its value (3) is used
    // `y` is global, and global variables can be seen from anywhere. so its value (3) is also used
})();

您可以通过将代码更改为如下内容来使所有内容都本地化:

(function() {
    var a = b = 3; // local a, global b
    // the original code

    var b, a = b = 3; // local a, local b
    // because of the comma, the `var` applies to all variables; 
equivalent to:
    // var b; // local; further assignments to `b` will stay local
    // b = 3; // local
    // var a = b; // local

    var b = 3, a = b; // local a, local b; equivalent to:
    // var b = 3;
    // var a = b;

    var a, b; a = b = 3; // local a, local b; equivalent to:
    // var a; var b;
    // b = 3; // local
    // a = b; // local
})();

或者通过完全不使用 var 使其成为全局的,如下所示:

(function() {
    var a = b = 3; // local a, global b
    // the original code

    a = b = 3; // global a, global b; equivalent to:
    // b = 3; // global
    // a = b; // global
})();

如您所见,很容易让变量泄漏到函数范围之外。因此,在编码时,我们需要确保 var 应用于我们创建的所有变量,除非我们实际上 想要 全局设置一个变量。

设置局部 var 时要记住的一件事是,那个 变量将 "shadow" 任何具有相同名称的全局变量。当代码是 运行 时,任何局部作用域的变量都将在 之前被使用 它会在链的更高层查找相同的变量名(如果该函数嵌套在另一个函数中,或者最终一直到全局范围)。