DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> JavaScript是一門面向對象語言(一)
JavaScript是一門面向對象語言(一)
編輯:關於JavaScript     
簡介: JavaScript 函數式腳本語言特性以及其看似隨意的編寫風格,導致長期以來人們對這一門語言的誤解,即認為 JavaScript 不是一門面向對象的語言,或者只是部分具備一些面向對象的特征。本文將回歸面向對象本意,從對語言感悟的角度闡述為什麼 JavaScript 是一門徹底的面向對象的語言,以及如何正確地使用這一特性。

前言
當今 JavaScript 大行其道,各種應用對其依賴日深。web 程序員已逐漸習慣使用各種優秀的 JavaScript 框架快速開發 Web 應用,從而忽略了對原生 JavaScript 的學習和深入理解。所以,經常出現的情況是,很多做了多年 JS 開發的程序員對閉包、函數式編程、原型總是說不清道不明,即使使用了框架,其代碼組織也非常糟糕。這都是對原生 JavaScript 語言特性理解不夠的表現。要掌握好 JavaScript,首先一點是必須摒棄一些其他高級語言如 Java、C# 等類式面向對象思維的干擾,全面地從函數式語言的角度理解 JavaScript 原型式面向對象的特點。把握好這一點之後,才有可能進一步使用好這門語言。本文適合群體:使用過 JS 框架但對 JS 語言本質缺乏理解的程序員,具有 Java、C++ 等語言開發經驗,准備學習並使用 JavaScript 的程序員,以及一直對 JavaScript 是否面向對象模稜兩可,但希望知道真相的 JS 愛好者。

重新認識面向對象
為了說明 JavaScript 是一門徹底的面向對象的語言,首先有必要從面向對象的概念著手 , 探討一下面向對象中的幾個概念:
一切事物皆對象
對象具有封裝和繼承特性
對象與對象之間使用消息通信,各自存在信息隱藏
以這三點做為依據,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 指針的變化。正是這種特點更貼近 “萬物皆有所屬,宇宙乃萬物生存之根本”的自然觀點。在 程序清單 1中 window 便類似與宇宙的概念。

清單 1. 對象的上下文依賴

<script>
var str = "我是一個 String 對象 , 我聲明在這裡 , 但我不是獨立存在的!"
var obj = { des: "我是一個 Object 對象 , 我聲明在這裡,我也不是獨立存在的。" };
var fun = function() {
console.log( "我是一個 Function 對象!誰調用我,我屬於誰:", this );
};

obj.fun = fun;

console.log( this === window ); // 打印 true
console.log( window.str === str ); // 打印 true
console.log( window.obj === obj ); // 打印 true
console.log( window.fun === fun ); // 打印 true
fun(); // 打印 我是一個 Function 對象!誰調用我,我屬於誰:window
obj.fun(); // 打印 我是一個 Function 對象!誰調用我,我屬於誰:obj
fun.apply(str); // 打印 我是一個 Function 對象!誰調用我,我屬於誰:str
</script>

在接受了面向對象存在一種叫做基於原型實現的方式的事實之後,下面我們就可以來深入探討 ECMAScript 是如何依據這一方式構造自己的語言的。


最基本的面向對象
ECMAScript 是一門徹底的面向對象的編程語言(參考資源),JavaScript 是其中的一個變種 (variant)。它提供了 6 種基本數據類型,即 Boolean、Number、String、Null、Undefined、Object。為了實現面向對象,ECMAScript設計出了一種非常成功的數據結構 - JSON(JavaScript Object Notation), 這一經典結構已經可以脫離語言而成為一種廣泛應用的數據交互格式 (參考資源)。
應該說,具有基本數據類型和 JSON 構造語法的 ECMAScript 已經基本可以實現面向對象的編程了。開發者可以隨意地用 字面式聲明(literal notation)方式來構造一個對象,並對其不存在的屬性直接賦值,或者用 delete 將屬性刪除 ( 注:JS 中的 delete 關鍵字用於刪除對象屬性,經常被誤作為 C++ 中的 delete,而後者是用於釋放不再使用的對象 ),如 程序清單 2。

清單 2. 字面式 (literal notation) 對象聲明

var person = {
name: “張三”,
age: 26,
gender: “男”,
eat: function( stuff ) {
alert( “我在吃” + stuff );
}
};
person.height = 176;
delete person[ “age” ];

在實際開發過程中,大部分初學者或者對 JS 應用沒有太高要求的開發者也基本上只用到 ECMAScript 定義的這一部分內容,就能滿足基本的開發需求。然而,這樣的代碼復用性非常弱,與其他實現了繼承、派生、多態等等的類式面向對象的強類型語言比較起來顯得有些干癟,不能滿足復雜的 JS 應用開發。所以 ECMAScript 引入原型來解決對象繼承問題。

下一篇

http://www.ibm.com/developerworks/cn/web/1304_zengyz_jsoo/
原來標題:全面理解面向對象的 JavaScript
作者:曾 滢著
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved