繁体   English   中英

如何在javascript匿名函数中调用类释放函数

[英]How can I call the class slibing function in javascript anonymous function

我试图通过以下方式在匿名函数中访问对象的成员函数:

  function a()
    {
      this.memb = 10;
    }

    a.prototype.hide_member = function(id){
      alert(id);
    }

    a.prototype.show_member = function(){
      setTimeout('this.hide_member(this.memb)', 2000); //Problem 1
      setTimeout(this.hide_member(this.memb), 2000); //Problem 2
      setTimeout(alert(this.memb), 2000);  //Problem 3
      this.memb++;
    }

    var obj = new a();
    obj.show_member();

在这里, 问题1-代码正好在给定的时间正确执行,意味着恰好在2000毫秒后执行,但是在2000毫秒后显示以下错误-

Uncaught TypeError: Object [object global] has no method 'hide_member'
(anonymous function)

问题2-代码正在执行,但是在代码解析后立即执行,这意味着没有在2000 ms之后执行。

问题3-与问题2中的问题相同

我对这三个问题感到困惑。 谢谢

这里发生了几件事情:

在此代码中:

setTimeout(this.hide_member(this.memb), 2000);

您将立即调用 this.hide_member ,并将其返回值传递给setTimeout 这就像foo(bar()) ,您在其中调用 bar并将其返回值传递给foo

您需要将一个函数传递给setTimeout ,然后从该函数内部调用成员函数。 请注意,在函数中, this将有所不同,因此您必须记住它:

a.prototype.show_member = function(){
  var self = this,
      memb_to_hide = this.memb;
  setTimeout(function() {
      self.hide_member(memb_to_hide);
  }, 2000);
  this.memb++;
}

请注意,我还记得该函数中使用的this.memb的旧值。

另一种方法是使用ES5的Function#bind ,但它要求浏览器的JavaScript引擎具有该功能(或您已加载“ ES5垫片”,因为bind是可填充的功能):

a.prototype.show_member = function(){
  setTimeout(this.hide_member.bind(this, this.memb), 2000);
  this.memb++;
}

Function#bind返回,调用它时,使用你的第一个参数给出的值将调用原函数的函数this (再传递任何进一步的参数)。 在这种情况下,我们不必记住this.memb的旧值,因为我们已经将旧值传递给bind


旁注:您所依赖的恐怖是自动分号插入。 我建议不要这样做,并在语句末尾提供分号,例如:

a.prototype.mumble = function() {
    /*...*/
}; // <=== Note the ;

是代码恰好在正确的时间执行,即在2000毫秒后执行,但是在2000毫秒后显示以下错误

错误是不言自明的: this是引用全局对象而不是a类的实例。 为了避免这种情况,您必须保存对实例上下文的引用:

a.prototype.show_member = function(){
    var self = this; //self refers to the instance
    setTimeout('self.hide_member(self.memb)', 2000);
    this.memb++;
}

代码正在执行,但是在代码解析后立即执行,这意味着不会在2000 ms之后执行。

它是在解析后执行的(更清楚地说,是在最后一行中调用show_member时执行的),因为它是一个函数调用:

setTimeout(this.hide_member(this.memb), 2000);

setTimeout需要一个字符串或一个函数才能正确执行,此处您要执行的是执行该函数并返回一个值(在这种情况下为setTimeout ,因此undefined ),该值将由setTimeout在2000 ms后执行。 调用undefined的结果是什么? 一个错误。 在第三种情况下,问题完全相同。

注意 :必须强调指出,将字符串传递给setTimeout是eval的一种形式,应避免使用; 您可以改为传递匿名函数:

a.prototype.show_member = function(){
    var self = this; //self refers to the instance
    setTimeout(function() {
        self.hide_member(self.memb); 
    }, 2000);
    this.memb++;
}

尝试这个:

a.prototype.show_member = function(){
  var self = this;
  setTimeout('self.hide_member(self.memb)', 2000); //Problem 1
  setTimeout(function() { self.hide_member(self.memb) }, 2000); //Problem 2
  setTimeout(function() { alert(self.memb) }, 2000);  //Problem 3
  this.memb++;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM