事件触发对象方法丢失了对象

时间:2010-07-13 11:41:09

标签: javascript oop

我不习惯javascript的原型语法,所以这可能非常简单。

function MyClass(){
   this.init = function(input){
      this.input.onkeyup = function(){
         this.change();
      }
   }
}

显然我在这里留下了一些东西,但是this.input引用了一个HTML input元素。这里的问题是this.change()中的 this 将不再引用MyClass的实例而是引用HTML元素。如何获取对象而不是元素?

1 个答案:

答案 0 :(得分:1)

事件处理程序会自动将this关键字指向事件触发的元素。 ECMA-262第5版试图通过实现将函数“绑定”到特定对象的旧技术来打击这种情况:

// From Prototype.js
if (!Function.prototype.bind) { // check if native implementation available
  Function.prototype.bind = function(){ 
    var fn = this, args = Array.prototype.slice.call(arguments),
        object = args.shift(); 
    return function(){ 
      return fn.apply(object, 
        args.concat(Array.prototype.slice.call(arguments))); 
    }; 
  };
}

用法:

function MyClass(){
   this.init = function(input){
      this.input.onkeyup = (function(){
         this.change();
      }).bind(this);
   }
}

ECMAScript实现与PrototypeJS implementation相同(代码在上面)。

您也可以按类实现它:

function MyClass(){
   this.bind = function(){ 
       var args = Array.prototype.slice.call(arguments),
           self = this,
           fn = args.shift();
       return function(){ 
         return fn.apply(self, 
           args.concat(Array.prototype.slice.call(arguments))); 
       }; 
   };
   this.init = function(input){
      this.input.onkeyup = this.bind(function(){
         this.change();
      });
   }
}

古老的;-)选项只是在函数之外存储对this的引用:

function MyClass(){
   var self = this;
   this.init = function(input){
      this.input.onkeyup = function(){
         self.change();
      }
   }
}