return语句后的函数声明全局变量不会被覆盖

Jee*_*evi 7 javascript closures

我有一个如下的Javascript代码,http://jsfiddle.net/ramchiranjeevi/63uML/

var foo = 1;
function bar() {
    foo = 10;
    return;
    function foo() {}   
}

bar();
console.log(foo);  // returns 1
Run Code Online (Sandbox Code Playgroud)

执行代码时,将调用bar()函数,并使用值10覆盖全局变量,然后将日志打印为10,而不是将其打印为值1。

Chr*_*ker 6

由于有一个称为“提升”的概念,因此将函数声明“移至”作用域的顶部。

发生这种情况时,将foo在本地范围内创建一个新的上下文。以后的分配10会影响本地范围,而不影响父范围的变量。

如果声明foo使用var关键字调用的块局部变量,则可以看到相同的行为:

var foo = 1;
function bar() {
    var foo = 10; // this is, functionally,
    return;       // the same as declaring a function in this scope named foo
}

bar();
console.log(foo); // output: 1
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/GRMule/8F5K3/

另一个例子,将其分解

var foo = 1;
function bar() {
    console.log(foo); // because of hoisting, you will get "function" as output
    foo = 10;         // you just over-wrote the block-local foo, the function
    return;
    function foo () {} // this is "hoisted" to the top of this scope, 
                       // creating a new "foo" context
}
Run Code Online (Sandbox Code Playgroud)

您可以使用var声明函数的方法来阻止其吊起,但通常应避免使用这样的名称,以使代码可维护:

var foo = 1;
function bar() {
    console.log(foo); // undefined
    foo = 10;
    return;
    var foo = function () {};
}
bar();
console.log(foo); // 1
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/znrG2/

...但是,正如您所看到的,一旦var在作用域块中使用了该词就将悬挂该本地上下文的存在(如果不是value的话),并且父作用域中具有相同名称的任何变量将不可访问或受到影响。在当前范围内。

同样,在范围内使用声明的函数和变量this,例如this.foo = function () {}; 不会提升:http : //jsfiddle.net/8F5K3/3/

不过,最重要的是,使用的函数或变量声明this不会覆盖父作用域中的变量上下文。如果您绝对需要重用名称“ foo”,则可以使用该事实来避免使用该语言的此功能:

var foo = 1;
function bar() {
    console.log(foo); // 1
    foo = 10;
    return;
    this.foo = function () {};
}
bar();
console.log(foo); // 10
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/znrG2/1/

相关阅读