Kiedy używam requestAnimationFrame
do tworzenia natywnych obsługiwanych animacji z poniższym kodem:
var support = {
animationFrame: window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame
};
support.animationFrame(function() {}); //error
support.animationFrame.call(window, function() {}); //right
Bezpośrednio dzwoniąc do support.animationFrame
testamentu ...
Uncaught TypeError: Niedozwolone wywołanie
w przeglądarce Chrome. Czemu?
źródło
myObj.myAlert('this is an alert');
jest nielegalne. Prawidłowe użycie jestmyObj.myAlert.call(window, 'this is an alert')
. Przeczytaj odpowiedzi poprawnie i spróbuj je zrozumieć.Możesz także użyć:
źródło
var realReplaceState = history.replaceState.bind(history);
.bind(localStorage)
, nie.bind(window)
.Kiedy wykonujesz metodę (tj. Funkcję przypisaną do obiektu), wewnątrz niej możesz użyć
this
zmiennej, aby odwołać się do tego obiektu, na przykład:Jeśli przypiszesz metodę z jednego obiektu do innego, jej
this
zmienna odwołuje się do nowego obiektu, na przykład:To samo dzieje się, gdy przypiszesz
requestAnimationFrame
metodęwindow
do innego obiektu. Funkcje natywne, takie jak ta, mają wbudowaną ochronę przed wykonywaniem ich w innym kontekście.Istnieje
Function.prototype.call()
funkcja, która umożliwia wywołanie funkcji w innym kontekście. Musisz tylko przekazać go (obiekt, który będzie używany jako kontekst) jako pierwszy parametr tej metody. Na przykładalert.call({})
dajeTypeError: Illegal invocation
. Jednakalert.call(window)
działa dobrze, ponieważ terazalert
jest wykonywany w swoim oryginalnym zakresie.Jeśli używasz
.call()
ze swoim obiektem w ten sposób:działa dobrze, ponieważ
requestAnimationFrame
jest wykonywany w zakresiewindow
zamiast obiektu.Jednak używanie za
.call()
każdym razem, gdy chcesz wywołać tę metodę, nie jest zbyt eleganckim rozwiązaniem. Zamiast tego możesz użyćFunction.prototype.bind()
. Ma podobny efekt.call()
, ale zamiast wywoływać funkcję, tworzy nową funkcję, która zawsze będzie wywoływana w określonym kontekście. Na przykład:Jedynym minusem
Function.prototype.bind()
jest to, że jest częścią ECMAScript 5, który nie jest obsługiwany w IE <= 8 . Na szczęście na MDN jest polyfill .Jak prawdopodobnie już się zorientowałeś, możesz użyć,
.bind()
aby zawsze wykonywaćrequestAnimationFrame
w kontekściewindow
. Twój kod może wyglądać następująco:Następnie możesz po prostu użyć
support.animationFrame(function() {});
.źródło