我在計算原型鏈如何設置給定以下代碼時遇到了一些問題。在通過Object.create創建的對象上設置原型
var Model = {
prototype: {
init: function(){},
log: function(){ console.log('instance method log was called') }
},
log: function(){ console.log('class method log was called') },
create: function() {
var object = Object.create(this);
object.parent = this;
object.prototype = object.fn = Object.create(this.prototype);
return object;
},
init: function() {
var instance = Object.create(this.prototype);
instance.parent = this;
instance.init.apply(instance, arguments);
return instance;
}
}
var User = Model.create();
User.log(); // 'class method log was called'
// create a new method after creation
Model.warn = function() { console.warn('warn was called') }
User.warn() // 'warn was called'
var user = User.init();
user.log(); // 'instance method log was called'
特別是此行讓我困惑的創建方法:
object.prototype = object.fn = Object.create(this.prototype);
我瞭解如何創建方法是創建一個新的對象是誰的原型點回模式,但倒數第二行似乎覆寫帶有新對象的原型(Model.prototype)。但是,似乎原始原型仍然完好無損,因爲即使在創建新對象後,我仍然可以向模型中添加方法,並且新對象仍然可以訪問它。
有人可以說明實際發生的情況嗎?
編輯 - 我應該指出,這個代碼來自的JavaScript的Web應用程序由O'Reilly
對於什麼讓你感到困惑,有點不清楚,但是也許你認爲''this''和'object'指的是'Model.create'中的同樣的東西。如果是這樣,他們不是。 'this'是對'Model'的引用,但'object'是對從Object.create(this)創建的新對象的引用。所以,當你做'object.prototype = ... whatever'時,你不會覆蓋'Model.prototype',但是你可以通過將'object'原型鏈中存在的'.prototype'屬性隱藏*一個屬性直接在'object'上。 – 2012-07-28 20:12:40
我明白'this'是Model和'object'是一個新對象,而讓我困惑的是最初Object.create(this)將新對象原型設置爲'Model',但後來幾行對象。原型重置爲Object.create(this.prototype)。這是我不明白的路線。對我來說,它看起來像object.prototype現在設置爲一個對象的原型設置爲Model.prototype(init和日誌功能),但返回的對象,而不是直接訪問模型上的方法。 – jhummel 2012-07-29 02:53:31
我想我看到了什麼讓你感到困惑。在'object'上設置的'.prototype'屬性與原型鏈本身無關。一旦你創建了一個對象,就不可能改變原型鏈。所以當一個值被寫入'object.prototype'時,它不會干涉'object'和'Model'之間的關係。設置'.prototype'屬性的唯一時間對原型鏈有影響,就是當你改變''時。原型'屬性的構造函數,然後只有將來的構造函數產生的對象纔會受到該變化的影響。 – 2012-07-29 03:22:31