无法按'this'访问属性



在以下片段中,我尝试从成员函数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的上下文不同。第二个功能闭合会改变此范围。

最新更新