Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 事件触发对象方法将丢失该对象_Javascript_Oop - Fatal编程技术网

Javascript 事件触发对象方法将丢失该对象

Javascript 事件触发对象方法将丢失该对象,javascript,oop,Javascript,Oop,我不太习惯javascript的原型语法,所以这可能非常简单 function MyClass(){ this.init = function(input){ this.input.onkeyup = function(){ this.change(); } } } 显然,我在这里遗漏了一些内容,但this.input指的是HTMLinput元素。这里的问题是,this.change()中的this将不再引用MyClass的实例,而是引用H

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

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

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

事件处理程序会自动将
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实现与相同(代码在上面)

您还可以在每个类的基础上实现它:

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();
      });
   }
}
古语;-)选项是仅在函数外部存储对该的引用:

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

事件处理程序自动将
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实现与相同(代码在上面)

您还可以在每个类的基础上实现它:

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();
      });
   }
}
古语;-)选项是仅在函数外部存储对该的引用:

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

这应该是首选的方式而不是使用闭包吗?@Felix Kling:我当然这么认为,尤其是如果你经常这样做的话。无论如何,我添加了闭包解决方案,以使答案更完整。谢谢!都是好办法。我想我现在会继续使用古老的版本,因为它只在一个地方我需要它。这是不是最好的方式而不是使用闭包?@Felix Kling:我当然这么认为,特别是如果你经常这样做的话。无论如何,我添加了闭包解决方案,以使答案更完整。谢谢!都是好办法。我想我现在会继续使用古老的版本,因为它只在一个地方我需要它。