第一部分 基礎知識
第一章 面向對象的Javascript
JavaScript 通過原型委托的方式來實現對象與對象之間的繼承赃承。在語言層也沒有提供對抽象類和接口的支持痒谴。
1.1 動態(tài)類型語言和鴨子類型
靜態(tài)類型語言在編譯時便確定變量的類型,動態(tài)類語言的變量類型要到程序運行時箱叁,待變量被賦予某個值后墅垮,才會具有某種類型。
JavaScript是一門動態(tài)類型語言耕漱。
動態(tài)類型語言對變量的寬容給實際編碼帶來了很大的靈活性算色。由于無需進行類型檢測,我們可以嘗試調用任何對象的任意方法螟够,而無需去考慮它原本是否被設計為擁有該方法灾梦。
這一切都是建立在鴨子類型(duck typing)的概念上。鴨子類型的通俗說法是:如果它走起來像鴨子齐鲤,叫起來也是鴨子斥废,那么它就是鴨子。
模擬鴨子故事的代碼
var duck = {
duckSinging: function(){
console.log('gagaga');
}
};
var chicken = {
duckSinging: function(){
console.log('gagaga');
}
};
var choir = [ ]; //合唱團
var joinChoir = function ( animal ){
if( animal && typeof animal.duckSinging === 'function'){
choir.push(animal);
console.log('恭喜加入合唱團');
console.log('合唱團已有成員數量:' + choir.length);
}
};
joinChoir( duck ); //恭喜加入合唱團
joinChoir( chicken ); //恭喜加入合唱團
對于加入合唱團的動物给郊,大臣們無需檢查它的類型牡肉,只需要保證他們擁有duckSinging方法即可。
1.2多態(tài)(polymorphism) 復數的形態(tài)
含義:同一操作作用于不同的對象上面淆九,可以產生不同的解釋和不同的執(zhí)行結果统锤。意思是,給不同的對象發(fā)送同一個消息的時候炭庙,這些對象會根據這個消息分別給出不同的反饋
1.2.1 一段“多態(tài)”的JavaScript代碼
var makeSound = function( animal ){
if( animal instanceof Duck ){
console.log('gagaga');
}else if ( animal instanceof Chicken ){
console.log('lololo');
}
};
var Duck = function(){};
var Chicken = function(){};
makeSound ( new Duck ); //gagaga
makeSound ( new Chicken ); //lololo
這段代碼如果要增加狗饲窿,則要改動makeSound函數,當動物越來越多焕蹄,makeSound有可能變成一個巨大的函數
1.2.2 對象的多態(tài)性
下面是改寫后的代碼逾雄,首先我們把不變的部分隔離出來,那就是所有的動物都會發(fā)出聲音:
var makeSound =function ( animal ){
animal.sound();
};
然后把可變的 部分各自封裝起來腻脏,我們剛才談到的多態(tài)性實際上指的是對象的多態(tài)性:
var Duck = function (){}
Duck.prototype.sound =function(){
console.log('gagaga');
};
var Chicken =function(){}
Chicken.prototype.sound=function(){
console.log('lololo');
};
makeSound( new Duck() ); //gagaga
makeSound( new Chicken ); //lololo
加一個狗的叫只需加一段代碼鸦泳,而不需要改動以前的makeSound函數
var Dog =function(){}
Dog.prototype.sound=function(){
console.log('wnwnwn');
};
makeSound( new Dog() ) //wnwnwn
1.2.3 類型檢查和多態(tài)
JavaScript是一門不必進行類型檢查的動態(tài)類型語言。
作者舉的java實例看不懂永品。
1.2.4 使用繼承得到多態(tài)效果
作者舉的java實例看不懂做鹰。
1.2.5JavaScript的多態(tài)
多態(tài)的思想實際上是把“做什么”和“誰去做”分離開,要實現這一點鼎姐,歸根結底先要消除類型之間的耦合關系钾麸。如果類型之間的耦合關系沒有被消除更振,那么我們在makeSound方法中指定了發(fā)出叫聲的對象是某個類型,它就不能被替換為另一個類型饭尝。在Java中肯腕,可以通過向上轉型來實現多態(tài)。而在JavaScript中則不需要芋肠。
1.2.6 多態(tài)在面向對象程序設計中的作用
在電影的拍攝現場乎芳,當導演喊出“action”時,主角開始背臺詞帖池,照明師負責打燈光,后面的群眾演員假裝中槍倒地吭净,道具師往鏡頭里撒上雪花睡汹。在得到同一個消息時,每個對象都知道自己應該做什么寂殉。如果不利用對象的多態(tài)性囚巴,而是用面向過程的方式來編寫這一段代碼,那么相當于在電影開始拍攝之后友扰,導演每次都要走到每個人的面前彤叉,確認它們的職業(yè)分工(類型),然后告訴他們要做什么村怪。如果映射到程序中秽浇,那么程序中將充斥著條件分支語句。
利用對象的多態(tài)性甚负,導演在發(fā)布消息時柬焕,就不必考慮各個對象接到消息后應該做什么。對象應該做什么并不是臨時決定的梭域,而是已經事先約定和排練完畢的斑举。每個對象應該做什么,已經成為了該對象的一個方法病涨,被安裝在對象的內部富玷,每個對象負責它們自己的行為。所以這些對象可以根據同一個消息既穆,有條不紊地分別進行各自的工作赎懦。