3

I have following code of javascript

var Obj = {
    init: function () {
        this.over = $('<div />').addClass('over');
        $('body').append(this.over);
        $('.click').on('click', this.show);
    },
    show: function () {
        console.log(this.over);
    }
}

Obj.init();

When this does is when user clicks a .click link then it triggers show function and logs out the dom element created in init function. But the problem is then it logs out undefined. Why? How to solve it?

5 Answers 5

4

try this :

var Obj = {
init: function () {
    this.over = $('<div />').addClass('over');
    $('body').append(this.over);
    $('.click').on('click', this.show);
},

show: function () {
    // here the 'this' is the button , not the obj object ..
    console.log($('.over'));
}
}

Obj.init();

another option :

var Obj = {
init: function () {
    this.over = $('<div />').addClass('over');
    $('body').append(this.over);
    var that = this;
    $('.click').on('click', function(e){
       that.show.call(that, e); // calling the show function with call, causing 'this' to be obj
    });
},

 // 'this' is the obj
show: function (e) {
    console.log(this.over);
}
}

Obj.init();
Sign up to request clarification or add additional context in comments.

3 Comments

hope it helps , and solves your problem , if you need help understand something , let me know.
Thank you for you help. One more thing can you look at this jsfiddle.net/SQGsZ/1 . Why me is not logged out?
Obj.me; => Obj.me(); // in line 9 !
2

The problem here is the scope of that this (Obj).

Use the following code to solve your problem.

var Obj = {
init: function () {
    this.over = $('<div />').addClass('over');
    $('body').append(this.over);
    $('.click').on('click', $.proxy(this.show, this));
},

show: function () {
    console.log(this.over);
}
};

Obj.init();

learn more about jQuery.proxy

Comments

1

Because jQuery injects the DOM element that was clicked on into 'this' as opposed to the 'Obj' object. One solution is closure:

var Obj = {
  init: function () {
    this.over = $('<div />').addClass('over');
    $('body').append(this.over);
    $('.click').on('click', this.show());
  },

  show: function () {
    var self = this;
    return function () {
        console.log("over:", self.over);
    }
  }
}
Obj.init();

Comments

0

You pass the function stored in this.show to on. When it gets called, it is not called in the context of Obj so this is not Obj.

You need to create a new function which isn't dependent on being called in the context of Obj.

The easiest way to do this is with bind:

$('.click').on('click', this.show.bind(this));

But this has limited browser support.

You can also use a closure:

var myObj = this;
var show = function () {
    myObj.show()
}
$('.click').on('click', show);

Comments

0

When binding a function to an event with jquery, the context in which this function is called is the dom object that has been clicked.

var Obj = {
init: function () {
    this.over = $('<div />').addClass('over');
    $('body').append(this.over);
    var that = this;
    $('.click').on('click', function(){ 
        // console.log( this ) will log the dom object
        that.show.call( that ) 
     } );
},

show: function () {
    console.log(this.over);
}
}

Obj.init();

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.