【问题标题】:Call JavaScript's setTimeOut in dojo Class在 dojo 类中调用 JavaScript 的 setTimeOut
【发布时间】:2011-02-23 14:08:06
【问题描述】:

我正在尝试将我的 JavaScript 函数转换为 dojo 类。我的一个 JS 方法中有一个 setTimeOut("functionName",2000)。如何从使用 dojo.declare 方法声明的类中的方法调用它。例如,下面是我的自定义类。

    dojo.declare("Person",null,{
                    constructor:function(age,country,name,state){
                        this.age=age;
                        this.country=country;
                        this.name=name;
                        this.state=state;
                    },
                    moveToNewState:function(newState){
                        this.state=newState;
//I need to call "isStateChanged" method after 2000 ms. How do I do this?
                        setTimeOut("isStateChanged",2000);
                    },                  
                    isStateChanged:function(){
                        alert('state is updated');
                    }
                });
var person=new Person(12,"US","Test","TestState");
person.moveToNewState("NewState");

请告诉我如何在 2000 毫秒后从 moveToNewState 方法调用 isStateChanged 方法。

【问题讨论】:

  • 它是setTimeout,而不是setTimeOut,最好(总是或几乎总是)将函数引用传递给它,而不是它必须编译的字符串。

标签: javascript dojo settimeout


【解决方案1】:

您正在寻找一种将this绑定setTimeout 将调用的函数的方法:

moveToNewState:function(newState){
    // Remember `this` in a variable within this function call
    var context = this;

    // Misc logic
    this.state = newState;

    // Set up the callback
    setTimeout(function() {
        // Call it
        context.isStateChanged();
    }, 2000);
},     

上面是使用 closure 来绑定上下文(参见:Closures are not complicated),这是执行此操作的常用方法。 Dojo 可能会提供一个内置函数来生成这些“绑定”回调(Prototype 和 jQuery)。 (编辑:确实如此,在peller下方的评论中请指出dojo.hitch。)

更多关于这个一般概念的信息:You must remember this

【讨论】:

  • 非常感谢您的回复。有效。为什么我们要创建一个名为 context 的新变量,然后将当前对象分配给它?我认为“this”将引用“Person”对象并且它有一个方法“isStateChanged”
  • @Steven: “我们为什么要创建一个名为 context 的新变量,然后将当前对象分配给它?” 因为this(在 JavaScript 中)完全由如何调用函数,而不是在哪里定义函数setTimeout 在全局上下文中调用函数,这在浏览器上意味着this 将是window,这显然不是你想要的。更多内容请参见上面的 You must remember this 链接以及此处:Mythical methods
  • 这种情况下实际上不需要闭包,但是dojo.hitch是Dojo中绑定变量的等价物。
  • @peller:啊,你去,谢谢。我知道 Dojo 会有一个。请记住,无论如何都涉及到闭包,这只是闭包的问题——jQuery 的 proxy、Prototype 的 bind 和 Dojo 的 hitch 都会创建闭包,但它们是在一个很好的、包含良好的库代码中的范围,因此闭包不会不必要地在内存中保留任何其他内容。
  • +1 确实,必须涉及闭包,至少如果您想在被调用函数中引用“this”。抱歉,我意识到我的反对票很仓促。堆栈溢出并没有让我撤消它们:-/ FWIW,现在 ES5 也有绑定。
【解决方案2】:

这与dojo无关,这是纯javascript。您正在寻找的是:

var $this = this;
setTimeout(function() { $this.isStateChanged() }, 2000);

查看the docs on setTimeout

哦,而且,请不要在函数名周围使用引号(因为这会使其成为一个无用的字符串,可能会得到 evaled 并会出错)。

【讨论】:

  • 非常感谢您的回复。有效。为什么我们要创建一个名为 $this 的新变量,然后将当前对象分配给它?我认为“this”将引用“Person”对象,它有一个方法“isStateChanged”
  • this 确实引用了 Person 实例,但仅在 moveToNewState 闭包中。当超时触发时,它的上下文(阅读:this 魔术变量)将不是Person 实例,而是window。这就是为什么您需要将实例存储在不同名称的变量中的原因。 T.J. Crowder 发布了一些关于这个问题的好链接。
  • 非常感谢 Felix 的热情回复
【解决方案3】:

您可以简单地调用setTimeout(this.isStateChanged, 2000),它将传递正确的函数引用,这与您直接调用该方法的方式不同。立即计算表达式 this.isStateChanged。要进行调用,无需将其包装在额外的函数中或声明局部变量。

要将this 变量绑定到被调用的函数,您可以使用dojo.hitch,它将创建自己的闭包,而不会污染局部变量空间并可能通过其他引用泄漏。

【讨论】:

    【解决方案4】:

    您可以使用 dojo/_base/lang 并使用它的挂接方法,如下面的代码:

    moveToNewState:function(newState){
      // Misc logic
      this.state = newState;
    
      // Set up the callback
      setTimeout(lang.hitch(this, function() {
        // Call with `this`
        this.isStateChanged();
      }), 2000);
    }, 
    

    【讨论】:

      猜你喜欢
      • 2012-08-25
      • 2011-08-20
      • 1970-01-01
      • 2011-10-23
      • 2011-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多