问题
I'm a bit confused on the result I'm getting when calling the 'this' variable inside in object constructor.
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);
I'm logging tag console.log(this.tag)
however it's returning undefined
and when logging the this
variable inside console.log(this)
it refers to the window object.
Here is a Demo
Question: Why isn't console.log(this.tag)
returning the selected element?
回答1:
This is because when you pass a callback function to setInterval
, it's called in the global scope. That's why this
is window
.
You can use Function.bind() to set the context of the function to your this
object and make it work as you want.
this.interval = setInterval(function(){
console.log(this.tag);
}.bind(this), 2000);
Also, I just want to point out that mySlide.start();
does nothing. When you call new Slider('slider')
, that's when your interval is set. Your mySlide.start();
just returns the intervalID (which is only used for clearInterval()
). Actually since you are not even using the return value of mySlide.start();
, calling it is useless.
UPDATE: Another solution is to use var self = this;
in your constructor function and then use self
inside setInterval()
:
function Slider(tag){
var self = this;
this.tag = document.querySelector(tag),
this.interval = setInterval(function(){
console.log(self.tag);
}, 2000);
}
UPDATE: If you are on a browser that supports "arrow functions", then you can do this:
this.interval = setInterval(() => {
console.log(this.tag);
}, 2000);
回答2:
The scope of the anonymous function in the setInterval
is the Window.
If you want it to be the Slider instance, you should bind it first.
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)
}
来源:https://stackoverflow.com/questions/40515218/using-the-this-variable-within-object-constructor