[英]A few questions about how JavaScript works
我最近一直在深入研究JavaScript以完全理解語言,並且有一些嘮叨的問題,我似乎無法找到答案(特別是處理面向對象的編程)。
假設以下代碼:
function TestObject()
{
this.fA = function()
{
// do stuff
}
this.fB = testB;
function testB()
{
// do stuff
}
}
TestObject.prototype = {
fC : function
{
// do stuff
}
}
函數fA
和fB
什么區別? 他們的范圍和潛在能力是否完全相同? 它只是慣例還是技術上更好或更合適的一種方式?
如果在任何給定時間只有一個對象的實例,那么將原型中的函數添加到fC
是否值得? 這樣做有什么好處嗎? 原型只在處理對象或繼承的許多實例時才真正有用嗎?
從技術上來說,每次都按照我上面的方式或者調用TestObject.prototype.functionName = function(){}
方法向原型添加方法的“正確”方法是什么?
我希望盡可能保持我的JavaScript代碼干凈和可讀,但我也非常感興趣的是對象的正確約定在語言中。 我來自Java和PHP背景,我試圖不對JavaScript如何工作做任何假設,因為我知道它是基於原型的非常不同。
函數fA和fB之間有什么區別
在實踐中,沒有。 函數表達式(fA)和函數聲明(fB)之間的主要區別在於創建函數時(聲明的函數在執行任何代碼之前可用,而函數表達式在表達式實際執行之前不可用)。 您可能會偶然發現與函數表達式相關的各種怪癖。
在這個例子中,我使用函數表達式,只是因為聲明一個函數表達式,然后分配結果似乎有點抽象。 但這兩種方法都沒有“正確”或“錯誤”。
如果在任何給定時間只有一個對象的實例,那么將原型中的函數添加到fC中是否值得?
沒有。幾乎所有進行繼承的人都發現普通對象通常更簡單,因此“更好”。 原型繼承對於修補內置對象非常方便(例如,在缺少的情況下添加Array.prototype.each)。
從技術上講,在原型中添加方法的“正確”方法是什么......
沒有一個。 用一些其他對象替換默認原型似乎有點浪費,但是分配由文字創建的對象可能更整潔,更容易閱讀順序分配。 對於一個或兩個作業,我會使用:
Constructor.prototype.method = function(){…}
但是對於很多方法我會使用對象文字。 有些甚至使用經典的擴展功能,並做:
myLib.extend(Constructor.prototype, {
method: function(){…}
});
如果已經定義了一些方法,那么添加方法是有益的。
看看一些圖書館並決定你喜歡什么,一些混合搭配。 做任何適合特定情況的事情,通常只需要獲得足夠的代碼就可以看到相同的內容,然后無論您選擇何種模式,它都會看起來很整潔。
fA
和fB
實際上是相同的,這只是一個慣例問題。
如果只有一個對象的實例,我甚至不會使用構造函數,而只是一個對象文字,例如:
var o = {
fA: function () { ... },
fB: function () { ... },
fC: function () { ... }
};
至於將它添加到實例或原型中,如果你只有一個實例,那么實例比將它添加到原型更有效,但正如我所說,使用文字代替。
我避免在構造函數中聲明函數,因為構造函數的每次調用都將創建表示每個函數的新對象。 這些對象不是很大,如果創建了很多對象,它們往往會相加。 如果可以將函數移動到原型,那么這樣做會更有效。
至於添加到原型,我贊成
TestObject.prototype.functionName = function () { };
風格,但這是一個偏好的問題。 我喜歡上述內容,因為無論是擴展原型還是創建初始原型,它看起來都是一樣的。
我回答第一部分:沒有區別,當你聲明函數不是變量時,它的聲明在塊中上升,所以
...
func();
...
function func () { ... }
等於
var func = function () { ... };
...
func();
...
所以你的代碼
function TestObject () {
this.fA = function() { // do stuff };
this.fB = testB;
function testB() { // do stuff }
}
等於
function TestObject () {
var testB = function () { // do stuff };
this.fA = function () { // do stuff };
this.fB = testB;
}
還有關於JavaScript如何在低級別運行的任何明確的JavaScript樣式指南或文檔嗎?
該死的javascript程序員應該錯過“面向Web開發人員的專業JavaScript” 。 這本書很精彩,深入探討。 它解釋了對象,類仿真,函數,范圍等等。 它也是一個JS參考。
從技術上來說,每次都按照我上面的方式或者調用TestObject.prototype.functionName = function(){}的方式向原型添加方法的“正確”方法是什么?
至於定義類的方法,我建議看看各種JS MVC框架(如Spine.js,它是輕量級的)。 您不需要整個它們,只需要它們的類仿真庫 。 這樣做的主要原因是JS沒有類的概念,而是純粹由對象和原型組成。 另一方面,可以完美地模擬類(請不要模仿,因為它是缺少的東西)。 由於這需要程序員的一些規則,最好有一個類仿真庫來完成這項工作並使代碼更清晰。
程序員應該期望類仿真庫的標准方法是:
// define a new Class
var AClass = Class.create({
// Object members (aka prototype),
// usually an initialize() method is called if it is defined
// as the "constructor" function when a class object is created
}, {
// Static members
});
// create a child class that inherits methods and attributes from parent
var ChildClass = AClass.extend({
// Child object members
},{
// Child static members
});
AClass.include({
// Object amendments (aka mixin), methods and attributes
// to be injected to the class object
},{
// Statics amendments, methods and attributes to be
// injected as class static members
});
// check object type
var aObj = new AClass();
aObj instanceof AClass; // true
aObj instanceof ChildClass; // false
var cObj = new ChildClass();
cObj instanceof AClass; // true
cObj instanceof ChildClass; // true
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.