bfops
bfops

Reputation: 5688

Javascript: Member-variable-accessing closures

I'm wondering how to deal with member variables in closures in JavaScript. The following code alerts "6".

function testy()
{
    function blah()
    {
        this.a = 5;
        this.func = function()
        {
            this.a = 6;
            alert(this.a);
        }
    }

    var x = new blah;
    x.func();
}

but this code alerts 5.

function testy()
{
    function execute(func)
    {
        func();
    }

    function blah()
    {
        this.a = 5;
        this.func = function()
        {
            execute(function()
            {
                this.a = 6;
            });

            alert(this.a);
        }
    }

    var x = new blah;
    x.func();
}

How do I pass a closure which still accesses the member variables of the enclosing object?

Upvotes: 0

Views: 284

Answers (2)

Raynos
Raynos

Reputation: 169551

execute(function()
{
   this.a = 6;
});

function execute(func)
{
    func();
}

Your calling the function as func(); and by default without specifying a context this will resolve to the global context which is window in the browser.. There are three options you can use here.

make this local

var that = this;
execute(function()
{
   that.a = 6;
});

Now that points to the correct this.

bind this scope to the function

execute((function()
{
   this.a = 6;
}).bind(this));

This will bind the correct / expected this scope to your function. Note that Function.prototype.bind is ES5 and will break older browsers. _.bind is a reasonable cross browser alternative.

edit execute

function execute(f, context) {
    f.call(context);
}

execute(function() {
    this.a = 6;
}, this);

Your passing the context as an extra parameter to execute. Then execute will call Function.prototype.call to make sure that the function is called with the desired context

Upvotes: 1

c-smile
c-smile

Reputation: 27490

Try this:

function blah()
{
    this.a = 5;
    this.func = function()
    {
        var self = this;
        execute(function()
        {
            self.a = 6;
        });
        alert(this.a);
    }
}

Upvotes: 0

Related Questions