首頁 web前端 js教程 JavaScript的物件導向程式設計基礎_基礎知識

JavaScript的物件導向程式設計基礎_基礎知識

May 16, 2016 pm 03:45 PM
javascript 物件導向

重新認識物件導向
為了說明 JavaScript 是一門徹底的物件導向的語言,首先有必要從物件導向的概念著手 , 探討一下物件導向中的幾個概念:

  1. 一切事物皆對象
  2. 物件具有封裝與繼承特性
  3. 物件與物件之間使用訊息通信,各自存在訊息隱藏

以這三點做為依據,C 是半物件導向半面向過程語言,因為,雖然他實作了類別的封裝、繼承和多態,但存在非物件性質的全域函數和變數。 Java、C# 是完全的物件導向語言,它們透過類別的形式組織函數和變量,使其無法脫離物件存在。但這裡函數本身就是一個過程,只是依附在某個類別上。

然而,物件導向只是一個概念或程式設計思想而已,它不應該依賴某個語言存在。例如 Java 採用物件導向思想建構其語言,它實作了類別、繼承、衍生、多型、介面等機制。但是這些機制,只是實現物件導向程式設計的一種手段,而非必須。換言之,語言可以根據其自身特性選擇合適的方式來實現物件導向。所以,由於大多數程式設計師首先學習或使用的是類似Java、C 等高階編譯型語言(Java 雖然是半編譯半解釋,但一般做為編譯型來講解),因而先入為主地接受了「類別」這個物件導向實作方式,從而在學習腳本語言的時候,習慣性地用類式物件導向語言中的概念來判斷該語言是否為物件導向語言,或者是否具備物件導向特性。這也是阻礙程式設計師深入學習並掌握 JavaScript 的重要原因之一。
實際上,JavaScript 語言是透過一種稱為 原型(prototype)的方式來實現物件導向程式設計的。以下就來討論 基於類別的(class-based)物件導向和 基於原型的 (prototype-based) 物件導向這兩種方式在建構客觀世界的方式上的差異。
基於類別的物件導向和基於原型的物件導向方式比較
在基於類別的物件導向方式中,物件(object)依靠 類別(class)來產生。而在基於原型的物件導向方式中,物件(object)則是依賴 構造器(constructor)利用 原型(prototype)建構出來的。舉個客觀世界的例子來說明二種方式認知的差異。例如工廠造一輛車,一方面,工人必須參考一張工程圖紙,設計規定這輛車應該如何製造。這裡的工程圖就好比是語言中的類別(class),而車子就是按照這個類別(class)製造出來的;另一方面,工人和機器( 相當於constructor) 利用各種零部件如發動機,輪胎,方向盤( 相當於prototype 的各個屬性) 將汽車構造出來。
事實上關於這兩種方式誰更為徹底地表達了物件導向的思想,目前仍有爭論。但筆者認為原型式物件導向是一種更徹底的物件導向方式,理由如下:
首先,客觀世界中的物件的產生都是其它實體物件建構的結果,而抽象的「圖紙」是不能產生「汽車」的,也就是說,類別是一個抽象概念而非實體,而物件的產生是一個實體的產生;
其次,按照一切事物皆對象這個最基本的物件導向的法則來看,類別(class) 本身並不是一個對象,然而原型方式中的建構器(constructor) 和原型(prototype) 本身也是其他物件透過原型方式構造出來的對象。
再次,在類別物件導向語言中,物件的狀態(state) 由物件實例(instance) 所持有,而物件的行為方法(method) 則由宣告物件的類別所持有,並且只有物件的結構和方法能夠被繼承;而在原型式物件導向語言中,物件的行為、狀態都屬於物件本身,並且能夠一起被繼承(參考資源),這也更貼近客觀實際。
最後,類別物件導向語言例如 Java,為了彌補無法使用過程導向語言中全域函數和變數的不便,允許在類別中宣告靜態 (static) 屬性和靜態方法。而實際上,客觀世界不存在所謂靜態概念,因為一切事物皆物件!而在原型式物件導向語言中,除內建物件 (build-in object) 外,不允許全域物件、方法或屬性的存在,也沒有靜態概念。所有語言元素 (primitive) 必須依賴物件存在。但由於函數式語言的特點,語言元素所依賴的物件是隨著執行時間 (runtime) 上下文 (context) 變化而變化的,具體體現在 this 指標的變化。正是這種特徵更貼近 「萬物皆有所屬,宇宙乃萬物生存之根本」的自然觀點。


