2010-07-13 93 views
1

我不是很習慣JavaScript的原型語法,所以這可能非常簡單。事件觸發對象方法丟失對象

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

很顯然,我已經留下了一些東西在這裏,但this.input指HTML input元素。這裏的問題是這個this.change()將不再引用MyClass的實例,而是引用HTML元素。我如何獲得對象而不是元素?

回答

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(); 
     } 
    } 
} 
+0

若本成爲使用閉包的首選方式? – 2010-07-13 11:50:15

+0

@Felix Kling:我當然這麼認爲,特別是如果你做了很多。無論如何,我都添加了封閉解決方案,以使答案更完整。 – 2010-07-13 11:53:19

+1

謝謝!所有的好方案。現在我想繼續使用古代版本,因爲它只在我需要它的地方。 – Martin 2010-07-13 13:01:45

相關問題