2011-11-06 50 views
1

我有點理解Javascript和Java在面向對象方面的區別。我閱讀了Javascript書中的底部段落,但我不完全明白它的含義,能否進一步解釋並提供示例以顯示兩種語言之間的區別?OOP Javascript vs Java(或其他,比如PHP)

「在許多面向對象的編程語言中,可以定義一類對象,然後創建個別對象作爲該類的實例。」

謝謝!

回答

3

面向對象的javascript非常簡單。

您創建一個對象。

var Klass = { 
    method: function() { 

    }, 
    constructor: function() { 

    }, 
    ... 
}; 

然後你通過原型繼承創建對象的實例

// instantiate 
var o = Object.create(Klass); 
// initialize 
o.constructor(); 

這是經典的面向對象的不同,因爲任何物體可以在JavaScript中的「類」。而且只有一個繼承鏈,即原型鏈。

通常在經典的OO語言中,類將相互繼承,並且實例將具有單獨的繼承鏈。

同樣在經典的OO中,您有兩個對象,實際的類對象和實例的藍圖(即static)。這在JavaScript中不存在,因爲只有一個對象即藍圖。

免責聲明:Object.create是ES5,所以您需要爲舊版平臺es5-shim

+5

哦,親愛的,不要推你喜歡的最近發現的原型作爲類風格沒有至少一些免責聲明...... @在雷諾斯做什麼是由極少數人完成,並且是一些文章的結果在上個月內變得流行;你不會像這樣看到很多JavaScript代碼。 – Domenic

+0

@Domenic它幾乎是一回事。 'Klass.constructor.prototype === Klass' &&'Constructor.prototype.constructor ===構造函數'。這是一個個人風格的問題,我發現這更容易可讀和優雅,然後用構造函數'.prototype'和'new'四處遊蕩。實際上,我正在做的是鏡像es.next對象示例和es.next類,ES社區將遠離構造函數。除了「這不是我的風格選擇」之外,我所展示的結構有什麼問題嗎? – Raynos

+0

這根本不是一回事。這種風格通過這個構造函數將初始化和創建分離開來,這是一個實質性的區別,更重要的是,這種風格被這個星球上很少的人所使用。關於可讀性和優雅性的主觀意見被OP是否希望他的代碼能夠被沒有閱讀過Rauschmayer博客文章的人閱讀。 – Domenic

9

什麼大多數人做的是使用構造函數,像這樣:

function MyClass(a, b) { 
    // Private instance properties 
    var x = "secret"; 
    var y = "also secret"; 

    // Public instance properties 
    this.a = a; 
    this.b = b; 

    // "Privileged" methods; can access private and public properties 
    this.foo = function() { 
     return x + " " + this.a; 
    }; 
} 

// "Public" methods; cannot access private properties 
MyClass.prototype.bar = function() { 
    return this.a + " " + this.b; 
}; 

// Public shared properties; not recommended: 
MyClass.prototype.w = "stuff"; 

// Static methods 
MyClass.baz = function() { 
    return "i am useless"; 
}; 

你會再使用這個構造函數,像這樣:

var instance = new MyClass("hi", "Meen"); 

asssert.equal(instance.foo(), "secret hi"); 
assert.equal(instance.bar(), "hi Meen"); 
assert.equal(MyClass.baz(), "i am useless"); 

var also = new MyClass("hi", "Raynos"); 

instance.w = "more stuff"; 
assert.equal(also.w, "more stuff"); 

如果你想要做的繼承,會做類似的事情:

function Inherited(a) { 
    // apply parent constructor function 
    MyClass.call(this, a, "Domenic"); 
} 
Inherited.prototype = Object.create(MyClass.prototype); 

var inherited = new Inherited("hello there good chap"); 

assert.equal(inherited.a, "hello there good chap"); 
assert.equal(inherited.foo(), "secret hello there good chap"); 
assert.equal(inherited.bar(), "hello there good chap Domenic"); 
+1

您不必解釋他們僅僅是封閉中的局部變量並且推斷運行時成本,而是妨礙了執行原型OO的方式,而忽略了「私有」和「特權」。它們是兩個平行的結構,它們不能很好地協同工作。 – Raynos

+0

在JavaScript中使用OOP的經驗中,微優化從未如此重要。能夠擁有OOP的四個原則之一,即。封裝,更重要。 – Domenic

+0

在這種情況下,您不需要原型OO。你應該讓工廠改變'this'。另外請注意[封裝]由[維基百科的第二個定義](http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming))滿足。 – Raynos

3

In Jav您可以使用class關鍵字創建一個班級。類是其實例(對象)的藍圖。

例如

class AClass { // AClass is a class 
    AClass() { } //this is the constructor which will be used to create instances of this class 
} 

然後創建和類的實例:

AClass obj1 = new AClass(); // an instance of the class AClass 
AClass obj2 = new AClasss(); //another instance of the class AClass 

因此,Java中的每個對象是一些類的實例。而且你可以有許多不同的類實例,但是如果沒有充當他們藍圖的類,你就不會有任何對象。

而且,在類中,您可以定義成員變量和方法,這些成員變量和方法可以屬於類本身,它將被所有實例共享,或者屬於實例,在這種情況下,每個實例都有自己的副本。

在Javascript中我主要是創建對象如下:

var obj = { }; 

所以,我並不需要創建的任何類實際創建的對象。

+0

哈哈,你答案的簡單讓我發笑:)。 +1 – Domenic