首頁 > web前端 > js教程 > 主體

JavaScript物件導向程式設計入門教學_基礎知識

WBOY
發布: 2016-05-16 16:52:19
原創
1417 人瀏覽過

儘管物件導向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)。

物件導向程式設計可視為使用協作物件集合來進行軟體設計,這與傳統觀點相反,傳統觀點將程式視為函數集合,或簡化為電腦指令列表。在物件導向程式設計中,每個物件都具有以下能力:接收訊息、處理資料、以及傳送訊息給其他物件。每個物件都可以視為一個獨立的具有不同角色或責任的小機器。
物件導向程式設計旨在為程式設計提升更大的靈活性和可維護性,並在大規模軟體工程中廣泛流行。由於其非常重視模組化,因此物件導向程式碼旨在讓開發更簡單、稍後理解起來更容易,而且相對於較少採用模組化的程式設計方法,使得對於複雜情況及步驟的分析、編碼和理解更加直接。

專用術語

類別(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元件時) 、及其他幾種語言。

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() { }


function 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() {
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) {  .
    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) {  .
    alert('Person instantiated');
}
Person.prototype.sayHello = function() {
    alert('hello');
};
    alert('hello');
};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 person = new Personerson = 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'e

更多相關信息,請參閱

Function.callFunction.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!');
    alert('I am walking!');
}
} ;
Person.prototype.sayHello = function() {
    alert('hello');
};
//定義Student類別
function Student() {
// 定義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');
    alert('hi, I am a student');
}
// 加入sayGoodBye方法
Student.prototype.sayGoodBye = function() {
    alert('goodBye');
}
var student1 = new Student();
}
var student1 = new Student();
}var student1 = new Student();

Hello. );
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('>alert(' foo is a Function: ' (foo instanceof Function));

alert('foo.prototype is an Object: ' (foo.prototype instanceof Object));

多型



就像所有的方法和屬性被定義在原型屬性內部一樣,不同的類別可以定義具有相同名稱的方法;方法的作用域限於定義它們的類別之內。這僅當兩個類別之間沒有父子關係(當一個類別沒有從繼承鏈中的其他類別繼承時)時才為真。

提示 本文所提出的物件導向程式實作技術不僅適用於JavaScript,因為就如何進行物件導向程式設計而言,這是非常靈活的。 同樣,這裡展示的技術既沒有使用任何語言技巧(language hacks),也沒有模仿其他語言的對象理論實現。 在JavaScript中,還有其他更進階的物件導向程式設計的技術,但是那些內容已超出了這篇介紹文章的範圍。
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板