Wenn Sie eine Methode ausführen (dh eine einem Objekt zugewiesene Funktion), können Sie darin eine this
Variable verwenden, um auf dieses Objekt zu verweisen, zum Beispiel:
var obj = {
someProperty: true,
someMethod: function() {
console.log(this.someProperty);
}
};
obj.someMethod(); // logs true
Wenn Sie eine Methode von einem Objekt zu einem anderen zuweisen, this
bezieht sich ihre Variable auf das neue Objekt, zum Beispiel:
var obj = {
someProperty: true,
someMethod: function() {
console.log(this.someProperty);
}
};
var anotherObj = {
someProperty: false,
someMethod: obj.someMethod
};
anotherObj.someMethod(); // logs false
Das gleiche passiert, wenn Sie einem anderen Objekt eine requestAnimationFrame
Methode zuweisen window
. Native Funktionen wie diese verfügen über einen integrierten Schutz vor der Ausführung in einem anderen Kontext.
Es gibt eine Function.prototype.call()
Funktion, mit der Sie eine Funktion in einem anderen Kontext aufrufen können. Sie müssen es nur (das Objekt, das als Kontext verwendet wird) als ersten Parameter an diese Methode übergeben. Zum Beispiel alert.call({})
gibt TypeError: Illegal invocation
. Funktioniert jedoch alert.call(window)
einwandfrei, da jetzt alert
im ursprünglichen Bereich ausgeführt wird.
Wenn Sie .call()
mit Ihrem Objekt so verwenden:
support.animationFrame.call(window, function() {});
es funktioniert gut, weil requestAnimationFrame
es im Bereich von window
anstelle Ihres Objekts ausgeführt wird.
Es .call()
ist jedoch keine sehr elegante Lösung , jedes Mal zu verwenden, wenn Sie diese Methode aufrufen möchten. Stattdessen können Sie verwenden Function.prototype.bind()
. Es hat einen ähnlichen Effekt wie .call()
, aber anstatt die Funktion aufzurufen, wird eine neue Funktion erstellt, die immer im angegebenen Kontext aufgerufen wird. Beispielsweise:
window.someProperty = true;
var obj = {
someProperty: false,
someMethod: function() {
console.log(this.someProperty);
}
};
var someMethodInWindowContext = obj.someMethod.bind(window);
someMethodInWindowContext(); // logs true
Der einzige Nachteil Function.prototype.bind()
ist, dass es Teil von ECMAScript 5 ist, das in IE <= 8 nicht unterstützt wird . Glücklicherweise gibt es eine Polyfüllung auf MDN .
Wie Sie wahrscheinlich bereits herausgefunden haben, können Sie verwenden, .bind()
um immer requestAnimationFrame
im Kontext von auszuführen window
. Ihr Code könnte folgendermaßen aussehen:
var support = {
animationFrame: (window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame).bind(window)
};
Dann können Sie einfach verwenden support.animationFrame(function() {});
.