物件導向JavaScript入門——來自Mozilla的官網教程
儘管物件導向JavaScript與其他語言相比之下存在差異,並由此引發了一些爭論,但毋庸置疑,JavaScript具有強大的物件導向程式設計能力。本文先從介紹物件導向程式設計開始,然後回顧JavaScript物件模型,最後演示JavaScript中的物件導向程式設計概念。
目錄
- JavaScript回顧
- 物件導向程式設計
- 專用術語
- 基於原型的程式設計
- JavaScript物件導向程式設計
5.1. 核心物件
5.2. 自定義物件
5.2.1. 類
5.2.2. 物件(類例項)
5.2.3. 建構函式
5.2.4. 屬性(物件屬性)
5.2.5. 方法
5.2.6. 繼承
5.2.7. 封裝
5.2.8. 抽象
5.2.9. 多型 - 提示
- 參考文獻
儘管物件導向JavaScript與其他語言相比之下存在差異,並由此引發了一些爭論,但毋庸置疑,JavaScript具有強大的物件導向程式設計能力。
本文先從介紹物件導向程式設計開始,然後回顧JavaScript物件模型,最後演示JavaScript中的物件導向程式設計概念。
JavaScript回顧
如果你對諸如變數(variables)、型別(types)、函式(functions)、以及作用域(scope)等JavaScript概念覺得心裡沒底,那麼你可以閱讀重新介紹JavaScript中的這些主題。你還可以查閱JavaScript 1.5核心指南
物件導向程式設計
物件導向程式設計是一種程式設計正規化(paradigm),即使用抽象來建立基於真實世界的模型。它使用了幾種以前建立的正規化技術,包括模組化(modularity)、多型(polymorphism)、和封裝(encapsulation)。今天,許多流行的程式語言(比如Java、JavaScript、C#、C++、Python、PHP、Ruby、以及Objective-C)都支援物件導向程式設計(OOP)。
物件導向程式設計可視為使用協作物件集合來進行軟體設計,這與傳統觀點相反,傳統觀點把程式視為函式集合,或者簡化為計算機指令列表。在物件導向程式設計中,每個物件都具有以下能力:接收訊息、處理資料、以及給其他物件傳送訊息。每個物件都可以視為一個獨立的具有不同角色或責任的小機器。
物件導向程式設計旨在為程式設計提升更大的靈活性和可維護性,並在大規模軟體工程中廣泛流行。由於其非常重視模組化,因此物件導向程式碼旨在讓開發更簡單、稍後理解起來更容易,而且相對於較少採用模組化的程式設計方法,使得對於複雜情況及步驟的分析、編碼和理解更加直接。[2]
專用術語
類(Class)
~ 定義物件的特徵(characteristics)。
物件(Object)
~ 類的例項(Instance)。
屬性(Property)
~ 某一物件特徵(characteristic),例如顏色。
方法(Method)
~ 某種物件能力,例如行走。
建構函式(Constructor)
~ 例項化(instantiation)時所呼叫的方法。
繼承(Inheritance)
~ 一個類可以繼承來自另一個類的特徵。
封裝(Encapsulation)
~ 一個類只定義該物件的特徵,一個方法只定義該方法如何執行。
抽象(Abstraction)
~ 將某一物件的複雜繼承、方法、屬性結合在一起,而且必須能夠模擬某一現實模型。
多型(Polymorphism)
~ 不同類可能會定義相同的方法或屬性。
對於物件導向程式設計的進一步描述,參閱維基百科的物件導向程式設計詞條。
基於原型的程式設計
基於原型的程式設計(Prototype-based programming)是一種物件導向程式設計風格,其中類(classes)並不存在,並且行為重用(在基於類的語言中稱為繼承)是通過粉飾充當原型的現存物件來完成的。這種模式也稱為無類的(class-less)、面向原型的(prototype-oriented)、或基於例項(instance-based)的程式設計。
關於基於原型語言的最初(且非常規範的)示例就是由David Ungar和Randall Smith開發的Self程式語言。然而,這種無類程式設計風格最近越來越受歡迎,並且已被一些程式語言採用,例如avaScript、Cecil、NewtonScript、Io、MOO、REBOL、Kevo、Squeak(當使用Viewer框架來操縱Morphic元件時)、及其他幾種語言。[2]
JavaScript物件導向程式設計
核心物件(Core Objects)
JavaScript有幾個包含在其核心中的物件;例如,Math、Object、Array、以及String等物件。下面的示例演示瞭如何使用Math物件的random()
方法獲取隨機數。
alert(Math.random());
提示:本例和所有其他示例都假設已在全域性範圍內定義了函式名
alert
(正如包含在web瀏覽器中的alert一樣)。alert
函式實際上不是JavaScript本身的一部分。
JavaScript核心物件列表,參閱JavaScript 1.5核心參考:全域性物件(Global Objects)。
JavaScript中的每個物件都是一個Object
物件的例項,並因此繼承其所有屬性和方法。
自定義物件(Custom Objects)
類(The Class)
JavaScript是基於原型的語言,其中不包含可在如 C++或Java中找到的類宣告(class statement)。有時這會讓一些習慣於具有類宣告語言(languages with a class statement)的程式設計師感到困惑。不過,JavaScript用函式(functions)作為類。定義一個類簡單到就是定義一個函式。在下例中,我們定義了名為Person
(人)的新類。
function Person() { }
物件(類例項)(The Object (Class Instance))
要建立obj
物件的一個新例項,我們使用語句new obj
,同時將結果(其型別是obj
)賦給某個變數(variable),以便稍後訪問。
在下例中,我們首先定義名為Person
的類,然後建立兩個例項(person1
和person2
)。
function Person() { }
var person1 = new Person();
var person2 = new Person();
還可參閱新的例項化替代方法Object.create。
建構函式(The Constructor)
當例項化時(建立物件例項的瞬間)是會呼叫建構函式。建構函式是類的一個方法。而在JavaScript中,會函式(function)作為作為該物件的建構函式;因此,也就無需顯式定義一個建構函式方法。類中宣告的每個行為在例項化時都會執行。
建構函式用於設定物件屬性或呼叫方法為使用該物件做準備。本文稍後會介紹,通過使用一種不同的語法來新增類方法及其定義 。
在下例中,當例項化Person
時,Person
類的建構函式會顯示一個警告框。
function Person() {
alert('Person instantiated');
}
var person1 = new Person();
var person2 = new Person();
屬性(物件屬性)(The Property (object attribute))
屬性是包含在類中的變數;每個物件例項都有這些屬性。屬性應設定在類(函式)的原型(prototype)屬性中,以便繼承正常工作。
在類中操作屬性是通過this
關鍵字實現的,this
引用當前物件。在類外部訪問(讀或寫)某個屬性要通過以下語法:InstanceName.Property
;這與C++、Java、以及其他一些語言所用語法相同。(在類內部使用this.Property
的語法來獲取或設定屬性值)。
在下例中,我們為Person
類定義gender
(性別)屬性,然後在初始化時定義該屬性。
function Person(gender) {
this.gender = gender;
alert('Person instantiated');
}
var person1 = new Person('Male'); // Male: 男
var person2 = new Person('Female'); // Female: 女
//顯示person1的性別
alert('person1 is a ' + person1.gender); // person1 is a Male
方法(The methods)
方法遵循與屬性相同的邏輯;區別在於它們是函式而且被定義為函式。呼叫方法與訪問屬性相似,不過你要在方法名末尾新增()
,可能會有引數(arguments)。定義一個方法,就是為該類prototype
屬性上的某個命名屬性指定一個函式;函式被分配到的那個名稱就是在物件上呼叫該方法的名稱。
在下例中,我們為Person
類定義並使用sayHello()
方法。
function Person(gender) {
this.gender = gender;
alert('Person instantiated');
}
Person.prototype.sayHello = function()
{
alert ('hello');
};
var person1 = new Person('Male');
var person2 = new Person('Female');
// 呼叫Person的sayHello方法。
person1.sayHello(); // hello
在JavaScript中,方法是作為屬性被繫結到某個類/物件的普通函式物件,這意味著,可以“脫離上下文(out of the context)”來呼叫它們。考慮如下示例程式碼:
function Person(gender) {
this.gender = gender;
}
Person.prototype.sayGender = function()
{
alert(this.gender);
};
var person1 = new Person('Male');
var genderTeller = person1.sayGender;
person1.sayGender(); // alerts 'Male'
genderTeller(); // alerts undefined
alert(genderTeller === person1.sayGender); // alerts true
alert(genderTeller === Person.prototype.sayGender); // alerts true
此示例一次演示了多個概念。這表明,在JavaScript中沒有“基於物件的方法(per-object methods)”,因為該方法的所有引用都指向完全相同的函式,即我們起初在原型上定義的那個函式。當某個函式被作為方法(或確切地說是屬性)呼叫時,JavaScript會將當前的“物件上下文(object context)”“繫結”到特定的“this”變數。這與呼叫該函式物件的“call”方法等效,如下所示:
genderTeller.call(person1); //alerts 'Male'
更多相關資訊,請參閱Function.call和Function.apply
繼承(Inheritance)
繼承是一種方法,用於建立作為一個或多個類專用版本的類。(JavaScript僅支援單類繼承)。這個專用類通常被稱為子類(child),而其他類通常被稱為父類(parent)。在JavaScript中,你要完成繼承,需將父類的例項賦給子類,然後將子類特化(specializing)。
提示:由於JavaScript不檢測的子類的
prototype.constructor
(原型的建構函式),參閱Core JavaScript 1.5核心參考:Global Objects:Object:prototype屬性,因此我們必須手動指定該值。
在下例中,我們定義Student
類作為Person
的子類。然後我們重新定義sayHello()
方法,並新增sayGoodBye()
方法。
// 定義Person類
function Person() {}
Person.prototype.walk = function(){
alert ('I am walking!');
};
Person.prototype.sayHello = function(){
alert ('hello');
};
// 定義Student類
function Student() {
// 呼叫父類建構函式
Person.call(this);
}
// 繼承Person
Student.prototype = new Person();
// 修正建構函式指標,由於它指向Person
Student.prototype.constructor = Student;
// 替換sayHello方法
Student.prototype.sayHello = function(){
alert('hi, I am a student');
}
// 新增sayGoodBye方法
Student.prototype.sayGoodBye = function(){
alert('goodBye');
}
var student1 = new Student();
student1.sayHello();
student1.walk();
student1.sayGoodBye();
// 檢驗繼承
alert(student1 instanceof Person); // true
alert(student1 instanceof Student); // true
封裝
在上例中,Student
無須知曉Person
類的walk()
方法是如何實現的,但仍可使用該方法;Student
類無須顯式定義該方法,除非我們想改變它。這稱為封裝(encapsulation),這樣每個類繼承其父類的方法,並且只需定義它所希望改變的東西。
抽象
抽象是一種機制(mechanism),允許對處理中的問題的當前部分進行建模。這可以通過繼承(特化)或組合(composition)來實現。JavaScript通過繼承實現特化(specialization),通過讓類例項成為其他物件的屬性值實現組合。
JavaScript的Function類繼承自Object類(這說明模型的特化),並且Function.prototype屬性是Object的例項(這說明了組合)。
var foo = function(){};
alert( 'foo is a Function: ' + (foo instanceof Function) );
alert( 'foo.prototype is an Object: ' + (foo.prototype instanceof Object) );
多型
就像所有的方法和屬性被定義在原型屬性內部一樣,不同的類可以定義具有相同名稱的方法;方法的作用域限於定義它們的類之內。這僅當兩個類之間沒有父子關係(當一個類沒有從繼承鏈中的其他類繼承時)時才為真。
提示
本文中所提出的物件導向程式設計實現技術不僅適用於JavaScript,因為就如何進行物件導向程式設計而言,這是非常靈活的。
同樣,這裡展示的技術既沒有使用任何語言技巧(language hacks),也沒有模仿其他語言的物件理論實現。
在JavaScript中,還有其他更高階的物件導向程式設計的技術,但是那些內容已超出了這篇介紹性文章的範圍。
參考文獻
- Mozilla。“JavaScript 1.5核心指南”, http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide
- 維基百科。“物件導向程式設計”,http://en.wikipedia.org/wiki/Object-oriented_programming
原始文件資訊
- 作者:Fernando Trasviña Email: f_trasvina at hotmail dot com
- 版權資訊:© 1998-2005由mozilla.org個人貢獻者所有;所提供內容採用知識共享許可協議(Creative Commons license)進行許可。
簡體中文版譯文資訊
- 譯者(簡體中文):高翌翔 Email: yixianggao at 126 dot com
- 版權資訊:
本作品採用知識共享署名-相同方式共享 2.5 中國大陸許可協議進行許可。
相關文章
- Java入門教程八(物件導向)Java物件
- 全網最適合入門的物件導向程式設計教程:00 物件導向設計方法導論物件程式設計
- 全網最適合入門的物件導向程式設計教程:01 物件導向程式設計的基本概念物件程式設計
- python-物件導向入門Python物件
- JavaScript 物件導向JavaScript物件
- C#快速入門教程(1)——物件導向程式設計C#物件程式設計
- 更多物件導向的JavaScript物件JavaScript
- JavaScript 的物件導向(OO)JavaScript物件
- 【3】python入門-物件導向-2Python物件
- 從入門到入獄------物件導向(二)物件
- 好程式設計師前端教程-javascript的物件導向程式設計師前端JavaScript物件
- Python入門教程100天:Day09-物件導向進階Python物件
- JavaScript物件導向—物件的建立和操作JavaScript物件
- PHP 物件導向 (八)類的自動載入PHP物件
- JavaScript7:物件導向JavaScript物件
- 【讀】JavaScript之物件導向JavaScript物件
- JavaScript 物件導向初步理解JavaScript物件
- 物件導向程式設計入門 - Janos Pasztor物件程式設計
- javascript:物件導向的程式設計JavaScript物件程式設計
- 《JavaScript物件導向精要》之六:物件模式JavaScript物件模式
- 《JavaScript物件導向精要》之三:理解物件JavaScript物件
- 1.16 JavaScript7:物件導向JavaScript物件
- 《JavaScript物件導向精要》系列文章JavaScript物件
- JavaScript物件導向詳解(原理)JavaScript物件
- JavaScript 物件導向實戰思想JavaScript物件
- Javascript物件導向與繼承JavaScript物件繼承
- 全網最適合入門的物件導向程式設計教程:60 Python物件導向綜合例項-感測器資料實時繪圖器物件程式設計Python繪圖
- 全網最適合入門的物件導向程式設計教程:23 類和物件的Python實現-丟擲異常物件程式設計Python
- 全網最適合入門的物件導向程式設計教程:02 類和物件的Python實現-使用Python建立類物件程式設計Python
- Go 語言極速入門4 - 物件導向Go物件
- JavaScript物件導向—繼承的實現JavaScript物件繼承
- Python入門教程100天:Day08-物件導向程式設計基礎Python物件程式設計
- JavaScript入門-物件JavaScript物件
- JavaScript高階:JavaScript物件導向,JavaScript內建物件,JavaScript BOM,JavaScript封裝JavaScript物件封裝
- 物件導向-物件導向思想物件
- JavaScript物件導向之一(封裝)JavaScript物件封裝
- Javascript 物件導向程式設計(一)JavaScript物件程式設計
- Javascript 物件導向程式設計(二)JavaScript物件程式設計
- Javascript 物件導向程式設計(三)JavaScript物件程式設計