在以下片段中,我尝试从成员函数shift()
中访问属性offset
。看来,我无法以这种方式访问它,因为console.log
报告了Offset: NaN
:
function shiftImg() {
this.offset = 0;
this.shift =
function() {
this.offset++;
console.log("Offset: " + this.offset);
};
}
productImg = new shiftImg;
window.setInterval(productImg.shift, 100);
但是,将上述代码从模板范式转换为闭合范式,如我所期望的:
function shiftImg() {
var offset = 0;
return {
shift: function() {
offset++;
console.log("Offset: " + offset);
}
}
}
productImg = shiftImg();
window.setInterval(productImg.shift, 100);
在我的第一个示例中,为什么我无法通过操作员this
访问offset
?
我的答案:
我将在这里发布我的解决方案,因为我无法附加独立答案。我再次浏览了可怕的MDN文档的混乱,我了解了bind
方法:
function shiftImg() {
this.offset = 0;
this.shift =
function() {
this.offset++;
var img = document.getElementById('img');
img.style.paddingLeft = this.offset + 'px';
console.log("Offset: " + this.offset);
};
}
productImg = new shiftImg;
window.setInterval(productImg.shift.bind(productImg), 100);
嵌套函数没有其自己的this
上下文(它将简单地参考window
),因此将变量分配给shiftImg
中的this
方法,您可以在该方法中参考该变量嵌套功能:
function shiftImg() {
var self = this;
this.offset = 0;
this.shift =
function() {
self.offset++;
console.log("Offset: " + self.offset);
};
}
productImg = new shiftImg();
window.setInterval(productImg.shift, 100);
您需要这样做的原因是因为调用该方法的setInterval
的调用是在单独的执行上下文中运行的,其中this
等于window
。如果您从shiftImg()
中调用this.shift()
,您会发现您的工作正常,而无需添加self
。有关更多信息,请参见此MDN文章。
或者,您将匿名函数传递给setInterval
中的回调方法:
window.setInterval(function() {
productImg.shift();
}, 100);
如果您使用对象和jQuery,那么您会发现很多问题,而JQuery的$.proxy
实用程序方法使与上面的事情相似。
在第一个示例中,偏移的上下文与shiftimage的上下文不同。第二个功能闭合会改变此范围。