เมื่อคุณเรียกใช้วิธีการ (เช่นฟังก์ชันที่กำหนดให้กับวัตถุ) ภายในนั้นคุณสามารถใช้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() {});
จากนั้นคุณก็สามารถใช้