user5638730 user5638730 - 5 months ago 10
AngularJS Question

Get the right this-context in function

I have the following problem:

I try to overwrite a function to apply it then with angular (

$scope.$apply()
), but my
this
-context doesn't seem to be the right one.

The original function (in another file) looks like the following:

Anno.prototype.switchTo = function(otherAnno) {
if (otherAnno != null) {
this.hideAnno();
return otherAnno.show();
} else {
console.warn("Can't switchTo a null object. Hiding instead.");
return this.hide();
}
};


And then in another file I "overwrite" it like the following:

var switchToFunction = AnnoModule.Anno.prototype.switchTo;
AnnoModule.Anno.prototype.switchTo = function(otherAnno) {
switchToFunction(otherAnno);
$scope.$apply();
};


So actually I save the original function, then redefine the original function to call the original one and then apply the scope.

Now comes the problem: As you can see, the function uses
this.hideAnno()
in it, but in my redefined function, the context is another one, that's why chrome is throwing an error saying "this.hideAnno() is not a function". But now I'm not sure how I can get the right context. I tried to understand this, but that JavaScript is so confusing that I really don't get it.

Can somebody help me understand that JavaScript confusion?

Answer

When a function is defined as a method in js, the this inside of it refers to the object the method belongs to.

On the other hand, when a function is defined on its own, this inside of it refers to the global object or undefined in strict mode.

You are extracting a function defined as a method into a standalone function, that's why this doesn't do what you expect it to.

What you need in this case is to call or apply your switchToFunction, setting the value of this to what you need. In other words you set the this of the old method to be the this of the new method you created:

var switchToFunction = AnnoModule.Anno.prototype.switchTo;
AnnoModule.Anno.prototype.switchTo = function(otherAnno, that) {
    switchToFunction.call(this, otherAnno); // sets `this` of the old method to be this of the new method you created
    $scope.$apply();
};