天天看點

《JavaScript設計模式與開發實踐》-面向對象的JavaScript

設計模式 面向對象

動态類型語言

程式設計語言按照資料類型大體分為:靜态類型語言和動态類型語言。

靜态類型語言在編譯時便已确定變量的類型,而動态類型語言的變量類型要到程式運作時,待變量被賦予某個值之後,才會具有某種類型。

在JavaScript中,當我們對一個變量指派時,顯然不需要考慮它的類型,是以JavaScript是一門典型的動态類型語言。

動态類型語言對變量類型的寬容給實際編碼帶來了很大的靈活性,由于無需進行類型檢測,我們可以嘗試調用任何對象的任意方法,而無需去考慮它原本是否被設計為擁有該方法。

這一切都建立在鴨子類型的概念上,即如果它走起來像鴨子,叫起來也是鴨子,那麼它就是鴨子。

var duck = {
   duckSinging: function() {
     printf('gagaga');
   }
 };
 var chicken = {
   duckSinging: function() {
     printf('gagaga');
   }
 };
 var choir = [];

 var joinChoir = function(animal) {
   if (animal && typeof animal.duckSinging === "function") {
     choir.push(animal);
     printf("恭喜加入合唱團");
     printf("合唱團已有人數" + choir.length);
   }
 }

 joinChoir(duck);
 joinChoir(chicken);
           

由此,實作了動态類型語言中的一個重要原則:面向接口程式設計,而不是面向實作程式設計。

多态

多态的實際含義是:同一操作作用域不同的對象上面,可以産生不同的解釋和不同的執行結果。

var makeSound = function(animal) {
   if (animal instanceof Duck) {
     printf('ggaga');
   } else if (animal instanceof chicken) {
     printf('gegege');
   }
 }

 var Duck = function() {};
 var chicken = function() {};

 makeSound(new Duck());
 makeSound(new chicken());
           

這段代碼确實實作了多态性,但是如何增加一隻動物,那麼makeSound函數也需要去改動,這顯然并不讓人滿意。

多态背後的思想是将“做什麼”和“誰去做及怎樣做”分離開來,也就是将“不變的事物”與“可能改變的事物”分離開來。

原型程式設計範型的一些規則

  • 所有的資料都是對象
  • 要得到一個對象,不是通過執行個體化類,而是找到一個對象作為原型并克隆它
  • 對象會記住它的原型
  • 如果對象無法響應某個請求,它會把這個請求委托給它自己的原型

事實上,JavaScript中的根對象是Object.prototype,它是一個空對象,我們在JavaScript中遇到的每個對象,實際上都是從它克隆而來的。Object.prototype就是它們的原型。

雖然我們經常用new去執行個體化一個函數,但是在JavaScript中,當使用new運算符來調用函數時,實際上也是先克隆Object.prototype對象,再進行一些其他額外的過程。

我們一直在讨論對象的原型,就JavaScript的真正實作來說,并不能說對象有原型,而應該說對象的構造器有原型。

實際上,雖然JavaScript的對象最初都是又Object.prototype對象克隆而來,但對象構造器的原型并不限于Object.prototype上,而是可以動态指向其他對象。這樣一來,當對象a需要借用對象b的能力時,可以有選擇性地把對象a的構造器的原型指向對象b,進而達到繼承的效果。

var A=function(){};
A.prototype={name:'sven'};

var B=function(){};
B.prototype.new A();

var b=new B();
console.log(b.name);//輸出:sven
           

轉載于:https://www.cnblogs.com/depsi/p/5077353.html

繼續閱讀