如果存在具有相同名称的局部变量,如何访问闭包中的变量?

时间:2010-08-13 06:42:19

标签: javascript

我是从Google Code Playground http://code.google.com/apis/ajax/playground/

获取的
/*CLOSURE
* When a function is defined in another function and it
*    has access to the outer function's context even after
*    the outer function returns
* An important concept to learn in Javascript
*/

function outerFunction(someNum) {
  var someString = 'Hai!';
  var content = document.getElementById('content');
  function innerFunction() {
    content.innerHTML = someNum + ': ' + someString;
    content = null; // IE memory leak for DOM reference
  }
  innerFunction();
}

outerFunction(1);

///////////////////////

一切正常,但是如果我在内部函数中有一个局部变量,并且外部函数中的变量同名,那么如何访问该变量?

function outerFunction(someNum) {
  var someString = 'Hai!';
  var content = document.getElementById('content');
  function innerFunction() {
    var someString='Hello';
    content.innerHTML = someNum + ': ' + someString;
    content = null; // IE memory leak for DOM reference
  }
  innerFunction();
}

outerFunction(1);

5 个答案:

答案 0 :(得分:8)

你不能,因为外部范围的变量被内部函数上的阴影

innerFunction上的范围链看起来像这样:


  innerFunction                     outerFunction             global object
 ______________________         ________________________        _______________
|* someString = 'Hello'| <---- |  someString = 'Hai!'    | <---|* outerFunction|
 ----------------------        |* content = [HTMLElement]|     |    .....      |
                               |* someNum (argument)     |      ---------------
                               |* innerFunction          |
                                -------------------------

* Denotes a resolvable identifier from the scope of innerFunction.

每个函数都有自己的变量对象,它是函数声明,变量声明和函数形式参数的标识符,作为属性。

代码无法直接访问这些对象,范围链由所有这些链接对象组成。

当标识符为resolved时,查找在范围链中上升,查找它的第一次出现,直到到达全局对象,如果找不到标识符,则为ReferenceError扔了。

查看以下文章:

答案 1 :(得分:1)

关闭的局部变量“影子”外部函数同名的变量,所以这个:

function outerFunction(s) {
  var someString = 'Hai!';
  function innerFunction() {
    var someString='Hello';
    alert(someString);
  }
  innerFunction();
}
outerFunction();

will alert Hello.

解决这个问题的唯一方法是重命名变量,或者传入你想要使用的变量:

function outerFunction(s) {
  var someString = 'Hai!';
  function innerFunction(outer) {
    var someString='Hello';
    alert(outer);
  }
  innerFunction(someString);
}
outerFunction();        

Will alert Hai!

要了解范围链take a look at this previous scope question.

答案 2 :(得分:0)

尝试使用this.varname来引用闭包中的那个。

你的例子中的this.someString。

答案 3 :(得分:0)

你可以

  • 简单地避免创建具有相同名称的任何局部变量,或
  • 声明同名的局部变量之前制作闭包变量的本地副本(如果你真的想要一个同名的局部变量)

(有一个解决方法,但在指出它实际上无法正常工作后将其删除)

答案 4 :(得分:0)

function outerFunction(someNum) {
var someString = 'Hai!';
var content = document.getElementById('content');
function innerFunction() {
this.someString = 'Hello'; 
content.innerHTML = someNum + ': ' + someString;
content = null; // IE memory leak for DOM reference
 }
    innerFunction();

}     outerFunction(1);