2016-11-09 82 views
0

在我當前的Web項目中,我正在處理多個JavaScript文件,每個文件都包含從其他類型繼承的類型定義。因此,在任何給定的文件,我可以有像...JavaScript繼承和提升

function Type(){ 
    ParentType.call(this); 
} 
Type.prototype = Object.create(ParentType.prototype); 
Type.prototype.constructor = Type; 

...用同樣宣佈在另一個文件中ParentType

function ParentType(){ 
    this.data = "";  
}  

由於與許多JavaScript文件工作中變得麻煩<head>標籤,我寫了一個bash腳本將文件連接成一個文件(稱爲master.js)。這樣,我可以鏈接HTML中的單個文件。

對於只有一個孩子的類型,無論我的文件串聯順序如何,原型鏈都是正確構建的。換句話說,這個片段...

function ParentType(){ 
    this.data = ""; 
} 

function Type(){ 
    ParentType.call(this); 
} 
Type.prototype = Object.create(ParentType.prototype); 
Type.prototype.constructor = Type; 

...行爲等同於這個片段:

function Type(){ 
    ParentType.call(this); 
} 
Type.prototype = Object.create(ParentType.prototype); 
Type.prototype.constructor = Type; 

function ParentType(){ 
    this.data = ""; 
} 

當我在任何情況下創造的Type一個實例,ParentType.prototype.isPrototypeOf(typeobj)返回true(其中typeobj是我的實例Type)。

function ParentType(){ 
    this.data = ""; 
} 

function Type(){ 
    ParentType.call(this); 
} 
Type.prototype = Object.create(ParentType.prototype); 
Type.prototype.constructor = Type; 

function ChildType(){ 
    Type.call(this); 
} 
ChildType.prototype = Object.create(Type.prototype); 
ChildType.prototype.constructor = ChildType; 

...否則,鏈條「:

然而,當我添加另一種類型的「原型鏈」的最後,只有當文件按順序連接起來,即工作休息」。我的猜測是,爲什麼在一個孩子的情況下這是可以接受的,因爲這兩種類型定義都被吊起來了,並且只有一組陳述擔心原型鏈。但對於多鏈接原型鏈,如果語句無序,則鏈無法正確連接。

所以我真正要問的是,有沒有一種方法可以在JavaScript中實現繼承,「工作」,而不管我的文件連接順序如何?我的第一個雖然是classextends的做事方式,但後來我才知道,即使class的定義也沒有掛起!

注:通過「工程」,所有我的意思是,當對任何其父母的原型檢查亞型繼承(所有的)父母的,isPrototypeOf返回true,對任何目標函數/值。

回答

0

對於多鏈路原型鏈,如果語句是無序,鏈未能正確地連接。

是的。在使用它創建ChildType.prototype之前,您需要設置Type.prototype。這不需要對函數聲明的提升做任何事情。

有沒有一種方法可以在JavaScript中實現「工作」繼承,而不管我的文件連接順序如何?

嗯,你可以可能使用Object.setPrototypeOf

function ChildType(){ 
    Type.call(this); 
} 
Object.setPrototypeOf(ChildType.prototype, Type.prototype); 

function Type(){ 
    ParentType.call(this); 
} 
Object.setPrototypeOf(Type.prototype, ParentType.prototype); 

function ParentType(){ 
    this.data = ""; 
} 

但是,你真的想避免這種方法,依靠吊裝像這是一個非常不好的做法,所以你真的應該修復你的連接腳本以使用正確的順序。或者使用一個模塊系統來爲你提供依賴關係。

我的第一個雖然是class和做事的方式extends,但後來我瞭解到,即使class定義不是紅旗!

That's a good thing。只要認爲它們純粹是糖 - 你總是需要按照正確的順序設置它們,遵循層次結構。

+0

+1回答實際問題,這幾乎是我所尋找的(「探索我的其他選項」)。似乎沒有好辦法避免提煉我的腳本,除非我想使用外部源。 – user1819699

0

功能掛起,所以它們可能出現故障,但連接原型的調用必須按順序進行。

如果它們出現故障,您的代碼將在託管後看起來如下所示。

function ParentType(){ 
    this.data = ""; 
} 

function Type(){ 
    ParentType.call(this); 
} 

function ChildType(){ 
    Type.call(this); 
} 
ChildType.prototype = Object.create(Type.prototype); 
ChildType.prototype.constructor = ChildType; 

Type.prototype = Object.create(ParentType.prototype); 
Type.prototype.constructor = Type; 

也就是說,要鏈接到ChildType.prototypeType.prototype,那麼你覆蓋Type.prototype到鏈它ParentType.prototype

沒有辦法使這項工作失序,JavaScript的繼承取決於那些被調用的代碼行。

+0

我已經知道了。我問的是,如果有一種方法來實現繼承的代碼順序無關緊要。 – user1819699

+1

如果你已經知道,爲什麼你的問題甚至提到託管? –

0

一種方法是爲每種類型聲明一個靜態初始化器。

但是,只有在執行運行時(通過Object.crate或通過賦值)纔有可能,因此我們又回到了開始階段。如果你的文件是按照隨機順序真正連接的,那麼你應該使用更復雜的機制和一些「工廠」函數,這些函數會在它們出現時創建類型,並將子類型「擱置」,直到它們的父代被創建。只是出於說明的目的

簡化的例子:

function factory(precondition, callback) 
{ 
    if(!this.registry) this.registy = []; 
    if(!precondition || this.registry[precondition]) 
     this.registry[callback()] = true; 
    else setTimeout(function(){factory(precondition, callback);}, 100); 
} 

factory('Type', function() 
{ 
    Window.ChildType = function(){} 
    return 'ChildType'; 
}); 

factory(null, function() 
{ 
    Window.Type= function(){} 
    return 'Type'; 
});