0

I have a small piece of code here, which is a model of some situation I am stuck with. For me as a PHP programmer this is so easy to do in PHP, but I never know how to do this in JS. Maybe someone can help.

var counterObj = {

items: [1,4,7],

total: 0,

run: function() {

    $.each(this.items, function(i, item){
        // Call my own method
        this.add(item);
    })
    .promise()
    .done(function(){

        // doubt it will log 12
        console.log(this.total);
    });
},

add: function(item){
    this.total = this.total + item;
}
};

counterObj.run();

http://jsfiddle.net/EH9qK/

4
  • 2
    promose......... I'll read the docs again Commented Feb 23, 2014 at 7:32
  • .promose() is that a new method or something Commented Feb 23, 2014 at 7:34
  • No i fixed that, spelling mistake. Hope you were just trying to be funny. Commented Feb 23, 2014 at 7:35
  • @SaifBechan - The problem in your code is that this is referring to the number in the array. Commented Feb 23, 2014 at 7:36

3 Answers 3

1
run: function() {
    $.each(this.items, function(i, item){
        this.add(item);
    })
    .promise()
    .done(function(){
        console.log(this.total);
    });
}

this inside $.each is referring to the number in your array (blame jQuery for that.) Instead, you should do this:

run: function() {
    var _this = this;
    $.each(this.items, function(){
        _this.add(this);  //so many "this"
    });
    console.log(this.total);
}

http://jsfiddle.net/DerekL/EH9qK/4/

By the way, .promise and .done only exist in jQuery objects. $.each returns the original array.


this in JavaScript is a really confusing keyword. It can also be changed with .apply, which is what jQuery has done in its methods:

The value can also be accessed through the this keyword, but Javascript will always wrap the this value as an Object even if it is a simple string or number value.
From jQuery's docs

But even if jQuery isn't modifying this, it would still be referring to the wrong object (window).

Oh yea, 1 + 4 + 7 is 12, not 13. :)

Sign up to request clarification or add additional context in comments.

1 Comment

I would not recommend using the variable 'self' since it points to the 'window' object by default in browsers.'that' or '_this' would be much more readable.
0

Each function you declare creates another scope. All you have to do is bind the functions to the counterObject by calling the bind 'method'. I don't understand the use of 'promise' but I tried to make as little changes as I can in your code so my changes will be clear.

var counterObj = {

    items: [1,4,7],

    total: 0,

    run: function() {

        $.each(this.items, function(i, item){
            // Call my own method
            this.add(item);
        }.bind(this))
        .promise()
        .done(function(){

            // doubt it will log 13
            console.log(this.total);
        }.bind(this));
    },

    add: function(item){
        this.total = this.total + item;
    }
};

counterObj.run();

Comments

0

You need to return the functions that are supposed to be public from your scope, otherwise they are considered private.

For your example:

var counterObject = {
    ...
    return {
        run: run
    };
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.