This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 8 years ago.
I have a problem with javascript namespaces.
I want to call secondMethod from ajax callback function but I don't know how to get reference to it.
I have done it like that yet. But variable thisReference seems to me awkward. And whole construction is difficult to read.
So I'm writing there for help and answer how to rewrite it better.
var testObject = new TestObject();
testObject.firstMethod("hello world!");
function TestObject() {
var thisReference = this;
this.firstMethod = function(firstParam) {
ajaxFunc(firstParam, function(ajaxResult) {
thisReference.secondMethod(ajaxResult);
});
};
this.secondMethod = function(secondParam) {
alert("secondMethod " + secondParam);
};
}
function ajaxFunc(hello, callBack) {
callBack(hello);
}
Thanks a lot.
Ondra
Something like what you're doing is a common way to do it. Using:
var that = this;
or:
var self = this;
are common names to keep a hold of your original scope.
Another option (which I prefer) is to bind the this object to the method you're calling so that you have access to it in the callback. That would look like this:
this.firstMethod = function(firstParam) {
ajaxFunc(firstParam, function(ajaxResult) {
this.secondMethod(ajaxResult);
}.bind(this));
};
Hope that helps.
Related
This question already has answers here:
Referencing "this" inside setInterval/setTimeout within object prototype methods [duplicate]
(2 answers)
How to return value from an asynchronous callback function? [duplicate]
(3 answers)
Closed 5 years ago.
This question is from an written test for a company. It looks very confusing. I thought it will print whatever this.name is set to. Bu when I typed the code it shows nothing. I have little knowledge about closures and I think it is related to the problem. I want a little explanation here.
function dd(name) {
this.name = name;
this.go = function() {
setInterval(function() {
return this.name;
}, 2000)
}
}
var tt = new dd("corolla");
tt.go()
You can't get the return value from setInterval in this way. Try with a callback as in the following snippet
function dd(name)
{
this.name=name;
console.log( name );
var _this = this;
this.go=function(cb)
{
setInterval(function() {
cb(_this.name);
},1000)
}
}
var tt=new dd("corolla");
tt.go(function(ret) {
console.log( ret );
})
Also, please note that inside setInteval the value of this is not the same as in the otter function. That's why var _this=this;
This question already has answers here:
javascript "this" keyword not referring to correct thing
(3 answers)
Closed 7 years ago.
The Problem
In my "private" object for the facade pattern, I am defining methods and properties. When calling a method in this "private" object, I am getting Uncaught Typerror's saying that the method I am calling is not a function.
The Code
var lazySize = (function() {
var _ = {
images: [],
lazySizes: {},
resizeTimeout: null,
pageWidth: document.getElementsByClassName('crop_image')[0].offsetWidth,
resizeHandler: function() {
var i = 0;
for (var image in this.lazySizes) {
if (this.pageWidth < image) {
this.images[i++].src = this.lazySizes[image];
}
}
},
resizeThrottler: function() {
if (!this.resizeTimeout) {
this.resizeTimeout = setTimeout(function() {
this.resizeTimeout = null;
this.resizeHandler();
}, 66);
}
}
};
return {
init: function() {
window.addEventListener('resize', _.resizeThrottler, false);
}
};
}());
lazySize.init();
The Error
Uncaught TypeError: this.resizeHandler is not a function
The Question
Why am I unable to access the resizehandler method while inside resizeThrottler?
My understanding when using var rather than let, is that JavaScript is function scoped, so I am rather puzzled as to why I can't access it.
I am trying to improve my JavaScript, so if I am doing something really bad here, I would be very grateful if someone could point it out.
This is because this does not correspond to what you think it does.
You pass the resizeThrottler method as a reference for the browser to call, but when it does call it, the context is no longer your object, but window, which evidently does not have the same properties.
You could solve this as follows:
window.addEventListener('resize', _.resizeThrottler.bind(_), false);
This way you set the context of the method passed as handler to always run with _ as this.
This question already has answers here:
Constructors in JavaScript objects
(19 answers)
Closed 7 years ago.
I have JavaScript function as object:
function hexMesh(){
var side=25;
console.log('hexMesh');
function drawOver(){
}
}
As you can see it has a function call drawOver.
I try to call it by using a constructor as follows:
window.onload = function() {
hexMeshObj=new hexMesh();
hexMeshObj.drawOver();
}
But it gives me error saying undefined is not a function
Now I know I could declare the function in the prototype of the object but I don't want to do that.
Here it is on JSFiddle.
You can't use JavaScript like that!
Solution: Use Class-like prototypes (please don't treat them as classes, although they provide inheritance)
var x = function(v){ this.test = v; } // This is your constructor
x.prototype.show = function(){ console.log("TEST", this.test); } // This is a prototype with this as a context
var y = new x(true);
y.show(); // Logs TEST true
Edit:
Alternatively (although the prototype way is better as it provides real inheritance the oop way)
var x = function(v){
var context = this;
this.test = v;
this.show = function(){
console.log('test', context.test)
});
Another alternative way is to use bind to bind context if you need it.
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 8 years ago.
When test.testHello(helloWorld.sayHello); runs, it doesn't recognize that I have inserted a new greeting is the greeting is undefined. I can use bind to make sure it runs it in the proper scope, I am not really sure why isn't it running in the proper scope to begin with. Could someone explain why this is happening and show me a better solution?
Solution: test.testHello(helloWorld.sayHello.bind(helloWorld));
http://jsfiddle.net/EzabX/
var HelloWorldClass = function() {
this.greetings = [];
}
HelloWorldClass.prototype.addGreeting = function(greeting) {
this.greetings.push(greeting);
}
HelloWorldClass.prototype.sayHello = function() {
document.getElementById('output').innerHTML += this.greetings;
this.greetings.forEach(function(greeting) {
greeting.execute();
})
}
var TestClass = function() {
this.testHello = function(callback) {
alert("TestHello is working, now callback");
callback();
}
}
var main = function() {
var helloWorld = new HelloWorldClass();
var test = new TestClass();
helloWorld.addGreeting({
execute: function() {
alert("Konichiwa!");
}
});
helloWorld.sayHello();
test.testHello(helloWorld.sayHello);
}
main();
Managing the this variable within the prototype function scope when called as a callback can be complicated for novice users. You don't always need a prototype for all functions on a class. If you really want to use a prototype function look at Javascript .bind(this) implementations. Google and Stackoverflow are your friend on that topic. Example: Preserving a reference to "this" in JavaScript prototype functions
Offending code with this referring to DOM Window object and not a HelloWorld instance:
this.greetings.forEach(function(greeting) {
greeting.execute();
})
A non-prototype version that works just great, easy to use. Fiddle: http://jsfiddle.net/EzabX/2/
var HelloWorldClass = function() {
var greetings = [];
this.greetings = greetings;
this.addGreeting = function(greeting) {
greetings.push(greeting);
};
this.sayHello = function() {
document.getElementById('output').innerHTML += greetings;
greetings.forEach(function(greeting) {
greeting.execute();
})
}; }
This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 9 years ago.
I see named functions exampled this way:
var clearClick = function() {
// do something
}
...and then used for binding like so:
$("#clear").bind(click, clearClick);
...or with the "shorthand" methodology thus:
$("#clear").click(clearClick);
But why not use a more "normal" (similar to other programming languages) construct like this:
function clearClick() {
// do something
}
It works the same, doesn't it? Is there any disadvantage to defining functions in this traditional way? Is the previous way just jQuerians flaunting their newfangledness?
This works Function expression
var clearClick = function() {
// do something
}
$("#clear").bind(click, clearClick);
This does not work Function expression. The order matters here.
$("#clear").bind(click, clearClick);
var clearClick = function() {
// do something
}
But when you declare your function using a function declaration the order does not matter.
One more advantage of the below syntax is that the function name appears in debugger.
function clearClick() {
// do something
}
One reason you might want to do it is how this works:
var clearClick;
$("#clear").click(clearClick);
clearClick = function() {
// do something
}
... lots of stuff in here ...
clearClick = function() {
// do something different
}