javascript - 这等于 requestAnimationFrame 回调中的窗口

标签 javascript

我有一些使用揭示模块模式的画廊代码:

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/

相关文章:

javascript - $(window).width() 在正常状态下和在检查元素上的响应状态下的区别

javascript - Discord.js 每隔 1 分钟发送一条消息

javascript - 如何有效地连接 Uint8Array?

javascript - 使用 jQuery 动态创建多个 div 并为每个 div 分配不同的 css 属性

javascript - 在 Perl-CGI 生成的页面中包含 JavaScript

javascript - 访问 D3.js 中的 javascript 对象

javascript - 从 ul 中删除 li 元素

javascript - 从 Chrome 扩展程序发送 XHR 到 PHP 页面时出错 : Cross origin requests are only supported for HTTP

javascript - Vuetify v-btn-toggle 组的 v-model 错误

javascript - React-Router 无法创建子路由