Msgstr "Невозможно ввести TypeError: Незаконный вызов" в Chrome.

Когда я использую requestAnimationFrame для создания некоторой родной поддерживаемой анимации с нижеследующим кодом:

var support = {
    animationFrame: window.requestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        window.oRequestAnimationFrame
};

support.animationFrame(function() {}); //error

support.animationFrame.call(window, function() {}); //right

Прямо вызов support.animationFrame даст...

Uncaught TypeError: незаконный вызов

в Chrome. Почему?

Ответ 1

В коде вы назначаете собственный метод для свойства настраиваемого объекта. Когда вы вызываете support.animationFrame(function () {}), он выполняется в контексте текущего объекта (т.е. поддержки). Для правильной работы функции nativeAnimationFrame она должна выполняться в контексте window.

Итак, правильное использование здесь support.animationFrame.call(window, function() {});.

То же самое происходит и с предупреждением:

var myObj = {
  myAlert : alert //copying native alert to an object
};

myObj.myAlert('this is an alert'); //is illegal
myObj.myAlert.call(window, 'this is an alert'); // executing in context of window 

Другой вариант - использовать Function.prototype.bind(), который является частью стандарта ES5 и доступен во всех современных браузерах.

var _raf = window.requestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        window.oRequestAnimationFrame;

var support = {
   animationFrame: _raf ? _raf.bind(window) : null
};

Ответ 2

Вы также можете использовать:

var obj = {
    alert: alert.bind(window)
};
obj.alert('I´m an alert!!');

Ответ 3

Когда вы выполняете метод (т.е. функцию, назначенную объекту), внутри него вы можете использовать переменную this для ссылки на этот объект, например:

var obj = {
  someProperty: true,
  someMethod: function() {
    console.log(this.someProperty);
  }
};
obj.someMethod(); // logs true