views:

20

answers:

3

I'am trying to use some values from the "upper" function in the "inner" function:

function Load(el, script)
{
    el.addEventListener('click',
        function (e)
        {
            this.test = "testing";
            script.apply(this, arguments);
        }, false);
};

Load(document.getElementById("panel"),
    function (e)
    {
        alert(test); // test is undefined
    });

The above example doesn't work, it says test is undefined.

But the following works:

function A(B)
{
  this.test = "bla";
  B.apply(this);
}
function B()
{
  alert(test);
}
A(B);

What's the difference? How can I make it work properly?

+3  A: 

test is a property on the element at that point, so you need to reference it like that:

Load(document.getElementById("panel"),
function (e)
{
    alert(this.test); // "testing"
});

You can test it here. The difference is that in the first example this refers to the id="panel" element and the property is set there. In the second example this refers to the global object, or window, so test is a global variable that works when you go to access it.

Nick Craver
Hmm thanks!! Is there a way to allow me to reference `test` without using `this.` ?
BrunoLM
@BrunoLM - Nope...you have to have some context, unless it's a global or local variable (and it won't be in the handler) you need to reference it from the object it's on.
Nick Craver
I see. Thanks again!
BrunoLM
@BrunoLM `test` and `this.test` are two different variables. You cannot reference one and get the value of the other.
bluesmoon
+1  A: 

In your second example, when you call A(), this refers to the window object since that's the scope in which A() runs. All global variables also belong to the window object, so in that context, test, this.test and window.test are all the same entity.

In the first example, however, this refers to the element on which the handler was called, so this.test (which is defined) is the same as "#panel".test but is different from test and window.test (which are not defined).

bluesmoon
A: 

You should accept Nick Craver's answer, I'm just clarifying here with some more code:

function Load(el, script)
{
    el.addEventListener('click',
        function (e)
        {
            this.test = "testing";  // sets el.test="testing" ('cos this==el)
            script.apply(this, arguments);
        }, false);
};

Load(document.getElementById("panel"),
    function (e)
    {
        alert(test); // alerts window.test, not el.test
    });
function A(B)
{
  this.test = "bla"; // sets window.test="bla" ('cos this==window)
  B.apply(this);
}
function B()
{
  alert(test); // alerts window.test
}
A(B);
lucideer