开发者

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/

/*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 inne开发者_如何学JAVArFunction() {
    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                     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.

Give a look to the following articles:

  • ECMA262-3 in detail: The Variable Object
  • Variables vs. Properties in JavaScript


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.

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!

To learn about the scope chain, take a look at this previous scope question.


Try with this.varname to refer to the one in the closure.

this.someString in your example.


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)


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