【问题标题】:Cannot access properties by 'this' [duplicate]无法通过“this”访问属性[重复]
【发布时间】:2014-04-18 08:41:06
【问题描述】:

在下面的 sn-p 中,我尝试从成员函数 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);

【问题讨论】:

  • 只有在传递给 setInterval 时才会丢失范围:jsfiddle.net/F8cJc,这是因为当您将函数引用传递给 setInterval 时,它会以 window 作为上下文执行,除非你用.bind

标签: javascript scope this private


【解决方案1】:

嵌套函数没有它自己的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(),您会发现它工作得很好,无需添加selfSee this MDN article for more.

或者,您将匿名函数传递给setInterval 中的回调方法:

window.setInterval(function() {
    productImg.shift();
}, 100); 

如果你使用对象和 jQuery,那么你会发现这个问题很多,而 jQuery 的$.proxy 实用方法使得做上面类似的事情变得相当容易。

【讨论】:

  • 投反对票有什么原因吗?
  • 这是一个影响每个嵌套函数情况的通用“问题”,还是仅针对window.setInterval() 发生这种情况?
  • 不使用self 变量,bind() 是否更合适,如我编辑的问题底部所示?
  • 更新了我的答案,希望对@davide 有帮助 :)
【解决方案2】:

在第一个示例中,偏移量的 this 的上下文与 shiftImage 的上下文不同。第二个函数闭包改变了 this 的范围。

【讨论】:

  • 实际上是对window的引用
  • 所以这是范围的问题。那么,如何从方法函数中访问offset
  • @KevinB - 是的,你是对的。我没有看到“新”被省略了。我已经编辑并删除了该部分。
  • @davide - 上面 Ian 的回答向您展示了如何做到这一点,您保存对范围的引用(变量“self”)并改用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-27
  • 1970-01-01
  • 1970-01-01
  • 2018-05-15
  • 2013-03-20
  • 2011-11-05
  • 2021-02-05
相关资源
最近更新 更多