0

I've got a child Javascript object

var child = {
    foo: function() {
        console.log('bar');
    }
};

and a parent object

var parent = {
    baz: function() {
        this.foo();
    }
};

merged with jQuery

$.extend(child, parent);

I guess why this works

child.baz();
// prints 'bar'

and this does not

$('#btn').click(child.baz);
// Uncaught TypeError: this.foo is not a function

Thank you

Marco
  • 759
  • 3
  • 9
  • 22
  • `this` is `DOM` element within event handler – guest271314 Jun 09 '17 at 15:51
  • Possible duplicate of [How to access the correct `this` context inside a callback?](https://stackoverflow.com/q/20279484/218196). – Felix Kling Jun 09 '17 at 15:53
  • JS gets really screwy with it's `this` scope. This helped me to understand it if you wish to have a deeper understanding https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch2.md – dgeare Jun 09 '17 at 15:57

2 Answers2

2

this is DOM element within event handler. You can use $.proxy() to set this to an object within function call

var child = {
    foo: function() {
        console.log('bar');
    }
};

var parent = {
    baz: function() {
        this.foo();
    }
};

$.extend(child, parent);

$("#btn").click($.proxy(child.baz, child));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<div id="btn">click</div>
guest271314
  • 1
  • 15
  • 104
  • 177
2

You need to modify the code like this:

$('#btn').click(child.baz.bind(child));

The reason your code didn't work was that when click handler is called, this is set to button whereas you want this to be set to child. In javascript this is bound dynamically and is determined by who calls the function. So in first case child.baz();, implicit binding rule applies and this is set to child. Using bind will hard bind this to child in the button click callback case.

var child = {
  foo: function() {
    console.log('bar');
  }
};

var parent = {
  baz: function() {
    this.foo();
  }
};

$.extend(child, parent);

child.baz();
$('#btn').click(child.baz.bind(child));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">Click</button>
Pankaj Shukla
  • 2,657
  • 2
  • 11
  • 18