Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript setInterval未正确绑定到正确的闭包 问题_Javascript_Node.js_Coffeescript_Meteor - Fatal编程技术网

JavaScript setInterval未正确绑定到正确的闭包 问题

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

大家好,我对JavaScript相当陌生,我来自非常面向对象的Python和Java世界,这是我的免责声明

下面有两段代码,可选的实现,一个是JavaScript,一个是Coffeescript。我正在尝试在Meteor.js应用程序的服务器上运行它们。我遇到的问题是,当使用绑定方法“this.printSomething”作为回调调用函数“setInterval”时,一旦执行该回调,它将失去与实例的作用域,从而导致“this.bar”未定义!有人能解释一下为什么JavaScript或coffescript代码不起作用吗

JavaScript实现 Coffeescript实现
您在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();