我有一些使用揭示模块模式的画廊代码:
window.jdiGallery = (function () { //Structure from http://code.tutsplus.com/tutorials/build-your-first-javascript-library--net-26796
var instance = null;
function Gallery (nodeList, options) {
this.settings = this.extend({
'transitionSpeed': 100, //in ms
'slideSpeed': 5000
}, options);
this.requestAnimationId; //We need this handle for canceling the RAF
this.start = null; //To help determine how far we are between transitions
for(var i = 0; i < nodeList.length; i++ )
this.instances[i] = this.init(nodeList[i]);
}
Gallery.prototype.init = function(el){
var slideEls = el.querySelectorAll('* > .nd-slide');
var slides = [];
//this is equal to the Gallery instance
for(var i = 0; i < slideEls.length - 1; i++)
slides.push(new Slide(slideEls[i], i, this.settings["inTransition"], this.settings["outTransition"]));
}
Gallery.prototype.moveToNext = function(timestamp){
var progress;
if (this.start === null) //this is equal to window
this.start = timestamp;
progress = timestamp - this.start;
if (progress > 5000) {
console.log('moving to next');
this.start = null;
requestAnimationFrame(this.moveToNext);
}
}
return {
create: function (selector, options) {
//creation code omitted for brevity
instance = new Gallery(els, options);
this.requestId = window.requestAnimationFrame(instance.moveToNext);
},
当调用create
时,它最终会调用Gallery.init()
。在该函数中,this
等于 Gallery
的实例。
然后,我将 Gallery.moveToNext()
作为回调传递给我的 requestFrameAnimation
。当我们进入 moveToNext
时,this
的值为 window
。为什么它没有像我预期的那样引用Gallery
?
最佳答案
是的,这是 JavaScript 中的一个常见问题。 JavaScript 中的 this
绑定(bind)取决于如何调用函数。
一般规则是(对于浏览器):
如果从裸标识符调用函数,
this
将设置为window
> var foo = function() { console.log(this); }; > foo(); Window
如果直接从对象调用函数,
this
将设置为该对象> var bar = { > bar: function() { console.log(this); } > }; > bar.foo(); Object
如果使用
.call()
或.apply()
调用函数,this
将设置为作为第一个参数传入
在这种情况下,requestAnimationFrame
仅具有对 moveToNext
函数本身的引用,而不是对其上下文的引用。一种解决方案是使用 Function.prototype.bind
:
requestAnimationFrame(this.moveToNext.bind(this));
此外,您可以将绑定(bind)版本缓存在Gallery.prototype.init
内
this.moveToNextBound = this.moveToNext.bind(this);
您也可以只使用匿名函数,但为此您需要将 this
重新绑定(bind)到另一个变量。
var self = this;
requestAnimationFrame(function() { self.moveToNext.apply(arguments); });
关于javascript - 这等于 requestAnimationFrame 回调中的窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22082614/