在原型上聲明屬性根本不是反模式。當我看到一個對象時,我認爲「這就是這種類型的原型對象對數據和方法的作用。」
其他人已經警告不要在原型中給屬性一個參考值,例如:Foo.prototype.bar = [];
---因爲數組和對象是引用類型。引用類型是不可變的,因此「類」的每個實例都指向相同的數組或對象。只需在原型中將它們設置爲null
,然後在構造函數中給它們一個值。
我總是在原型中包含所有屬性,其中一個非常明確的原因是:向其他程序員傳達哪些屬性可公開提供,以及它們的默認值是什麼,而不需要通過構造函數篩選出來。
如果您要創建需要文檔的共享庫,這將變得特別有用。
考慮這個例子:
/**
* class Point
*
* A simple X-Y coordinate class
*
* new Point(x, y)
* - x (Number): X coordinate
* - y (Number): Y coordinate
*
* Creates a new Point object
**/
function Point(x, y) {
/**
* Point#x -> Number
*
* The X or horizontal coordinate
**/
this.x = x;
/**
* Point#y -> Number
*
* The Y or vertical coordinate
**/
this.y = y;
}
Point.prototype = {
constructor: Point,
/**
* Point#isAbove(other) -> bool
* - other (Point): The point to compare this to
*
* Checks to see if this point is above another
**/
isAbove: function(other) {
return this.y > other.y;
}
};
(文檔格式:PDoc)
只是閱讀文檔這裏是一個有點尷尬,因爲有關x
和y
性質的信息嵌入在構造函數中。對比,與包括原型這些特性的「反模式」:
/**
* class Point
*
* A simple X-Y coordinate class
*
* new Point(x, y)
* - x (Number): X coordinate
* - y (Number): Y coordinate
*
* Creates a new Point object
**/
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype = {
/**
* Point#x -> Number
*
* The X or horizontal coordinate
**/
x: 0,
/**
* Point#y -> Number
*
* The Y or vertical coordinate
**/
y: 0,
constructor: Point,
/**
* Point#isAbove(other) -> bool
* - other (Point): The point to compare this to
*
* Checks to see if this point is above another
**/
isAbove: function(other) {
return this.y > other.y;
}
};
現在看看樣機給你的實際對象的快照,這是很容易在你的頭上來可視化,也更容易供作者撰寫文檔。構造函數也不會與文檔混雜在一起,並且堅持將對象帶入生活的業務。
該原型具有一切,並且是關於「原型」Point
對象對於方法和數據具有什麼樣的信息的標準來源。
我會爭辯說不是包括原型中的數據屬性是反模式。
它說「數據屬性」,我相信它是指變量。我不認爲它提到了向原型添加功能的任何事情。 – 2012-08-10 14:54:54
arxanas說什麼。確切的引用是:「一個類的主體只能包含方法,沒有數據屬性,具有數據屬性的原型通常被認爲是反模式,所以這只是一個最佳實踐。」換句話說,通過「數據屬性」,作者的意思是「不屬於方法/功能的屬性」。 – ruakh 2012-08-10 14:57:44
你的問題是基於一個誤解,不知道該怎麼做。我永遠不會記得看到數據被放置在原型上。我不能真正編輯你的問題在原型中有數據,因爲這不是我經常看到的*模式。 – Esailija 2012-08-10 14:58:22