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

时间:2013-11-27 13:06:28

标签: javascript closures

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

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

bar();
console.log(foo);  // returns 1

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

4 个答案:

答案 0 :(得分:5)

由于一个名为“hoisting”的概念,函数声明被“移动”到范围的顶部。

当发生这种情况时,会在本地范围内创建新的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

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
}

您可以使用var声明函数的方法来阻止它挂起,但您通常会避免重复使用这样的名称,以保持代码的可维护性:

var foo = 1;
function bar() {
    console.log(foo); // undefined
    foo = 10;
    return;
    var foo = function () {};
}
bar();
console.log(foo); // 1

http://jsfiddle.net/znrG2/

...但正如您所看到的,一旦您在范围块中使用var字词,就会提升该本地情境的存在,如果不是值,则当前作用域中不能访问或影响父作用域中具有相同名称的变量。

类似地,使用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

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

相关阅读

答案 1 :(得分:2)

这是javascript提升行为。看一下这个link。在您的情况下,脚本的解释如下:

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

bar();
console.log(foo);

由于:

  

始终移动函数声明和变量声明   (“悬挂”)无形地到达其包含范围的顶部   JavaScript解释器

在您的情况下,当您指定foo = 10;时,您将分配 本地变量 。这就是全局变量仍未改变的原因。

答案 2 :(得分:1)

函数foo(){}在本地bar()作用域中定义,所以如果你在bar()中重新定义foo(),它会改变局部作用域变量而不是全局

答案 3 :(得分:0)

function bar() {
  foo = 10;  // define global variable named foo
  return;    // the function return value is "undefined"
  function foo() {}   // define a function named "foo" inside bar function, which means `foo = 10` inside function bar() becomes local variable declaration because "foo" is already defined.
}

因此全局变量foo根本不会受到影响。