2008-08-09 40 views
16

有幾種方法可以把JavaScript類般的行爲,最常見的似乎是基於這樣的原型:你用什麼樣式創建「班級」?

function Vector(x, y, x) { 
    this.x = x; 
    this.y = y; 
    this.z = z; 
    return this; 
} 

Vector.prototype.length = function() { return Math.sqrt(this.x * this.x ...); } 

和基於封閉的方法類似

function Vector(x, y, z) { 
    this.length = function() { return Math.sqrt(x * x + ...); } 
} 

由於各種原因後者速度更快,但我見過(並經常寫作)原型版本,並對其他人的做法感到好奇。

+0

我的測試表明,基於閉包的方法比較慢。你必須爲每個對象實例化一個單獨的閉包。原型方法與所有實例共享方法。 – 2011-01-20 20:08:21

回答

9

爲原型分配函數更好(對於公共方法),因爲該類的所有實例都將共享該方法的相同副本。如果像第二個示例中那樣在構造函數中分配函數,那麼每次創建新實例時,構造函數都會創建一個長度函數的新副本,並將其分配給該實例。

但是如果你每個副本都有它自己的拷貝,主要使用的是正在做即有機會獲得在構造函數中聲明,並通過關閉繼承私有變量私有/特權方法後者的技術是有用的機制。

道格拉斯克羅克福德有一個很好的summary

2

那麼,我真的沒有專家對此的意見。 我通常最終只使用基於閉包的方法,因爲它使代碼更容易管理。但是,我發現自己正在使用具有多行代碼的方法的原型。

2

此外,還可以選擇:

function Vector(x, y, z) { 
    function length() { 
    return Math.sqrt(x * x + ...); 
    } 
} 

這可能只是因爲例如兩個慢,但它看起來更象Java/C#和有點更加明確。

3

幸運的是我可以使用prototype.js,它提供了一些很好的包裝。所以,你可以這樣做:

var Person = Class.create({ 
    initialize: function(name) { 
     this.name = name; 
    }, 
    say: function(message) { 
     return this.name + ': ' + message; 
    } 
}); 

Prototype.js Documentation: Defining classes and inheritance

+0

我不認爲OP是要求隱藏細節的包裝。他想知道爲什麼你會選擇任一種方法,所以他可以權衡利益 – 2011-01-20 20:10:48

4

也有對象文學方法的原型:

var Vector = function(){}; 

Vector.prototype = { 
    init:function(x,y,z) { 
    this.x = x; 
    this.y = y; 
    this.z = z; 
    }, 
    length:function() { 
    return Math.sqrt(x * x + ...); 
    } 
}; 

var v1 = new Vector(); 
v1.init(1,2,3); 
+0

如果你從別的方面繼承,那麼你不能設置文字原型對象,這將覆蓋以前的原型 – 2011-01-20 20:08:51

1

我使用John Resig's library這是一個大風扇。輕量級的,直接的,如果你熟悉'慣常'的面向對象風格,你已經知道如何使用它。

1

JavaScript中沒有類。

但是有物體。你不需要一個類來在javascript中創建一個對象。它有constuctor功能,您可以用新的調用,例如:

var james = new Person(); 

您可以模擬類像行爲:

原型例如:

function Car (type) { 
    this.type = type; 
    this.color = "red"; 
} 

Car.prototype.getInfo = function() { 
    return this.color + ' ' + this.type + ' car'; 
}; 

對象字面例如

var car = { 
    type: "honda", 
    color: "red", 
    getInfo: function() { 
     return this.color + ' ' + this.type + ' car'; 
    } 
}