2013-02-21 71 views
0

UPDATE什麼是在JavaScript中啓用OOP的簡單方法?

自從我提出這個問題,大量的水已經下溪走了,我必須切換到使用模塊模式和CommonJS的文件格式+ Browserify並停止試圖讓JavaScript腳本更像是一個面向對象的語言。我接受了Javascript Prototypal Inheritance和Object.create,我的生活現在比以往更好!,是的,幾乎感覺就像我加入了new Religion,對不起religion ......對於我來說,再也沒有JS的「新」了。

問題的其餘的就是歷史...


我已經是與OOP玩弄於JavaScript的一段時間。

老實說,我的感覺是,大部分時間真正的OOP是不需要的。在OOP中我曾經用其他語言做過的事情,大部分時間都可以在javascript中用函數和閉包完成。

同樣爲了模仿OOP方法,有很多方法可以讓它通過手工或使用一個小型的庫發現。

我想嘗試一下OOP,但是我發現的所有解決方案在我看來都不那麼簡單,有些要求我添加一個init方法,或者在初始化期間他們正在對函數進行特殊檢查以瞭解是否他們需要被覆蓋。雖然這很聰明,但從簡單的Class創建一個對象似乎有點過分。

於是我想出了這個解決方案:

UPDATE:這個實驗,無意取代任何輝煌退出庫或生產

var Nexus = function() {}; // helper function to avoid create an instance of the child class 
Object._extend = function(child, parent) { 

    var base = Nexus.prototype = parent.prototype; 
    child.prototype = new Nexus(); 

    var cp = child.prototype; 
    cp.constructor = child; 
    child._parent = base; 
}; 




/* THIS THEN IS USED LIKE THIS */ 

var Person = function (name) { 
    this.name = name; 
    console.log('Person constructor'); 
}; 

$.extend(Person.prototype, { 
    walk : function() { 
    console.log(this.name + ' is Walking!!'); 
    } 

}); 

var Student = function() { 
    // call the base class constructor 
    Student._parent.constructor.apply(this, arguments); 
    console.log('Student Constructor'); 
} 

Object._extend(Student, Person); 

$.extend(Student.prototype, { 
    walk : function() { 
    console.log(this.name + ' walks like Student'); 
    //calling a parent method 
    Student._parent.walk.apply(this, arguments); 
    } 
}); 

var p = new Person('Jon Doe'); 
p.walk(); 
console.log(p instanceof Person) // true 

var s = new Student('Joan Doe'); 
s.walk(); 
console.log(s instanceof Person) // true 
console.log(s instanceof Student) // true 

正如你可以看到使用,這方法符合OOP的要求。

  1. 一個孩子obj是一個父類的實例,也還有子類
  2. 一個孩子obj的實例可以調用父類的方法來訪問覆蓋的方法。 (與CurrentClass._parent和BaseClass.prototype唯一的不同之處在於第二個需要類的使用者真正知道父類的名稱,這是我想避免的)。

  3. 創建構造函數必須簡單,在這種情況下...函數本身就是構造函數。不需要簡單的初始化方法...在實例化過程中被自動調用。

在方法的缺點我也跟着:

  1. 我需要一個虛擬類的Nexus(我真的不喜歡實例化基類的對象只得到繼承鏈正常工作... Nexus做的伎倆)
  2. 我沒有提供訪問重寫的方法,正確設置上下文。消費者可以使用呼叫或應用來更改上下文。

是否有額外的Nexus虛擬函數來創建正確的原型鏈是內存管理的一個問題?

我沒有時間做適當的測試,而且我的繼承鏈並不比3級更深。所以這裏的影響似乎非常小。

我可能正在使用一個庫,但它似乎非常簡單,直接做,並仍然在構造函數中,我沒有看到從初始化的額外init類的好處看到它的好處。

您認爲添加虛擬Nexus功能有什麼顯着的影響?

+1

在我看來,你對OOP for JavaScript的直觀感覺有些不恰當是正確的。 – Pointy 2013-02-21 22:27:00

+0

是的,我作爲一個實驗做得比實際使用更多。這就是我問的原因。感謝您的反饋 – 2013-02-21 22:29:25

+0

@Point和OP謝謝!最後,有些人不會認爲JavaScript是OOP,因爲它不是,它只是在玩範圍。如果您需要隱藏數據,請使用模塊模式,不要發瘋! – defaultNINJA 2013-02-21 22:30:08

回答

2

是否有額外的Nexus虛擬函數來創建正確的原型鏈是內存管理的問題?

不,你剛剛在內存中有一個(一個!)附加對象。將它移動到Object._extend函數中,它甚至會自動收集垃圾。

但是,而不是那Nexus事情你應該只使用Object.create。另見Understanding Crockford's Object.create shim

+0

感謝您的反饋,並明確地嘗試Object.create shim – 2013-02-21 22:42:12

+0

對於實驗,您不會需要填充它:-)只是鏈接,以幫助理解你的代碼爲什麼工作。另請參閱http://stackoverflow.com/q/4166616/1048572和http://stackoverflow.com/q/2709612/1048572 – Bergi 2013-02-21 22:45:16

+0

object.create是否剛創建一個新的對象?所以它不像是從預定義的類創建一個新的對象。無論如何,我很難說我需要超過3級的繼承。 – 2013-02-21 22:52:44

相關問題