This question already has answers here:
How does "this" keyword work within a function?
(7 answers)
Closed 8 years ago.
I have a JS object that in pseudo code is doing this:
function myObj {
// in constructor
... initialise vars
... call $.Ajax to fetch view from server
function AjaxCallBack() {
// load the DOM with the HTML result
$('#dialog').html(ajax.result);
// try to register a change handler
$("#dialog :input").change(this.formChangeEvent);
}
this.formChangeEvent = function(){
... do stuff
}
}
The problem is that in the AjaxCallBack, 'this' is not myObj object, but rather the 'window' object and can't resolve the function
The only way I've been able to get around this problem is to have the receiver of the object call back into a separate function of myObj and register the event
objInstance = new myObj();
objInstance.registerEventHandler();
I've tried a few other things, but I'm obviously missing something basic.
If I understand your question then you can hold this to any variable like var thisObj=$(this) . Now you can use thisObj.formChangeEvent. Hope this will help.
Try this:
function myObj {
// in constructor
... initialise vars
... call $.Ajax to fetch view from server
var oThis = this; // oThis is object this which points to myObj
function AjaxCallBack() {
// load the DOM with the HTML result
$('#dialog').html(ajax.result);
// try to register a change handler
$("#dialog :input").change(oThis.formChangeEvent);
}
this.formChangeEvent = function(){
... do stuff
}
}
It will do the trick.
Related
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 6 years ago.
I am new to node.js and I am trying to require a class. I have used https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes as reference. However, when I do this for example:
// talker.js
class Talker {
talk(msg) {
console.log(this.say(msg))
var t = setTimeout(this.talk, 5000, 'hello again');
}
say(msg) {
return msg
}
}
export default Talker
// app.js
import Talker from './taker.js'
const talker = new Talker()
talker.talk('hello')
I get:
talker.js:4 Uncaught TypeError: this.say is not a function
It should be said that app.js is the electron.js renderer process and it bundled using rollup.js
Any ideas why this would be?
Update: Sorry, I forgot to add in a line when putting in the psuedo code. It actually happens when I call setTimeout with callback. I have updated the code.
You are losing the bind of this to your method.
Change from this:
setTimeout(this.talk, 5000, 'hello again');
to this:
setTimeout(this.talk.bind(this), 5000, 'hello again');
When you pass this.talk as a function argument, it takes this and looks up the method talk and passes a reference to that function. But, it only passes a reference to that function. There is no longer any association with the object you had in this. .bind() allows you to pass a reference to a tiny stub function that will keep track of this and call your method as this.say(), not just as say().
You can see the same thing if you just did this:
const talker = new Talker();'
const fn = talker.say;
fn();
This would generate the same issue because assigning the method to fn takes no associate to talker with it at all. It's just a function reference without any association with an object. In fact:
talker.say === Talker.prototype.say
What .bind() does is create a small stub function that will save the object value and will then call your method using that object.
Is this possible? I'm trying to overwrite a javascript method after my page has been loaded. The code in question looks similar to this:
myObject = Backbone.ViewManager.BaseView.extend({
myMethod: function() {
alert("in old method definition");
},
initialize: function() {
var a = this;
Our.Events.on("alertEvent", function(){
a.myMethod();
}
}
);
(The Backbone.ViewManager bit is just a way to create an object in javascript using a framework and not important here.)
Note the event callback defined above in the initialize method. We initialize the objects as soon as they're created.
After my page has loaded I tried to redefine myMethod to alert a different message. But when the alertEvent fires the original message appears in the alert.
I assume this is because of a closure, that redefining the method on myObject after its been initialized won't affect the definition pointed to by a? If that's the case, is there something I can do to change the definition used by a, or am I out of luck?
You should be able to define myMethod on the object you create which will override the prototype myMethod. What you have written should be able to work because you arn't referencing myMethod directly, but through the a object.
The following works for me
function ObjCstr(){}
ObjCstr.prototype.myMethod = function(){ alert("Old Message"); };
ObjCstr.prototype.callMyMethod = function(){
var a = this;
return function(){ a.myMethod(); };
};
var test = new ObjCstr();
var fakeListener = test.callMyMethod();
fakeListener(); // "OldMessage"
test.myMethod = function(){ alert("Overridden!"); };
fakeListener(); // "Overridden!"
This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 7 years ago.
I've recently gone into developing with AngularJS. It's confusing to me the different between these two:
$scope.myScope = function () {
var x = 'do something with variable here';
$scope.anotherScope = x;
};
and
function myFunction () {
var x = 'do something with variable here';
$scope.anotherScope = x;
}
They both seem to be able to do the same thing (I use them a lot inside controllers). Is there a best practice for when and where to use these two?
$scope.myScope = function () {};
This means your function is a property of the scope object. So you can use it in your controller , html page even in your app. it can be referenced in different modules in the same app. so you just call it in your html page using the function name directly either onclick or onchange , anyhow depending on your need.
the other definition can only be used in your controller and is not the scope of your app. however if you define your function using "this.myScope = function(){};" then you can call the function in your html by using your controller. like ng-click = "controllerName.myScope();"
the main difference is i nwhich scope the function belongs to and where all you can reference the function.
hope it helps !!!!
As mourycy already mentioned, you should use the form
$scope.myScopeFunction = function () {
...
};
only for functions which you want to call via the scope object. This is needed for function calls within your views.
For example:
<button ng-click="myScopeFunction()" />
which calls the function myScopeFunction of the current $scope object.
If you don't need to be able to call a controller method from "outside" you should use the following form:
function myFunction() {
...
};
$scope.myScop = function(){
...
};
is a function you can execute from the HTML controller.
function foo(){
...
}
is a function you can only execute on the controller's JS file.
This question already has answers here:
Can I override the Javascript Function object to log all function calls?
(6 answers)
Closed 5 years ago.
For debugging purposes, I was wondering if there's some way in which I can create a piece of code to run whenever a javascript function is called - like adding something to Function.prototype or Function.constructor etc.
You could use a "decorator-like".
Something as simple as executing
var yourFunction = function { // do stuff };
var yourSecondFunction = function { // do stuff };
var myDecorator = function( callback )
{
// do your stuff
// ...
// then execute function
callback();
};
// usage
myDecorator( yourFunction );
myDecorator( yourSecondFunction );
I don't think overwriting the prototype of Function is a good idea.
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 8 years ago.
I want to make a select option for animations, so whatever type is selected, it's shown on the canvas.
So i make each animation as a "class" :
(function (exports) {
function animationA() {}
animationA.prototype.init = function(){}
animationA.prototype.draw = function(){}
exports.animationA = animationA;
})(this);
Then in the main js:
var a = new animationA();
function setup() {
a.init();
}
function update(callback) {
requestAnimationFrame(function () {
update(callback);
});
console.log(this);
callback();
}
setup();
update(a.draw);
I found error occurs in the update(a.draw). It cannot access the properties of a in this line of code.
I wonder if this is a javascript scope problem?
Thanks.
You need to create a reference to the context you want to refer to inside the callback before you call requestAnimationFrame, just like you would with a normal event callback.
Var that = this;
requestAnimationFrame(function(){
that.doSimething();
});