JavaScript 物件導向基礎知識

雖然 JavaScript 本身是沒有類別的概念,但它仍然有物件導向的特性,雖然和一般常見的物件導向語言有所差異。

簡單的建立一個物件的方法如下:

function myObject() {

};

JavaScript 中创建对象的方法一般来说有两种:函数构造法和字面量法,上面这种属函数构造法。下面是一个字面量法的例子:

var myObject = {

};

登入後複製

如果僅僅需要一個對象,而不需要對象的其它實例的情況下,推薦用字面量法。如果需要物件的多個實例,則建議函數建構法。
定義屬性和方法

函數構造法:

function myObject() {
 this.iAm = 'an object';

 this.whatAmI = function() {
 console.log('I am ' + this.iAm);
 };
};

登入後複製

字面量法:

var myObject = {
 iAm : 'an object',

 whatAmI : function() {
 console.log('I am ' + this.iAm);
 }
};

登入後複製

以上兩種方法所建立的物件中,都有一個名為 “iAm” 的屬性,還有一個名為 “whatAmI” 的方法。屬性是物件中的變量,方法則是物件中的函數。

如何取得屬性及呼叫方法:

var w = myObject.iAm;

myObject.whatAmI();

登入後複製

呼叫方法的時候後面一定要加上括號,如果不加括號,那麼它只是傳回方法的參考而已。
兩種創建物件方法的區別

  •     函數構造法裡面定義屬性和方法的時候,都要用前綴 this,字面量法不需要。
  •     函數構造法給屬性和方法賦值的時候用的是 =,字面量法用的是 : 。
  •     若有多個屬性或方法,函數構造法裡面用 ; 隔開,字面量法用 , 隔開。

對於字面量法所建立的對象,可以直接用對象的參考呼叫其屬性或方法:

myObject.whatAmI();

登入後複製

而對於函式建構法而言,需要建立物件的實例,才能呼叫其屬性或方法:

var myNewObject = new myObject();
myNewObject.whatAmI();

登入後複製

使用建構子

現在再來迴歸一下之前的函數構造法:

function myObject() {
 this.iAm = 'an object';
 this.whatAmI = function() {
 console.log('I am ' + this.iAm);
 };
};

登入後複製

其實它看起來就是個函數,既然是函數,能不能傳參數給它呢?將程式碼再稍作修改:

function myObject(what) {
 this.iAm = what;
 this.whatAmI = function(language) {
 console.log('I am ' + this.iAm + ' of the ' + language + ' language');
 };
};

登入後複製

再將物件實例化,並傳入參數:

var myNewObject = new myObject('an object');
myNewObject.whatAmI('JavaScript');

登入後複製

程式最終輸出 I am an object of the JavaScript language。
兩種建立物件的方法,我該用哪一種?

對於字面量方法而言,因為它不需要實例化,所以如果修改了某物件的值,那麼這個物件的值就永久地被修改了,其它任何地方再訪問,都是修改後的值。而對於函數建構法而言,修改值的時候是修改其實例的值,它可以實例化 N 個物件出來,每個物件都可以擁有自己不同的值,而且互不干擾。比較以下幾段程式碼。

先看字面量法:

var myObjectLiteral = {
 myProperty : 'this is a property'
};

console.log(myObjectLiteral.myProperty); // log 'this is a property'

myObjectLiteral.myProperty = 'this is a new property';

console.log(myObjectLiteral.myProperty); // log 'this is a new property'

登入後複製

即便創建了一個新的變數指向這個對象,結果還是一樣的:

var myObjectLiteral = {
 myProperty : 'this is a property'
};

console.log(myObjectLiteral.myProperty); // log 'this is a property'

var sameObject = myObjectLiteral;

myObjectLiteral.myProperty = 'this is a new property';

console.log(sameObject.myProperty); // log 'this is a new property'

登入後複製

再看函數構造法:

// 用函数构造法
var myObjectConstructor = function() {
   this.myProperty = 'this is a property'
};

// 实例化一个对象
var constructorOne = new myObjectConstructor();

// 实例化第二个对象
var constructorTwo = new myObjectConstructor();

// 输出
console.log(constructorOne.myProperty); // log 'this is a property'

// 输出
console.log(constructorTwo.myProperty); // log 'this is a property'

和预期一样,两个对象的属性值是一样的。如果修个其中一个对象的值呢?

// 用函数构造法
var myObjectConstructor = function() {
 this.myProperty = 'this is a property';
};

