I have an object. It initializes a button to alert "Hello!" when it is clicked. Why won't this work?
jsfiddle: /
HTML
<button>Test</button>
JS
var MyObject = {
testValue: "Hello!",
testFunction: function() {
alert(this.testValue);
},
init: function(button) {
button.click(this.testFunction());
}
}
$(document).ready(function(){
var buttonInstance = new MyObject();
var button = $('button');
buttonInstance.init(button);
});
I have an object. It initializes a button to alert "Hello!" when it is clicked. Why won't this work?
jsfiddle: http://jsfiddle/kUT52/1/
HTML
<button>Test</button>
JS
var MyObject = {
testValue: "Hello!",
testFunction: function() {
alert(this.testValue);
},
init: function(button) {
button.click(this.testFunction());
}
}
$(document).ready(function(){
var buttonInstance = new MyObject();
var button = $('button');
buttonInstance.init(button);
});
Share
Improve this question
edited Jul 25, 2020 at 11:39
Brian Tompsett - 汤莱恩
5,89372 gold badges61 silver badges133 bronze badges
asked Jun 28, 2013 at 20:16
Don PDon P
63.7k121 gold badges318 silver badges447 bronze badges
2
-
3
Your code makes no sense! You can't initialize a new object literal like that. If you want to use
new
and treat it like a "constructor", you have to makeMyObject
a function. Otherwise,MyObject
is an object literal and you can access it statically -MyObject.testValue
– Ian Commented Jun 28, 2013 at 20:24 - Mind blown @Ian. That makes js objects make so much more sense, thank you. – Don P Commented Jun 28, 2013 at 20:37
3 Answers
Reset to default 12Whenever you put ()
behind a function reference, you are executing the function. You have to pass the function reference to .click
, not what the function returns (unless the function returns a function that you want to use as event handler).
Example:
button.click(this.testFunction);
But now you have another problem: Inside the function, this
will refer to the DOM element and not to the object, so accessing this.testValue
will return undefined
.
You can use jQuery's $.proxy
function to fix this:
button.click($.proxy(this.testFunction, this));
Now this
will refer to the object, and you can get a reference to the clicked element via event.target
.
For two reasons:
You are using
testFunction()
instead oftestFunction
when you bind the event, so you will be calling the function and binding the (undefined) return value.When you use a method as a function, it's no longer attached to the object, so the context will not be the object when the callback is called, but the global
window
object.
Use the proxy
method to make a function that calls the method with the right context:
button.click($.proxy(this.testFunction, this));
That's an object literal, and you'd normally use it like so :
var MyObject = {
testValue: "Hello!",
testFunction: function() {
alert(MyObject.testValue);
},
init: function(button) {
button.on('click', this.testFunction);
}
}
var button = $('button');
MyObject.init(button);
FIDDLE
or passing the object:
var MyObject = {
testValue: "Hello!",
testFunction: function(e) {
alert(e.data.obj.testValue);
},
init: function(button) {
button.on('click', {obj: this}, this.testFunction);
}
}
var button = $('button');
MyObject.init(button);
FIDDLE