เมื่อคุณเรียกใช้วิธีการ (เช่นฟังก์ชันที่กำหนดให้กับวัตถุ) ภายในนั้นคุณสามารถใช้thisตัวแปรเพื่ออ้างถึงวัตถุนี้ตัวอย่างเช่น:
var obj = {
someProperty: true,
someMethod: function() {
console.log(this.someProperty);
}
};
obj.someMethod();
หากคุณกำหนดวิธีการจากอ็อบเจ็กต์หนึ่งไปยังอีกอ็อบเจกต์หนึ่งthisตัวแปรของมันจะอ้างถึงอ็อบเจ็กต์ใหม่เช่น
var obj = {
someProperty: true,
someMethod: function() {
console.log(this.someProperty);
}
};
var anotherObj = {
someProperty: false,
someMethod: obj.someMethod
};
anotherObj.someMethod();
สิ่งเดียวกันนี้จะเกิดขึ้นเมื่อคุณกำหนดrequestAnimationFrameวิธีการwindowให้กับวัตถุอื่น ฟังก์ชันเนทีฟเช่นนี้มีการป้องกันในตัวจากการเรียกใช้งานในบริบทอื่น
มีFunction.prototype.call()ฟังก์ชันที่ช่วยให้คุณสามารถเรียกใช้ฟังก์ชันในบริบทอื่นได้ คุณต้องส่งผ่าน (วัตถุที่จะใช้เป็นบริบท) เป็นพารามิเตอร์แรกของวิธีนี้ ยกตัวอย่างให้alert.call({}) TypeError: Illegal invocationอย่างไรก็ตามใช้alert.call(window)งานได้ดีเพราะตอนนี้alertถูกดำเนินการในขอบเขตเดิม
หากคุณใช้.call()กับวัตถุของคุณเช่นนั้น:
support.animationFrame.call(window, function() {});
มันใช้งานได้ดีเพราะrequestAnimationFrameดำเนินการในขอบเขตwindowแทนที่จะเป็นวัตถุของคุณ
อย่างไรก็ตามการใช้.call()ทุกครั้งที่คุณต้องการเรียกวิธีนี้ไม่ใช่วิธีแก้ปัญหาที่หรูหรามากนัก คุณสามารถใช้Function.prototype.bind()ไฟล์. มีผลคล้ายกับ.call()แต่แทนที่จะเรียกใช้ฟังก์ชันจะสร้างฟังก์ชันใหม่ซึ่งจะถูกเรียกใช้ในบริบทที่ระบุเสมอ ตัวอย่างเช่น:
window.someProperty = true;
var obj = {
someProperty: false,
someMethod: function() {
console.log(this.someProperty);
}
};
var someMethodInWindowContext = obj.someMethod.bind(window);
someMethodInWindowContext();
เพียงข้อเสียของการFunction.prototype.bind()เป็นว่ามันเป็นส่วนหนึ่งของ ECMAScript 5 ซึ่งไม่ได้รับการสนับสนุนใน IE <= 8 โชคดีที่มีpolyfill บน MDN
ดังที่คุณทราบแล้วคุณสามารถใช้.bind()เพื่อดำเนินการrequestAnimationFrameในบริบทของwindow. รหัสของคุณอาจมีลักษณะดังนี้:
var support = {
animationFrame: (window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame).bind(window)
};
support.animationFrame(function() {});จากนั้นคุณก็สามารถใช้