重新認識面向對象
為了說明 JavaScript 是一門徹底的面向對象的語言,首先有必要從面向對象的概念著手 , 探討一下面向對象中的幾個概念:
一切事物皆對象
對象具有封裝和繼承特性
對象與對象之間使用消息通信,各自存在信息隱藏
實際上,JavaScript 語言是通過一種叫做原型(prototype)的方式來實現(xiàn)面向對象編程的。下面就來討論基于類的(class-based)面向對象和基于原型的 (prototype-based) 面向對象這兩種方式在構造客觀世界的方式上的差別。
使用函數(shù)構造器構造對象
除了字面式聲明(literal notation)方式之外,ECMAScript 允許通過構造器(constructor)創(chuàng)建對象。每個構造器實際上是一個函數(shù)(function) 對象, 該函數(shù)對象含有一個“prototype”屬性用于實現(xiàn)基于原型的繼承(prototype-based inheritance)和共享屬性(shared properties)。對象可以由“new 關鍵字 + 構造器調用”的方式來創(chuàng)建
徹底理解原型鏈 (prototype chain)
在 ECMAScript 中,每個由構造器創(chuàng)建的對象擁有一個指向構造器 prototype 屬性值的隱式引用(implicit reference),這個引用稱之為原型(prototype)。進一步,每個原型可以擁有指向自己原型的隱式引用(即該原型的原型),如此下去,這就是所謂的原型鏈(prototype chain)在具體的語言實現(xiàn)中,每個對象都有一個__proto__ 屬性來實現(xiàn)對原型的隱式引用
基于類的面向對象和基于原型的面向對象方式比較
在基于類的面向對象方式中,對象(object)依靠類(class)來產(chǎn)生。而在基于原型的面向對象方式中,對象(object)則是依靠構造器(constructor)利用原型(prototype)構造出來的。舉個客觀世界的例子來說明二種方式認知的差異。例如工廠造一輛車,一方面,工人必須參照一張工程圖紙,設計規(guī)定這輛車應該如何制造。這里的工程圖紙就好比是語言中的類 (class),而車就是按照這個類(class)制造出來的;另一方面,工人和機器 ( 相當于 constructor) 利用各種零部件如發(fā)動機,輪胎,方向盤 ( 相當于 prototype 的各個屬性 ) 將汽車構造出來。