简体   繁体   English

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

[英]how to access variables in closures if there are local variables with the same name?

I took this from Google Code Playground http://code.google.com/apis/ajax/playground/ 我从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);

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

Its all ok, but if I have a local variable in the inner function with the same name as a variable in the outer function then how to access that variable? 一切都好,但是如果我在内部函数中有一个局部变量,并且外部函数中的变量同名,那么如何访问该变量?

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);

You can't, because the variable of the outer scope is shadowed by the one on your inner function. 你不能,因为外部范围的变量内部函数的变量所遮蔽

The scope chain on the innerFunction looks something like this: innerFunction上的作用域链看起来像这样:

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

* Denotes a resolvable identifier from the scope of innerFunction.

Each function has its own Variable Object , is where the identifiers of Function Declarations, Variable Declarations, and function Formal Parameters live, as properties. 每个函数都有自己的变量对象 ,其中函数声明,变量声明和函数形式参数的标识符作为属性存在。

Those objects are not directly accessible by code, the scope chain is formed by all those chained objects. 这些对象不能通过代码直接访问,范围链由所有这些链接对象组成。

When an identifier is resolved , the lookup goes up in the scope chain, looking for the first appearance of it, until the global object is reached, if the identifier is not found, a ReferenceError is thrown. 解析标识符后,查找在范围链中查找,查找它的第一次出现,直到到达全局对象,如果未找到标识符,则抛出ReferenceError

Give a look to the following articles: 看看以下文章:

The local variables of the closure "shadow" the variables of the same name from the outer function, so this: 闭包的局部变量“影子”外部函数的同名变量,所以这样:

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

will alert Hello . 会提醒Hello

The only way to work around it is to rename your variables, or pass in the variable you want to work with: 解决它的唯一方法是重命名变量,或者传入你想要使用的变量:

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

Will alert Hai! 请警惕Hai!

To learn about the scope chain, take a look at this previous scope question. 要了解范围链, 请查看以前的范围问题。

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); } outerFunction(1);

Try with this.varname to refer to the one in the closure. 尝试使用this.varname来引用闭包中的那个。

this.someString in your example. 你的例子中有this.someString。

You could 你可以

  • simply avoid creating any local variable with the same name, or 只需避免创建具有相同名称的任何局部变量,或
  • make a local copy of that closure variable before declaring the local variable of the same name (if you really want a local variable of the same name) 声明同名的局部变量 之前 ,创建该闭包变量的本地副本(如果你真的想要一个同名的局部变量)

(had a workaround but removed it after it was pointed out that it wouldn't actually work) (有一个解决方法,但在指出它实际上不起作用后删除它)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM