Passing around function including its context in javascript

后端 未结 3 952
遥遥无期
遥遥无期 2021-01-21 01:36

There is something I don\'t understand in javascript and broke down a sample problem to an essential case:

    a = function () {
      this.b = 5;
    }

    a.p         


        
相关标签:
3条回答
  • 2021-01-21 02:05

    It's about resolving the this value. This is resolved in the following way:

    myObject.something();//this in something is myObject
    window.something();//this is window
    button.onClick=function();//this when button is clicked is button
    

    How to solve it is already given, it's a common pitfall with passing callbacks like in the following example using setTimeout

    var test = function () {
      var me = this;// set reference to this
      this.sayAgain=function(){
         console.log("Hi, I am "+me.toString());
      }
    }
    test.prototype.toString=function(){
       return "test";
    }
    
    test.prototype.say = function () {
      console.log("Hi, I am "+this.toString());
    }
    
    var t = new test();
    setTimeout(t.say,50);//=window passing functon without ref to this
    setTimeout(function(){
      t.say();
    },150);//=test passing ref with function
    setTimeout(t.sayAgain,200);//=test using me as the saved this context
    

    The second timeout passes a closure to setTimeout, if you're planning to pass the say callback hundreds of times but only create a couple of test object instances then the implementation of the last one (sayAgain) would perform slightly better.

    This because you create a closure when you create the test instance but not when passing sayAgain as a callback, if you create many test instances and would not pass say that many times then remove this.me and this.sayAgain from the function body and pass say as a closure.

    You can use Function.prototype.bind but it's not supported in IE < 8 and I am not sure if it'll create a closure as in my example using t.say.

    0 讨论(0)
  • 2021-01-21 02:07

    You need to call the method using the object to get the context right. So:

    var e = function() { return d.c(); };
    

    In newer browsers you can use the bind method to do the same:

    var e = d.c.bind(d);
    

    In jQuery for example there is the proxy method that you can use also in older browsers:

    var e = $.proxy(d.c, d);
    
    0 讨论(0)
  • 2021-01-21 02:28

    d.c is like an unbound instance method. You can use Function.prototype.bind to create a new function that's bound to d (the first argument to .bind is the this argument):

    var e = d.c.bind(d);
    

    Or call e with d as the this argument:

    e.call(d);
    
    0 讨论(0)
提交回复
热议问题