简体   繁体   English

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

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

I am trying to access the object's member function in an anonymous function by the following way- 我试图通过以下方式在匿名函数中访问对象的成员函数:

  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();

Here, Problem 1 - is the code is executing exactly at right time what is given, means just after 2000 ms, but it's displaying the following error after 2000 ms - 在这里, 问题1-代码正好在给定的时间正确执行,意味着恰好在2000毫秒后执行,但是在2000毫秒后显示以下错误-

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

Problem 2 - The code is executing, but it's executing immediately after the code is parsed, means not after 2000 ms. 问题2-代码正在执行,但是在代码解析后立即执行,这意味着没有在2000 ms之后执行。

Problem 3 - Same problem as in Problem 2 问题3-与问题2中的问题相同

I am getting confusion here about these 3 problems. 我对这三个问题感到困惑。 Thanks 谢谢

A couple of things are going on here: 这里发生了几件事情:

In this code: 在此代码中:

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

you're calling this.hide_member immediately, and passing its return value into setTimeout . 您将立即调用 this.hide_member ,并将其返回值传递给setTimeout This is exactly like foo(bar()) , where you're calling bar and passing its return value into foo . 这就像foo(bar()) ,您在其中调用 bar并将其返回值传递给foo

You need to pass a function into setTimeout , and then call the member function from within that function. 您需要将一个函数传递给setTimeout ,然后从该函数内部调用成员函数。 Note that within the function, this will be different, so you have to remember it: 请注意,在函数中, 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++;
}

Note that I also remembered the old value of this.memb to use in the function. 请注意,我还记得该函数中使用的this.memb的旧值。

Another way to do that is with ES5's Function#bind , but it requires that the browser's JavaScript engine have that (or that you've loaded an "ES5 shim", as bind is a shimmable feature): 另一种方法是使用ES5的Function#bind ,但它要求浏览器的JavaScript引擎具有该功能(或您已加载“ ES5垫片”,因为bind是可填充的功能):

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

Function#bind returns a function that, when called, will call the original function using the value you give in the first argument as this (and then passing on any further arguments). Function#bind返回,调用它时,使用你的第一个参数给出的值将调用原函数的函数this (再传递任何进一步的参数)。 In this case, we didn't have to remember the old value of this.memb because we've already passed the old value into bind . 在这种情况下,我们不必记住this.memb的旧值,因为我们已经将旧值传递给bind


Side note: You're relying on the horror that is Automatic Semicolon Insertion. 旁注:您所依赖的恐怖是自动分号插入。 I recommend not doing that, and supplying semicolons at the ends of your statements, eg: 我建议不要这样做,并在语句末尾提供分号,例如:

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

is the code is executing exactly at right time what is given, means just after 2000 ms, but it's displaying the following error after 2000 ms 是代码恰好在正确的时间执行,即在2000毫秒后执行,但是在2000毫秒后显示以下错误

The error is self-explaining: this is referring to the global object instead of the instance of the a class. 错误是不言自明的: this是引用全局对象而不是a类的实例。 To avoid this you have to save a reference to the instance's context: 为了避免这种情况,您必须保存对实例上下文的引用:

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

The code is executing, but it's executing immediately after the code is parsed, means not after 2000 ms. 代码正在执行,但是在代码解析后立即执行,这意味着不会在2000 ms之后执行。

It is executed after the parsing(to be more clear it is executed when show_member is called in the last line) because it is a function call: 它是在解析后执行的(更清楚地说,是在最后一行中调用show_member时执行的),因为它是一个函数调用:

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

setTimeout expects a string or a function in order to be executed properly, what you're doing here is to execute the function and return a value(nothing in this case, so it's undefined ) which will be executed by setTimeout after 2000 ms. setTimeout需要一个字符串或一个函数才能正确执行,此处您要执行的是执行该函数并返回一个值(在这种情况下为setTimeout ,因此undefined ),该值将由setTimeout在2000 ms后执行。 What is the result of a call to undefined ? 调用undefined的结果是什么? An error. 一个错误。 The problem is exactly the same in the third case. 在第三种情况下,问题完全相同。

NOTE : It is important to highlight that passing a string to setTimeout is a form of eval and it should be avoided; 注意 :必须强调指出,将字符串传递给setTimeout是eval的一种形式,应避免使用; you can pass an anonymous function instead: 您可以改为传递匿名函数:

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

Try this: 尝试这个:

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