// 实例化一个对象
var constructorOne = new myObjectConstructor();

// 修改对象的属性
constructorOne.myProperty = 'this is a new property';

// 实例化第二个对象
var constructorTwo = new myObjectConstructor();

// 输出
alert(constructorOne.myProperty); // log 'this is a new property'

// 输出
alert(constructorTwo.myProperty); // log 'this is a property'

登入後複製

可以看到,用函數構造法實例化出來的不同對象,相互是獨立的,可以各自擁有不同的值。所以說,到底用哪一種方法來創建對象,需取決於各自實際情況。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

探索Go語言中的物件導向編程 探索Go語言中的物件導向編程 Apr 04, 2024 am 10:39 AM

Go語言支援物件導向編程,透過型別定義和方法關聯實作。它不支援傳統繼承,而是透過組合實現。介面提供了類型間的一致性,允許定義抽象方法。實戰案例展示如何使用OOP管理客戶訊息,包括建立、取得、更新和刪除客戶操作。

Go語言的物件導向特性解析 Go語言的物件導向特性解析 Apr 04, 2024 am 11:18 AM

Go語言支援物件導向編程,透過struct定義對象,使用指標接收器定義方法,並透過介面實現多態。物件導向特性在Go語言中提供了程式碼重用、可維護性和封裝,但也存在缺乏傳統類別和繼承的概念以及方法簽章強制型別轉換的限制。

PHP高階特性:物件導向程式設計的最佳實踐 PHP高階特性:物件導向程式設計的最佳實踐 Jun 05, 2024 pm 09:39 PM

PHP中OOP最佳實務包括命名約定、介面與抽象類別、繼承與多型、依賴注入。實戰案例包括:使用倉庫模式管理數據,使用策略模式實現排序。

Golang中有類似類別的物件導向特性嗎? Golang中有類似類別的物件導向特性嗎? Mar 19, 2024 pm 02:51 PM

在Golang(Go語言)中並沒有傳統意義上的類別的概念,但它提供了一種稱為結構體的資料類型,透過結構體可以實現類似類別的物件導向特性。在本文中,我們將介紹如何使用結構體實現物件導向的特性,並提供具體的程式碼範例。結構體的定義和使用首先,讓我們來看看結構體的定義和使用方式。在Golang中,結構體可以透過type關鍵字定義,然後在需要的地方使用。結構體中可以包含屬

如何在JavaScript中取得HTTP狀態碼的簡單方法 如何在JavaScript中取得HTTP狀態碼的簡單方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP狀態碼取得方法簡介:在進行前端開發中,我們常常需要處理與後端介面的交互,而HTTP狀態碼就是其中非常重要的一部分。了解並取得HTTP狀態碼有助於我們更好地處理介面傳回的資料。本文將介紹使用JavaScript取得HTTP狀態碼的方法,並提供具體程式碼範例。一、什麼是HTTP狀態碼HTTP狀態碼是指當瀏覽器向伺服器發起請求時,服務

PHP物件導向程式設計的深入理解:物件導向程式設計的除錯技巧 PHP物件導向程式設計的深入理解:物件導向程式設計的除錯技巧 Jun 05, 2024 pm 08:50 PM

透過掌握追蹤物件狀態、設定斷點、追蹤異常和利用xdebug擴展,可以有效調試PHP物件導向程式碼。 1.追蹤物件狀態:使用var_dump()和print_r()檢視物件屬性和方法值。 2.設定斷點:在開發環境中設定斷點,偵錯器會在執行到達斷點時暫停,以便檢查物件狀態。 3.追蹤異常:使用try-catch區塊和getTraceAsString()取得異常發生時的堆疊追蹤和訊息。 4.利用偵錯器:xdebug_var_dump()函數可在程式碼執行過程中檢查變數的內容。

JavaScript和WebSocket:打造高效率的即時搜尋引擎 JavaScript和WebSocket:打造高效率的即時搜尋引擎 Dec 17, 2023 pm 10:13 PM

JavaScript和WebSocket:打造高效率的即時搜尋引擎引言:隨著網路的發展,使用者對即時搜尋引擎的要求也越來越高。傳統的搜尋引擎在進行搜尋時,使用者需要點擊搜尋按鈕後才能得到結果,這種方式無法滿足使用者對於即時搜尋結果的需求。因此,採用JavaScript和WebSocket技術來實現即時搜尋引擎成為了一個熱門的話題。本文將詳細介紹使用JavaScri

See all articles