有關js模式的重要回答

Function.prototype.method =  function  (name, func) { //在Function的原型上增長一個函數叫作「method」。該方法會在「類」的原型上增長指定函數名的函數。
     if  (! this .prototype[name]) {
         this .prototype[name] = func;
     }
};    
Object.method( 'superior' function  (name) { //增長一個超級方法。該方法保存它從原型上繼承來方法。用來模擬面向對象中的super關鍵字。
     var  that =  this ,
         method = that[name];
     return  function  (  ) {
         return  method.apply(that, arguments);
     };
});
var  mammal =  function  (spec) { //定義一個哺乳動物類型。
     var  that = {};
     that.get_name =  function  (  ) { //獲取動物名字。
         return  spec.name;
     };
     that.says =  function  (  ) { //動物打招呼的方法。
         return  spec.saying ||  '' ;
     };
     return  that;
};
//var myMammal = mammal({name: 'Herb'});//建立一個哺乳動物的實例。
var  cat =  function  (spec) { //定義一個「貓」的類型。
     spec.saying = spec.saying ||  'meow' ; //爲這個類型指定一個「叫聲」,這裏是「喵」
     var  that = mammal(spec); //建立一個哺乳動物實例。
     that.purr =  function  (n) { //爲這個哺乳動物建立一個貓的咕嚕咕嚕聲音的方法「purr」
         var  i, s =  '' ;
         for  (i = 0; i < n; i += 1) {
             if  (s) {
                 s +=  '-' ;
             }
             s +=  'r' ;
         }
         return  s;
     };
     that.get_name =  function  (  ) { //獲取「貓」的名字。貓的叫聲(meow) + 貓的名字 + 貓的叫聲(meow)
         return  that.says(  ) +  ' '  + spec.name +
                 ' '  + that.says(  );
     }
     return  that;
};
var  myCat = cat({name:  'Henrietta' }); //建立一隻貓的實例。名字叫Henrietta
var  coolcat =  function  (spec) { //建立一個「酷貓」的類型
     var  that = cat(spec), //建立一隻普通貓。
         super_get_name = that.superior( 'get_name' ); //保存普通貓的「獲取名字」的方法。
     that.get_name =  function  (n) { //酷貓有本身的「獲取名字」的方法,「like」 + 普通貓的「獲取名字方法」 + 「baby」
         return  'like '  + super_get_name(  ) +  ' baby' ;
     };
     return  that;
};
 
var  myCoolCat = coolcat({name:  'Bix' }); //建立一隻酷貓。
var  name = myCoolCat.get_name(  ); //酷貓的名字是like meow Bix meow baby
//        'like meow Bix meow baby'

 

上面採用prototype(原型擴展)的方式來實現「類」的繼承,如,酷貓 > 繼承 > 貓 > 繼承 > 哺乳動物。javascript

 

而下面採用了另一種思路:使用工廠模式來建立對象,不是經過複用原型。而是拆分零部件。每一個部件都是可拆卸,可組裝的方式,來達到另外一種代碼複用的效果。java

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function  createCar(numberOfDoors){ //造車廠,指定門的數量,並製造一輛汽車。
   var  numberOfWheels = 4; //輪子的數量是4.
   function  describe(){ //描述一下車輛。
     return  "I have "  + numberOfWheels +  " wheels and "  + numberOfDoors +  " doors." ;
   }
   return  { //返回製造完成的汽車。
     describe: describe
   };
}
function  createOdometer(){ //加工車載里程計。
   var  mileage = 0;
   function  increment(numberOfMiles){ mileage += numberOfMiles;} //里程計跑表的方法
   function  report(){  return  mileage; } //報告當前的里程數
   return  { //返回製造完成的里程計
     increment: increment,
     report: report
   }
}
 
function  createCarWithOdometer(numberOfDoors){ //製造帶有里程計的汽車
   var  odometer = createOdometer(); //製造一個里程計
   var  car = createCar(numberOfDoors); //製造一輛車
   car.drive =  function (numberOfMiles){ //將里程計安裝到汽車上,當汽車行駛的過程當中,調用里程計的跑表方法。
     odometer.increment(numberOfMiles);
   }
   car.mileage =  function (){ //報告汽車的里程,經過已安裝的里程計的報告方法,獲取里程。
     return  "car has driven "  + odometer.report() +  " miles" ;
   }
   return  car; //返回製造並組裝完畢的汽車。
}
 
var  twoFn=createCarWithOdometer(100); //創造一輛帶有100個門的汽車(固然不可能。。Σ( ° △ °|||)︴)
 
console.log(twoFn);

 

上述兩種方式,體現了javascript的精妙之處。app

在面嚮對象語言中:dom

採用了類繼承的方式,實現代碼複用。函數

 

在javascript中,並無真正的類。而是用「function」來表明一種類型,學習

好比:this

1
function  Person(){};

咱們能夠認爲,Person就是所謂的javascript中的「類」的概念。咱們能夠這樣spa

1
2
3
var  p =  new  Person();
alert(p  instanceof  Person); //結果是true,由於p就是Person類型的一個實例。
alert(p  instanceof  Object); //結果也是true,由於全部實例終歸都是Object。

而每一個類型是若是擴展本身的新方法的呢?就是經過類型的prototype這個屬性。prototype

只有function纔有prototype屬性。code

 

好比:

1
2
3
4
5
6
function  Person(){}
Person.prototype.say =  function (){alert( 'hello' );}; //人這種類型有打招呼的方法
var  p1 =  new  Person();
var  p2 =  new  Person();
p1.say(); //hello
p2.say(); //hello

 

這樣,全部實例就均可以用打招呼的方法了。

當咱們建立一個新的類型「男人」。想要繼承Person的話。就像下面這樣:

 

1
2
3
4
5
6
7
8
9
10
11
function  Man(){}
 
var  proto = Man.prototype =  new  Person(); //男人也是人啊,男人的原型就是以一個普通人爲標準來參考的,因此咱們建立一我的類,賦值給男人,讓男人來學習,參考人的特性。
 
proto.fight =  function (){ //男人比起人來,脾氣大,所以有個打架的方法。
     alert( 'I\'ll kick your ass!!' );
}
 
var  m =  new  Man();
m.say(); //hello
m.fight(); //I'll kick your ass.這就是傳說中的一句話說不上來就開打。。。

 

原型繼承的核心就是這樣的。

 

而另一種思路就是工廠模式。

小汽車廠

輪子廠

里程計廠

卡車廠

 

小汽車廠須要輪子和里程計,分別向「輪子廠」和「里程計廠」要來了兩個現成的產品,直接安裝好,就完成了一輛小汽車。

 

卡車長也是同樣的。因此這種方式也是一種很好的代碼結構。

相關文章
相關標籤/搜索