development

Chrome의 '미 발견 TypeError : 잘못된 호출'

big-blog 2020. 7. 4. 09:27
반응형

Chrome의 '미 발견 TypeError : 잘못된 호출'


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의지를 직접 부르면 ...

잡히지 않은 TypeError : 잘못된 호출

Chrome에서. 왜?


코드에서 사용자 정의 객체의 속성에 기본 메소드를 할당합니다. 를 호출하면 support.animationFrame(function () {})현재 객체의 컨텍스트 (즉, 지원)에서 실행됩니다. 기본 requestAnimationFrame 함수가 제대로 작동하려면의 컨텍스트에서 실행되어야합니다 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 

또 다른 옵션은 ES5 표준의 일부이며 모든 최신 브라우저에서 사용할 수있는 Function.prototype.bind () 를 사용 하는 것입니다.

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

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

다음을 사용할 수도 있습니다.

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

메소드 (예 : 객체에 할당 된 함수)를 실행할 때 내부에서 this변수를 사용 하여이 객체를 참조 할 수 있습니다 .

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

한 객체에서 다른 객체로 메소드를 할당하면 해당 this변수는 새 객체를 참조합니다. 예를 들면 다음과 같습니다.

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

var anotherObj = {
  someProperty: false,
  someMethod: obj.someMethod
};

anotherObj.someMethod(); // logs false

requestAnimationFrame방법 window을 다른 객체에 할당 할 때도 마찬가지 입니다. 이와 같은 기본 기능은 다른 컨텍스트에서 실행되지 않도록 기본 제공 보호 기능을 갖추고 있습니다.

Function.prototype.call()다른 상황에서 함수를 호출 할 수 있도록 기능. 이 메소드의 첫 번째 매개 변수로 컨텍스트 (컨텍스트로 사용될 오브젝트)를 전달하면됩니다. 예를 들어 alert.call({})제공합니다 TypeError: Illegal invocation. 그러나 alert.call(window)이제는 alert원래 범위에서 실행 되기 때문에 제대로 작동합니다 .

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() {});.

참고URL : https://stackoverflow.com/questions/9677985/uncaught-typeerror-illegal-invocation-in-chrome

반응형