使用'this'对象构造函数中的变量

using the 'this' variable within object constructor

本文关键字:变量 this 使用 对象 构造函数      更新时间:2023-09-26

我对在对象构造函数中调用'this'变量时得到的结果有点困惑。

function Slider(tag){
    this.tag = document.querySelector(tag),
    this.start = function(){
        return this.interval;
    },
    this.interval = setInterval(function(){
        console.log(this.tag); //undefined
        console.log(this); //window object
    }, 2000)
}
var route ={
    init:function(){        
        mySlide = new Slider('slider');
        mySlide.start();
    }
}
document.addEventListener('DOMContentLoaded', route.init);

我正在记录标签console.log(this.tag),但它返回undefined,当记录this变量在console.log(this)它指的是窗口对象。

Here is a Demo

问题:为什么console.log(this.tag)不返回选定的元素?

这是因为当您将回调函数传递给setInterval时,它在全局作用域中被调用。这就是为什么thiswindow

您可以使用Function.bind()将函数的上下文设置为您的this对象,并使其按您的意愿工作。

this.interval = setInterval(function(){
    console.log(this.tag);
}.bind(this), 2000);

另外,我只是想指出mySlide.start();什么也不做。当调用new Slider('slider')时,就是设置间隔的时候。您的mySlide.start();只返回intervalID(仅用于clearInterval())。实际上,由于您甚至没有使用mySlide.start();的返回值,调用它是无用的。

更新:另一个解决方案是在构造函数中使用var self = this;,然后在setInterval()中使用self:

function Slider(tag){
    var self = this;
    this.tag = document.querySelector(tag),
    this.interval = setInterval(function(){
        console.log(self.tag);
    }, 2000);
}

更新:如果你的浏览器支持"箭头功能",那么你可以这样做:

this.interval = setInterval(() => {
    console.log(this.tag);
}, 2000);

setInterval中匿名函数的作用域是Window。如果你想让它成为Slider实例,你应该先绑定它。

function Slider(tag){
this.tag = document.querySelector(tag),
this.start = function(){
    return this.interval;
},
this.interval = setInterval(function(){
    console.log(this.tag); //undefined
    console.log(this); //window object
}.bind(this), 2000)
}