2014-01-16 36 views
1

我想將現有對象與擴展它(及其原型)的類相結合。JavaScript mixin組合對象和類創建TypeError

代碼如下,我當然可以添加更多的細節,如果需要但我認爲這涵蓋了這個問題。如代碼中指定的,錯誤是TypeError: this.prototype is undefined。這段代碼中的最後一行是導致此錯誤的調​​用,錯誤本身發生在.addMixin(mixin)函數中。

我已經習慣了到這裏引用包括: http://www.joezimjs.com/javascript/javascript-mixins-functional-inheritance/http://javascript.crockford.com/prototypal.html(雖然這是墊腳石以上到達)

注:我知道這可以用jQuery和其他圖書館做,但我想做這個香草。

// setup some tools 
var config = { 
    writable: true, 
    enumerable: true, 
    configurable: true 
}; 

var defineProperty = function(obj, name, value) { 
    config.value = value; 
    Object.defineProperty(obj, name, config); 
} 

// And mixins 
Object.prototype.addMixin = function (mixin) {  
    for (var prop in mixin) { 
     if (mixin.hasOwnProperty(prop)) { 
      this.prototype[prop] = mixin[prop]; // this is where the error occurs: 'TypeError: this.prototype is undefined' 
     } 
    } 
}; 

// Define File prototype 
var File = Object.create(Object.prototype); 
defineProperty(File, 'file', null); 
defineProperty(File, 'outputID', null); 
defineProperty(File, 'hash', null); 
defineProperty(File, 'hashThis', function (callback) {}); 

// define Timestamp prototype 
var Timestamp = Object.create(File); 
defineProperty(Timestamp, 'protectedHashValue', null); 
defineProperty(Timestamp, 'timestamp', null); 
defineProperty(Timestamp, 'read', function() {}); 
defineProperty(Timestamp, 'verify', function() {}); 

// Later, we take in a file using the HTML5 file API 
// First, create the File object (in an array because there are multiple files) 
globalStatus.files[fileIndex] = Object.create(File); 
// and now place the file in the file property of the new File object 
globalStatus.files[fileIndex].file = evt.target.files[fileIndex]; 

// Later on we determine that a particular file is a timestamp 
// We want to mix in the properties of the Timestamp prototype to this existing File object 
globalStatus.files[fileIndex].addMixin(Timestamp); // this is the call which initiates the error 
+0

那麼,放置在數組中的'File'實例(您稱之爲'addMixin'方法)沒有'.prototype'屬性。你爲什麼期望這樣做? – Bergi

+1

[不要搞亂'Object.prototype'!](http://stackoverflow.com/q/13296340/1048572) – Bergi

+0

當你混合古典繼承和原型繼承時,你正在尋求麻煩。但是如果你真的想在腳下拍攝自己,請嘗試使用this.constructor.prototype。 – mpm

回答

2

內部addMixin方法this是指一個對象實例,在其上調用的方法。 實例沒有prototype屬性 - Function s。

我不完全確定,您正在嘗試做什麼:將mixin屬性添加到所有將來的實例或將它們添加到實例,所以我會爲您提供兩種變體。

對於所有的情況下,你需要使用的是一個constructor屬性,它返回一個函數,這是用來創建一個實例:

Object.prototype.addMixin = function (mixin) {  
    for (var prop in mixin) { 
     if (mixin.hasOwnProperty(prop)) { 
      this.constructor.prototype[prop] = mixin[prop]; 
     } 
    } 
}; 

對於一個特定的實例,使用括號標記上this

Object.prototype.addMixin = function (mixin) {  
    for (var prop in mixin) { 
     if (mixin.hasOwnProperty(prop)) { 
      this[prop] = mixin[prop]; 
     } 
    } 
}; 

當心mixin參數的特性,即是引用類型(例如object Objectobject Array

+0

是的,意在改變那個特定的實例。你的回答很有道理,這是我第一次正確地使用OOP JavaScript。 – user2700751

+0

如何將Mixin函數添加到Object.prototype中? Bergi不喜歡/推薦它。 – user2700751

+0

@ user2700751:我很好,但你需要使它不可枚舉(通過你已經知道的Object.defineProperty)。 – Bergi