【问题标题】:javascript function pointer and "this"javascript函数指针和“this”
【发布时间】:2013-06-30 04:11:00
【问题描述】:

使用 jsPlumb 进行绑定,我将方法作为变量传递,用作回调。当它被调用时,“this”不是该方法所属的对象。如何访问该方法的对象实例,以便访问它的变量和其他成员函数?

我无法控制回调调用方法,它是一个单独的库。我所做的就是从我的对象 init 方法中调用绑定。我本来希望 this 在我的 _connection 方法中成为它的对象。

jsPlumb.bind('connection', this._connection);

【问题讨论】:

    标签: javascript jquery jsplumb


    【解决方案1】:

    任何functionthis 的值为determined when it's calledfunction 与“object”实际上没有其他联系,只是它是否被称为 object.method()method.call(object)

    因此,要传递具有固定this 值的function,它需要是bound

    jsPlumb.bind('connection', this._connection.bind(this));
    

    jQuery 还包含一个包装器和兼容性填充 jQuery.proxy():

    jsPlumb.bind('connection', $.proxy(this._connection, this));
    

    【讨论】:

    • 但是,.bind() 的第一个参数应该是您希望 this 指针成为的对象本身,而不是像您和 OP 那样的字符串 'connection'。我看不出你是如何用你的代码解决任何问题的。
    • @jfriend00 我假设jsPlumb.bind() 用于事件处理程序而不是函数上下文,'connection' 是事件名称。
    【解决方案2】:

    如果您不想使用 Function.prototype.bind(因为旧浏览器不支持它)并且您不想使用 jquery,则更复杂的版本是:

    jsPlumb.bind('connection', (function(me){
      return function(){
        me._connection();// no need for call, apply or bind
      }
    })(this));
    

    在传递对象方法时丢失this是一个常见问题,这里是问题及其在脚本中重新生成的解决方案:

    var ps={//publish subscribe
      messages:{},
      add:function(m,fn){
        if(!this.messages[m]){
          this.messages[m]=[];
        }
        this.messages[m].push(fn);
      },
      publish:function(m,data){
        var i = 0;
        var msg=this.messages[m];
        for(i=0;i<msg.length;i++){
          msg[i](data);
        }
      }
    }
    
    function test(){
    }
    test.prototype.logit=function(data){
      console.log(data,this.toString());
    };
    test.prototype.toString=function(){
      return "This is a test object";
    }
    // self made bind function
    function myBind(me,fn){
      return function(){
        fn.apply(me,arguments);
      }
    }
    var t=new test();
    // pass a closure instead of a function
    ps.add("test1",(function(me){
          return function(data){
            me.logit(data);
          }
        })(t)
    );
    // pass a function
    ps.add("test2",t.logit);
    // function created with bind
    ps.add("test3",t.logit.bind(t));
    // passing closure using myBind
    ps.add("test4",myBind(t,t.logit));
    // next line will log "This is a test object"
    ps.publish("test1","Passing a closure instead of the function, this is:");
    // next line will log "function (data){console.log(..."
    // so `this` is not test but test.logit
    ps.publish("test2","Passing a the function, this is:");
    // next line will log "This is a test object"
    ps.publish("test3","Passing a the function using bind, this is:");
    // next line will log "This is a test object"
    ps.publish("test4","Passing a closure with myBind, this is:");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-27
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      • 2011-06-19
      相关资源
      最近更新 更多