When you execute a method (i.e. function assigned to an object), inside it you can use this
variable to refer to this object, for example:
var obj = {
someProperty: true,
someMethod: function() {
console.log(this.someProperty);
}
};
obj.someMethod(); // logs true
If you assign a method from one object to another, its this
variable refers to the new object, for example:
var obj = {
someProperty: true,
someMethod: function() {
console.log(this.someProperty);
}
};
var anotherObj = {
someProperty: false,
someMethod: obj.someMethod
};
anotherObj.someMethod(); // logs false
The same thing happens when you assign requestAnimationFrame
method of window
to another object. Native functions, such as this, has build-in protection from executing it in other context.
There is a Function.prototype.call()
function, which allows you to call a function in another context. You just have to pass it (the object which will be used as context) as a first parameter to this method. For example alert.call({})
gives TypeError: Illegal invocation
. However, alert.call(window)
works fine, because now alert
is executed in its original scope.
If you use .call()
with your object like that:
support.animationFrame.call(window, function() {});
it works fine, because requestAnimationFrame
is executed in scope of window
instead of your object.
However, using .call()
every time you want to call this method, isn’t very elegant solution. Instead, you can use Function.prototype.bind()
. It has similar effect to .call()
, but instead of calling the function, it creates a new function which will always be called in specified context. For example:
window.someProperty = true;
var obj = {
someProperty: false,
someMethod: function() {
console.log(this.someProperty);
}
};
var someMethodInWindowContext = obj.someMethod.bind(window);
someMethodInWindowContext(); // logs true
The only downside of Function.prototype.bind()
is that it’s a part of ECMAScript 5, which is not supported in IE <= 8. Fortunately, there is a polyfill on MDN.
As you probably already figured out, you can use .bind()
to always execute requestAnimationFrame
in context of window
. Your code could look like this:
var support = {
animationFrame: (window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame).bind(window)
};
Then you can simply use support.animationFrame(function() {});
.
When you execute a method (i.e. function assigned to an object), inside it you can use this
variable to refer to this object, for example:
var obj = {
someProperty: true,
someMethod: function() {
console.log(this.someProperty);
}
};
obj.someMethod(); // logs true
If you assign a method from one object to another, its this
variable refers to the new object, for example:
var obj = {
someProperty: true,
someMethod: function() {
console.log(this.someProperty);
}
};
var anotherObj = {
someProperty: false,
someMethod: obj.someMethod
};
anotherObj.someMethod(); // logs false
The same thing happens when you assign requestAnimationFrame
method of window
to another object. Native functions, such as this, has build-in protection from executing it in other context.
There is a Function.prototype.call()
function, which allows you to call a function in another context. You just have to pass it (the object which will be used as context) as a first parameter to this method. For example alert.call({})
gives TypeError: Illegal invocation
. However, alert.call(window)
works fine, because now alert
is executed in its original scope.
If you use .call()
with your object like that:
support.animationFrame.call(window, function() {});
it works fine, because requestAnimationFrame
is executed in scope of window
instead of your object.
However, using .call()
every time you want to call this method, isn’t very elegant solution. Instead, you can use Function.prototype.bind()
. It has similar effect to .call()
, but instead of calling the function, it creates a new function which will always be called in specified context. For example:
window.someProperty = true;
var obj = {
someProperty: false,
someMethod: function() {
console.log(this.someProperty);
}
};
var someMethodInWindowContext = obj.someMethod.bind(window);
someMethodInWindowContext(); // logs true
The only downside of Function.prototype.bind()
is that it’s a part of ECMAScript 5, which is not supported in IE <= 8. Fortunately, there is a polyfill on MDN.
As you probably already figured out, you can use .bind()
to always execute requestAnimationFrame
in context of window
. Your code could look like this:
var support = {
animationFrame: (window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame).bind(window)
};
Then you can simply use support.animationFrame(function() {});
.
In this article, we will walk you through how to fix the “uncaught typeerror: illegal invocation” error message in detail.
Keep reading as we are going to discuss what this error means and what causes it.
So that you’ll understand this error thoroughly and it will be easier for you to troubleshoot this “typeerror: illegal invocation” error message.
The “uncaught typeerror illegal invocation” is an error message in JavaScript that occurs when you try to call a function in a way that is not allowed by the language.
In addition to that, this error message usually appears in the console of the browser, making it easier to identify and fix.
Indicating that there is an issue with your JavaScript code.
Why does this error occurs?
This error can occur for various reasons, such as:
→ “this” is not set correctly.
→ Calling a function with the wrong number or type of arguments.
→ Calling a function without the correct context object.
→ Calling non-method functions as if they were methods.
How to fix “uncaught typeerror: illegal invocation”?
The following are the different solutions you use to troubleshoot the “typeerror: illegal invocation” error message.
Solution 1: Check the context of “this”
You have to check the context of “this” and ensure it is set to the correct value.
The bind() method is used to set the value of “this” to the obj object.
function myFunction() {
console.log(this);
}
var obj = { website: "Itsourcecode" };
var boundFunction = myFunction.bind(obj);
boundFunction();
The bind() method allows us to explicitly set the context or “this” object for a function.
Output:
{ website: 'Itsourcecode' }
Solution 2: Use “call” or “apply” correctly
You have to ensure you’re passing the correct arguments to these methods.
The call () method is used to set the value of “this” to the obj object, and two arguments are passed to the myFunction function.
function myFunction(arg1, arg2) {
console.log(this);
console.log(arg1);
console.log(arg2);
}
var obj = { website: "Itsourcecode" };
myFunction.call(obj, "welcome", "to a website that offers free tutorials");
The call() and apply() methods also allow us to explicitly set the context or “this” object for a function.
Output:
{ website: 'Itsourcecode' }
welcome
to a website that offers free tutorials
Solution 3: Use dot notation to call methods
You can also use the dot notation to call methods.
The call() method is used to set the value of “this” to the obj object, and the sayHello method is called using dot notation.
var obj = {
website: "Itsourcecode",
sayHello: function() {
console.log("Hello, " + this.website);
}
};
var sayHelloFunc = obj.sayHello;
sayHelloFunc.call(obj);
Output:
Hello, Itsourcecode
Solution 4: Using Arrow Functions
The arrow functions provide a more concise syntax for writing functions in JavaScript.
Apart from that it also have a lexical this keyword, which means that the this keyword inside an arrow function always refers to its surrounding context.
const person = {
name: "Caren",
age: 20,
sayHello: function() {
const self = this;
const hello = () => {
console.log(`Hello, my name is ${self.name} and I'm ${self.age} years old`);
};
hello();
}
};
person.sayHello();
We have an object called person with a sayHello() method that uses a regular function.
Inside the sayHello() method, we create a variable called self that refers to the person object.
Then, define an arrow function called hello().
Ouput:
Hello, my name is Caren and I'm 20 years old
How to avoid the “uncaught typeerror: illegal invocation” error message
To avoid this error, it’s important to ensure that you’re calling your functions with the correct context object and the correct number of arguments.
Using bind, call, or apply to explicitly set the this keyword as needed.
Aside from that, it’s also important to ensure that you’re using the “this” keyword properly within your functions.
Additionally, be careful when passing functions as arguments, as they may lose their context and throw an error.
Frequently Asked Questions (FAQs)
What is the this keyword in JavaScript?
The this keyword in JavaScript, refers to the context in which a function is called. When a function is called as a method of an object, this refers to that object.
What is the difference between call() and apply() in JavaScript?
Call() and apply() are both methods that can be used to invoke a function with a specified context.
The main distinction between the two is in how arguments are passed to the function: call() accepts a comma-separated list of arguments, while apply() accepts an array of arguments.
Conclusion
By executing the different solutions that this article has already given, you can definitely resolve the “uncaught typeerror: illegal invocation” error message in JavaScript.
We are hoping that this article provides you with sufficient solutions.
You could also check out other “typeerror” articles that may help you in the future if you encounter them.
- Typeerror slice none none none 0 is an invalid key
- Typeerror: cannot read property ‘getrange’ of null
- Typeerror fsevents is not a constructor
Thank you very much for reading to the end of this article.
Доброе время суток!
По какой то причине при каждом обращении на Scope.apply в консоли идет ошибка
TypeError: Illegal invocation
at equals (angular.js:1041)
at equals (angular.js:1041)
at Scope.$digest (angular.js:15747)
at angular.js:15955
at completeOutstandingRequest (angular.js:5490)
at angular.js:5762(anonymous function) @ angular.js:12416(anonymous function) @ angular.js:9203Scope.$digest @ angular.js:15771(anonymous function) @ angular.js:15955completeOutstandingRequest @ angular.js:5490(anonymous function) @ angular.js:5762
2angular.js:12416 TypeError: Illegal invocation
at equals (angular.js:1041)
at equals (angular.js:1041)
at Scope.$digest (angular.js:15747)
at Scope.$apply (angular.js:16024)
at angular.js:17791
at completeOutstandingRequest (angular.js:5490)
at angular.js:5762(anonymous function) @ angular.js:12416(anonymous function) @ angular.js:9203Scope.$digest @ angular.js:15771Scope.$apply @ angular.js:16024(anonymous function) @ angular.js:17791completeOutstandingRequest @ angular.js:5490(anonymous function) @ angular.js:5762
Без понятия из за чего это.
Пожалуйста помогите решить проблему
-
Вопрос заданболее трёх лет назад
-
6872 просмотра
Эта ошибка возникает когда идёт вызов ф-ии без указания правильного this, например ф-ия из scope без самого scope, log без console, alert без window и т.п.
Какая версия ангуляра?
Пригласить эксперта
Помог костыль в виде конфига
app.config(function($provide){
$provide.decorator("$exceptionHandler", function($delegate, $injector){
return function(exception, cause){
};
});
})
отключил все ошибки из Angularjs
Багфиксы пока не выпущены, ожидаются в issues в github
У вас какой-то вотч криво написан, это не ангуляра проблема.
-
Показать ещё
Загружается…
07 июн. 2023, в 10:19
20000 руб./за проект
07 июн. 2023, в 10:12
1000 руб./за проект
07 июн. 2023, в 10:07
500 руб./за проект
Минуточку внимания
Comments
jdthorpe
changed the title
Illegal Invocation error in web-worker
Illegal Invocation error when used in a web-worker
Feb 8, 2017
domenic
added a commit
that referenced
this issue
Mar 12, 2017
Closes #1732. This worked fine in Node since there clearTimeout does not care what its thisArg is. But in browsers, it does, causing this error.
domenic
added a commit
that referenced
this issue
Mar 12, 2017
Closes #1732. This worked fine in Node since there clearTimeout does not care what its thisArg is. But in browsers, it does, causing the error described there.