Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

javascript

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 innerFunction() {
    var someString='Hello';
    content.innerHTML = someNum + ': ' + someString;
    content = null; // IE memory leak for DOM reference
  }
  innerFunction();
}

outerFunction(1);
like image 899
Sriram Avatar asked Aug 13 '10 06:08

Sriram


People also ask

Can we access global variable if there is a local variable with same name?

Global Variable: The variable that exists outside of all functions. It is the variable that is visible from all other scopes. We can access global variable if there is a local variable with same name in C and C++ through Extern and Scope resolution operator respectively.

Can local variables have the same name?

Local variable cannot have the same name as the function containing it.

Can a function have a parameter or a local variable with the same name as a global variable?

Within a function, each variable is either local or globalWhen you have two variables of the same name, a global variable, and a local variable, inside your function, that variable name will always be either global or local. One variable cannot be both global and local inside the same function.

What kind of access closure variables have?

A closure is an inner function that has access to the outer (enclosing) function's variables — scope chain. The closure has three scope chains: it has access to its own scope (variables defined between its curly brackets), it has access to the outer function's variables, and it has access to the global variables.


2 Answers

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
like image 106
Christian C. Salvadó Avatar answered Sep 29 '22 21:09

Christian C. Salvadó


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.

like image 39
Peter Ajtai Avatar answered Sep 29 '22 21:09

Peter Ajtai