在以下代码段中,我尝试从成员函数offset
中访问属性shift()
。看来,我无法以这种方式访问它,因为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);
在我的第一个示例中,为什么我无法通过运算符offset
访问this
?
我的回答:
我会在这里发布我的解决方案,因为我不能附加一个独立的答案。
再次浏览可怕编写的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);
答案 0 :(得分:3)
嵌套函数没有自己的this
上下文(它只是引用window
),因此在this
中为shiftImg
方法指定一个变量您可以在嵌套函数中引用它:
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
。如果您从this.shift()
内拨打shiftImg()
,则会看到您工作正常而无需添加self
。 See this MDN article for more
或者,您将匿名函数传递给setInterval
中的回调方法:
window.setInterval(function() {
productImg.shift();
}, 100);
如果你使用对象和jQuery,那么你会发现很多这个问题,而jQuery的$.proxy
实用工具方法可以很容易地对上面做类似的事情。
答案 1 :(得分:0)
在第一个示例中,偏移量的上下文与shiftImage的上下文不同。第二个函数闭包改变了这个范围。