为什么在IIFE的情况下未将值赋给变量?

时间:2016-07-21 05:21:18

标签: javascript iife

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

console.log(a, b);



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

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

4 个答案:

答案 0 :(得分:3)

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

console.log(a, b);

创建IIFE时,会创建一个函数并被调用。这是一个局部变量,变量具有局部范围,因此您无法在外部访问它

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

答案 1 :(得分:1)

基本上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.

答案 2 :(得分:1)

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

和第二个函数打印在访问局部变量的函数内部,因此效果很好

答案 3 :(得分:1)

所有答案都是正确的。我只是想用你自己的代码来展示正在发生的事情,并让所有涉及到这个问题的人都清楚地了解所有事情。而且我非常喜欢这样做; D

这里发生了三件事:

  1. 相关性:当分配与给定的代码一样时,所有内容都从从右向左流动,而不是从左到右。所以表达式被有效地重新排序。

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

  3. 全局与本地范围:同一范围内的代码(在同一函数的本地,在本例中)可以查看该范围内的变量。在该范围之外的代码(在该函数之外,在这种情况下)将只能看到未在该函数中绑定的全局变量。

  4. 让我们看看原始代码,以便清理:

    (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时要记住的一件事是, 变量将“遮蔽”具有相同名称的任何全局变量。当代码运行时,任何本地范围的变量将在之前使用它在链上方查找相同的变量名(如果函数嵌套在另一个函数中,或者最终一直到全球范围)。