代码之家  ›  专栏  ›  技术社区  ›  CodeCrypt

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

  •  1
  • CodeCrypt  · 技术社区  · 11 年前

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

      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毫秒之后执行。

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

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

    3 回复  |  直到 11 年前
        1
  •  4
  •   T.J. Crowder    11 年前

    这里发生了几件事:

    在此代码中:

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

    你是 使命感 this.hide_member 立即,并将其返回值传递到 setTimeout 。这和 foo(bar()) ,你在哪里 使命感 bar 并将其返回值传递到 foo .

    您需要将函数传递到 设置超时 ,然后从该函数中调用成员函数。注意,在该功能内, 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's Function#bind ,但它要求浏览器的JavaScript引擎具有该功能(或者您已经加载了一个“ES5填充程序”,如 bind 是一种可匀场功能):

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

    函数#bind 返回一个函数,该函数在被调用时将使用您在第一个参数中给定的值调用原始函数 (然后传递任何进一步的论点)。在这种情况下,我们 没有 必须记住 这个.membe 因为我们已经将旧值传递到 绑定 .


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

    a.prototype.mumble = function() {
        /*...*/
    }; // <=== Note the ;
    
        2
  •  1
  •   Niccolò Campolungo    11 年前

    代码是否在正确的时间执行,即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毫秒之后执行。

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

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

    setTimeout 期望一个字符串或函数能够正确执行,您在这里所做的是执行该函数并返回一个值(在这种情况下没有,所以它是 undefined )将由执行 设置超时 2000毫秒后。呼叫的结果是什么 未定义 ? 一个错误。第三种情况下的问题完全相同。

    注释 : 重要的是要强调将字符串传递给 设置超时 是eval的一种形式,应该避免;您可以传递一个匿名函数:

    a.prototype.show_member = function(){
        var self = this; //self refers to the instance
        setTimeout(function() {
            self.hide_member(self.memb); 
        }, 2000);
        this.memb++;
    }
    
        3
  •  0
  •   Chaitanya Munipalle    11 年前

    试试这个:

    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++;
    }