1. 程式人生 > >js 面向對象 繼承

js 面向對象 繼承

rop layer 原型 兩種方法 try 通用 undefine 傳參數 color

繼承方式有四種:

1、call

2、apply

3、prototype

4、for in

call 和 apply 的主要區別:

call 傳參數只能一個一個的傳,

apply 因為是用數組,所以可以用arguments 獲取所有的實參。當參數多時,就用apply更方便。

arguments = 返回參數集合

call 和 apply 繼承

已打飛機遊戲為例:

創建飛機時有很多重復的步驟

以創建玩家飛機 用call 繼承 和用applay 創建boss飛機為例:

/*父模板*/
/*x,y,節點,blood,speed
* move
* shoot XXX
* init
* */
 1   /*通用的父模板
*/ 2 function Plane(x,y){ 3 console.log("plane構造函數") 4 console.log(this); 5 this.x = x; 6 this.y = y; 7 this.imgNode = document.createElement("img") 8 this.imgsrc=""; 9 this.blood=5; 10 this.speed=10; 11 this.move=function(){ 12 console.log("Plane的move方法");
13 } 14 this.init=function(){} 15 this.init(); 16 }
/*1.call*/
    function PlayerPlane(px,py){
    console.log(this);    //new PlayerPlane()
     // call傳遞參數,參數依次寫上
    Plane.call(this,px,py); //寫在代碼第一行
//     重寫 ==》多態 同一個方法,不同的實現方式
    this.x=1000;
    this.move=function(){
    console.log(
"Player Plane 的move方法") } this.shoot=function(){} } var playerplane = new PlayerPlane(200,300); console.log(playerplane.hasOwnProperty("x")); //true console.log(playerplane.x) playerplane.move();
 /*2.apply*/

    function BossPlane(bx,by){
      console.log(arguments);   //參數數組
      Plane.apply(this,arguments);
      this.move=function(){
        console.log("Boss飛機的移動");
      }
    }

    var bossplane = new BossPlane(100,200);
    console.log(bossplane.x,bossplane.y);
    bossplane.move()

原型繼承

    /*通用的手機模板*/
    function Phone(name,price){
      this.phoneName = name;
      this.price = price;
      this.color="red";
      this.callPhone=function(){

      }
    }

    function IPhone(){
      this.color="blue";
      this.music=function(){
        console.log("聽音樂");
      }
      this.news=function(){
        console.log("看新聞");
      }
    }

    var iphone1 = new IPhone();
    console.log(iphone1.color);

    //原型鏈繼承
    IPhone.prototype = new Phone("蘋果",6000);
    var iphone2 = new IPhone();
    console.log(iphone2.color);

    console.log(iphone1.__proto__); //原本的Iphone.prototype, 空對象
    console.log(iphone2.__proto__); //new Phone()
    console.log(iphone1.__proto__===iphone2.__proto__); //false

    IPhone.prototype.newfunc=function(){
      console.log("新添加的功能");
    }
    iphone1.__proto__.newfunc2=function(){
      console.log("另外一個新添加的功能");
    }
//    iphone1.newfunc2();
//    iphone2.newfunc();
    console.log("color" in iphone2);    //true
    console.log(iphone2.hasOwnProperty("color"));   //false

區別與前兩種方法:

通過原型鏈繼承的屬性不是自己的,

只是存在於原型鏈上。
 
 Phone.country="中國";
//    var p = new Phone();
//    console.log(p.country)    //undefined 原型鏈上並沒有
//    console.log("country" in p) //false
    /*p = 實例化對象
    * Phone = 函數 --- 函數也是一個對象*/
//    console.log(Phone.country);   //只有Phone函數才能調用country

//    var iphone1 = new IPhone();
//    console.log(iphone1.country);

    IPhone.prototype = new Phone();
    var iphone2 = new IPhone();
    console.log(iphone2.country);   //undefined
    console.log(iphone2.color);


    IPhone.prototype = Phone;
    var iphone3 = new IPhone();
    console.log(iphone3.country); // 打印得出來了
    console.log(iphone3.color);  // undefined
    console.log(iphone3.__proto__.__proto__.__proto__)

//prototype 指向一個對象就行了,可以是自己創建的新對象。
    IPhone.prototype={
      newAttr1:"新屬性1",
      newAttr2:"新屬性2"
    }
    var iphone4 = new IPhone();
    console.log(iphone4.newAttr1);

js 面向對象 繼承