本文真沒啥難點,我就是為了檢驗我英語水平退化了沒哈哈雖然我英語本來就渣翻譯起來也像大白話。將原文看了一遍也碼完翻譯了一遍差不多一個小時,其中批註部分是自己的理解如有疏漏或誤解還請之處感激不盡吶,比如JavaScript中對於單例的理解感覺定義有些模糊啊。 翻譯自斯托揚·斯蒂凡諾夫的原文鏈接:http ...
本文真沒啥難點,我就是為了檢驗我英語水平退化了沒哈哈雖然我英語本來就渣翻譯起來也像大白話。將原文看了一遍也碼完翻譯了一遍差不多一個小時,其中批註部分是自己的理解如有疏漏或誤解還請指出感激不盡吶,比如JavaScript中對於單例的理解感覺定義有些模糊啊。
翻譯自斯托揚·斯蒂凡諾夫的原文鏈接:http://www.phpied.com/3-ways-to-define-a-javascript-class/
引言
當涉及到語法時JavaScript是一個非常靈活的面向對象語言。這篇文章你可以找到三種方式定義和實例化一個對象。即使你已經用了某個你喜歡的方式,下麵的介紹幫助你去瞭解一些別的方式有助於你閱讀別人的代碼。
需要註意的是在JavaScript中沒有類的概念,但是通過 Function 可以模擬類,JavaScript中基本一切事物皆對象,在繼承方面,對象繼承對象而不是類繼承類。
1.使用 function
這可能是最通用的一種方法了,定義一個JavaScript function然後通過 new 關鍵字創建一個實例對象,通過這個function, this 關鍵字來給這個實例對象添加屬性和方法。下麵是一個例子。
function Apple (type) { this.type = type; this.color = "red"; this.getInfo = getAppleInfo; } // anti-pattern!(反模式) keep reading... function getAppleInfo() { return this.color + ' ' + this.type + ' apple'; }
這個對象實例的創建需要用Apple構造器函數,添加一些屬性然後調用一些方法,請繼續看:
var apple = new Apple('macintosh'); apple.color = "reddish"; alert(apple.getInfo());
1.1.方法定義在內部
在上面例子中我們看到Apple"類"的getInfo方法分隔出來被定義為 function getAppleInfo() 。這樣看起來工作的很好,但有一個弊端——你可能會在最後定義許多類型這樣的functions,它們都在"全局命名空間"。這意味著當你用相同的名字創建另一個function(或者使用了其他的庫)會產生命名衝突。為了防止這種現象,你可以將方法定義在構造器函數內部,就像這樣:
function Apple (type){ this.type = type; this.color = "red"; this.getInfo = function() { return this.color + ' ' + this.type + ' apple'; } }
這種語法創建實例和之前的並沒什麼區別。
1.2.方法被添加在原型屬性上
1.1的方式中仍然存在弊端,在每一次創建新實例的時候 getInfo() 方法會被每次都添加到實例對象上。有時這可能不是你想要的,一個有效的方法添加 getInfo() 就是將其定義在構造函數的原型屬性上。
function Apple (type) { this.type = type; this.color = "red"; } Apple.prototype.getInfo = function() { return this.color + ' ' + this.type + ' apple'; };
可以與1.和1.1相同的方式使用。
2.使用對象自面量
在JavaScript中對象字面量是一個快速精簡的方式去定義一個對象實例或數組實例,為了創建一個空對象你可以:
var o = {};
來代替通用的方法:
var o = new Object();
創建數組實例你可以:
var a = [];
來代替:
var a = new Array();
這樣的方式你可以跳過類從而立即創建實例(object)。下麵仍用先前的例子描述,這次用對象字面量的語法:
var apple = { type: "macintosh", color: "red", getInfo: function () { return this.color + ' ' + this.type + ' apple'; } }
這種方式你不必通過類創建一個實例,因為這個實例對象已經存在了,你只需要使用它就好:
apple.color = "reddish";
alert(apple.getInfo());
這種實例有時被叫做單例,在一些典型的語言比如Java,單例意味著對於某個類任何時候你只能有一個單一的實例,你不能從相同的類中創建更多實例對象。但在JavaScript中這個概念是沒有意義的因為所有的對象都是從單例開始的(批註:JavaScript中最大的原生對象就是Object,它既是對象也是構造函數,它只有一個,其他原生對象Function,Array等也是,所以JavaScript實現的是單例繼承了單例?? ,任何時候都可以創建一個自面量對象)。
3.在函數中使用單例
第三種方式是前兩種方式的結合,你可以使用函數來定義一個單例對象,這是語法:
var apple = new function() { this.type = "macintosh"; this.color = "red"; this.getInfo = function () { return this.color + ' ' + this.type + ' apple'; } }
這定義和1.1非常相似,在使用實例對象上和2相似。
apple.color = "reddish";
alert(apple.getInfo());
new function(){...} 做了兩件事:定義了一個函數(匿名構造器)並使用 new 調用它。這可能看起來有點迷惑如果你之前沒怎麼用過的話,但是這是一個很好的選擇,當你真的需要一個構造函數而又只使用一次並且又不用給它賦名時。(批註:這種方式好像看起來好簡潔,因為給單例指定了類型,記得《高程》里給單例指定類型叫“增強的模塊模式”,對於此例的話用法如下:
var apple = function (){ var obj = new Apple(); return obj; }();
)
總結
通過上面三種方式創建實例對象,JavaScript是沒有類的定義的,真是個神奇的語言...