JavaScript setInterval未正确绑定到正确的闭包 问题
大家好,我对JavaScript相当陌生,我来自非常面向对象的Python和Java世界,这是我的免责声明 下面有两段代码,可选的实现,一个是JavaScript,一个是Coffeescript。我正在尝试在Meteor.js应用程序的服务器上运行它们。我遇到的问题是,当使用绑定方法“this.printSomething”作为回调调用函数“setInterval”时,一旦执行该回调,它将失去与实例的作用域,从而导致“this.bar”未定义!有人能解释一下为什么JavaScript或coffescript代码不起作用吗 JavaScript实现 Coffeescript实现JavaScript setInterval未正确绑定到正确的闭包 问题,javascript,node.js,coffeescript,meteor,Javascript,Node.js,Coffeescript,Meteor,大家好,我对JavaScript相当陌生,我来自非常面向对象的Python和Java世界,这是我的免责声明 下面有两段代码,可选的实现,一个是JavaScript,一个是Coffeescript。我正在尝试在Meteor.js应用程序的服务器上运行它们。我遇到的问题是,当使用绑定方法“this.printSomething”作为回调调用函数“setInterval”时,一旦执行该回调,它将失去与实例的作用域,从而导致“this.bar”未定义!有人能解释一下为什么JavaScript或coffe
您在setInterval回调中丢失了
Foo
的上下文。您可以使用将上下文设置为类似这样的内容,将回调函数引用的上下文设置回Foo
实例
setInterval(this.printSomething.bind(this), 3000);
随叫随到
setInterval(this.printSomething, 3000);
回调方法获取全局上下文(在web情况下为窗口,在租户(如节点)情况下为全局),因此您不会在那里获取属性bar
,因为此
引用全局上下文
或者只是
this.printSomething = function() {
console.log(bar); //you can access bar here since it is not bound to the instance of Foo
}
您还可以尝试创建一个闭包来捕获
this
。像这样:
var self = this;
this.start = function () {
setInterval(function(){
self.printSomething();
}, 3000);
}
当您输入一个函数时,您将在javascript中获得一个新的作用域。您可以从父范围继承,但
this
的值会更改。在coffeescript中,您可以使用fat箭头(看起来它将成为ecmascript 6的一部分),在进入新范围之前,它基本上保留了对this
的引用
class foo
constructor: (bar) ->
@bar = bar
start: () =>
Meteor.setInterval(@printSomething, 3000)
printSomething: () =>
console.log @bar
x = new foo 0
x.start()
在javascript中处理这类事情的标准方法是在要引用的点处创建一个对this
的引用,然后在范围外调用中使用该引用
function Foo(bar) {
// make reference to `this` at the point
// where you want to use it from
self = this;
self.bar = bar;
self.start = function () {
setInterval(self.printSomething, 3000);
}
self.printSomething = function() {
console.log(self.bar);
}
}
f = new Foo(5);
f.start();
对于CoffeeScript,函数可以与--
printSomething:()=>
@JonathanLonowski绑定,谢谢。。。不熟悉咖啡语法。:)
class foo
constructor: (bar) ->
@bar = bar
start: () =>
Meteor.setInterval(@printSomething, 3000)
printSomething: () =>
console.log @bar
x = new foo 0
x.start()
function Foo(bar) {
// make reference to `this` at the point
// where you want to use it from
self = this;
self.bar = bar;
self.start = function () {
setInterval(self.printSomething, 3000);
}
self.printSomething = function() {
console.log(self.bar);
}
}
f = new Foo(5);
f.start();