chris_mac
chris_mac

Reputation: 953

jQuery each() closure - how to access outside variable

What's the best way to access my this.rules variable from within $.each()? Any explanation of why/how would also be helpful!

app.Style = function(node) {
    this.style = node;
    this.rules = [];
    var ruleHolder = node.find('Rule');

    $.each(ruleHolder, function(index, value) {
        var myRule = new app.Rule($(ruleHolder[index]));
        this.rules.push(myRule);
    });

    console.log(this.rules)
}

Upvotes: 22

Views: 29809

Answers (3)

Zoltán Süle
Zoltán Süle

Reputation: 1694

it is more elegant without var self = this;

app.Style = function(node) {
    this.style = node;
    this.rules = [];
    var ruleHolder = node.find('Rule');

    $.each(ruleHolder, function(index, value) {
        var myRule = new app.Rule($(ruleHolder[index]));
        this.rules.push(myRule);
    }.bind(this));

    console.log(this.rules)
}

Upvotes: 1

Dustin Page
Dustin Page

Reputation: 59

The answer above by João Silva is not a good solution as it creates a global variable. You are not actually passing a "self" variable to the each function by reference, but are instead referencing the global "self" object.

In the example above "this" is the window object and setting "var self = this" isn't really doing anything.

The Window object has two self-referential properties, window and self. You can use either global variable to refer directly to the Window object.

In short, both window and self are references to the Window object, which is the global object of client-side javascript.

Creating a closure function is a better solution.

Screenshot showing window and self comparison

Upvotes: 0

João Silva
João Silva

Reputation: 91329

Store a reference to this -- name it self, for example --, before calling .each(), and then access rules using self.rules:

app.Style = function(node) {
    this.style = node;
    this.rules = [];
    var ruleHolder = node.find('Rule');

    var self = this;
    $.each(ruleHolder, function(index, value) {
        var myRule = new app.Rule($(ruleHolder[index]));
        self.rules.push(myRule);
    });

    console.log(this.rules)
}

Upvotes: 26

Related Questions