Javascript面向對象與原型

面向對象與原型

  • 原型的普通創建方式
function Box(){}              // 構造函數
Box.prototype.name='Tayle';      
Box.prototype.age='25';
Box.prototype.run=function(){
return this.name+this.age+'運行中......';
};
  • 使用字面量的方式創建原型
function Box(){}
Box.prototype={
    name:'tayler',
    age:'25',
    run:function{
    return this.name+this.age+'運行中......';
       }
   }
var box1= new Box();
box1.name='Jack';
alert(box1.name);    //Jack      
delete box1.name;                 //刪除實例中的屬性
delete Box.prototype.name;           //刪除原型中的屬性
Box.prototype.name='KKK';        //覆蓋原型中的屬性
alert(box1.name) ;                               //KKK  

原型的執行流程:
 1.先瀏覽構造函數裏面屬性或者方法,如果有,立即返回;
 2.如果構造函數裏面沒有,就去它的原型裏面找,如果有,就返回。
  • 原型重寫
function Box () {}
Box.prototype={
  constructor:Box,   //強制指向Box
  name:'Lee',
  age:'22',
  run:function () {
    return this.name+this.age+'運行中.....';
  }
};

//重寫原型對象
Box.prototype={
  age:'23'      //重寫之後不會保留原來的任何信息了  

}
var box=new Box();
alert(box.name)    //undefined
alert(box.age)    //23
alert(box.run());   //Error:box.run is not a function
  • 內置引用類型的原型擴展
//數組排序
var box=[5,2,4,6,8];
alert(box.sort());

alert(Array.prototype.sort);  //f查看sort是否是Array原型對象裏的方法 如果是 則返回true  這裏返回true
alert(String.prototype.addstring);//這裏不是String的方法 返回false 所以我可以自定義一個addstring

//內置引用類型的功能擴展
String.prototype.addstring=function  () {
  return this +',被添加了';
}
alert('Lee'.addstring());
  • 原型共享
unction Box () {}
Box.prototype={
  name:'Li',
  age:23,
  family:['哥哥','姐姐','妹妹'],
  run:function(){
    return this.name+this.age+"運行....";
  }
};
var box1= new Box();
//alert(box1.run());
alert(box1.family);
box1.family.push('弟弟');  //追加  
alert(box1.family);   

var box2 = new Box();
alert(box2.family);   //哥哥,姐姐,妹妹,弟弟。  //共享了box1添加後的引用類型的原型
  • 混合模式(構造函數+原型模式) //混合模式很好的解決傳參和引用共享的,是解決對象比較好的方法
function Box (name,age) {     //保持獨立的用構造函數
  this.name=name;
  this.age=age;
  this.family=['哥哥','姐姐','妹妹'];
}

Box.prototype={        //保持共享的用原型
  constructor:Box,
  run:function(){
    return this.name+this.age+"運行中";
  }
};
var box1=new Box('LEE','22');     
//alert(box1.run());   //LEE22運行中
alert(box1.family);     //哥哥,姐姐,妹妹
box1.family.push('弟弟');   //在family後面追加弟弟
alert(box1.family);     //哥哥,姐姐,妹妹,弟弟
var box2= new Box('kkk','23');
//alert(box2.run());
alert(box2.family);     //引用類型沒有使用原型,所以沒有共享。
  • 動態原型模式
//可以將原型封裝到構造函數裏
function Box(name,age){
  this.name=name;
  this.age=age;
  this.family=['哥哥','姐姐','妹妹'];
  if(typeof this.run!='function'){        //判斷this.run是否存在   因爲原型的初始化只要第一次初始化就夠了,沒必要每次構造的時候都初始化
    alert('原型初始化開始');
     Box.prototype.run=function(){
       return this.name+this.age+'運行中';
     }
    alert('原型初始化結束');
  }
}
var box1=new Box('LEE','22');
alert(box1.run());
var box2= new Box('kkk','23');
alert(box2.run());
  • 函數的繼承一(通過原型鏈繼承)
function Box(){
  this.name='Lee';
}
function Desk(){
  this.age='20';
} 
function Table(){
  this.level='aaa';
}

 Desk.prototype = new Box()  //Desk繼承Box   
 //new Box()Box構造裏面的屬性和原型裏面的都交給Desk Desk得到Box的構造+原型裏面的信息
 var desk = new Desk();
 alert(desk.name);  //Lee
 alert(desk.age);  //20

Table.prototype =  new Desk();
var table= new Table(); 
alert(table.name);  //Lee
alert(table.age);    //20
alert(desk instanceof Object)//true 子類型它自己它的超類型
  • 函數的繼承二(使用對象冒充繼承)
function Box(name,age,family){
   this.name=name;
   this.age=age;
   this.family=['哥哥','姐姐','妹妹'];
}
//Box.prototype.family='家庭';  //繼承不到
function Desk(name,age){
  Box.call(this,name,age);
}
var desk = new Desk('kkk','23');
alert(desk.name)//kkk
alert(desk.family); //哥哥姐姐妹妹  (對象冒充只能繼承構造函數中的信息)
desk.family.push('弟弟');
alert(desk.family) //哥哥姐姐妹妹弟弟
  • 函數的繼承三(組合繼承:對象冒充+原型鏈,解決原型中方法訪問不到的問題)
function Box (name,age,family) {
  this.name=name;
  this.age=age;
  this.family=['哥哥','姐姐','妹妹'];
}
Box.prototype.run=function (){
  return this.name+this.age+'運行中...';
}
function Desk(name,age){
  Box.call(this,name,age);  //對象冒充只能繼承構造函數中的信息
}
 var desk = new Desk('Lee','22');
 Desk.prototype =  new Box();  //組合繼承:對象冒充+原型鏈,解決原型中方法訪問不到的問題
 alert(desk.run());  //如果是冒充繼承 這裏本來是訪問不到的,現在採用了組合繼承 可以輸出 Lee22運行中... 
  • 函數的繼承四(原型式繼承)
//臨時中轉函數
function obj (o) {    //o表示將要傳遞進入的一個對象
    function F () {}    //F構造是一個臨時新建的對象,用來存儲傳遞過來的對象
    F.prototype=o;    //將o對象的實例賦值給F構造的原型
    return new F();   //返回傳遞過來的對象實例
}
var box={
  name:'jack',
  age:100,
};
var box1= obj (box);
alert(box1.name);
  • 函數的繼承五(寄生式繼承)
//臨時中轉函數
function obj (o) {    
  function F () {}     
    F.prototype=o;    
    return new F();   
}
//寄生函數
function create (o) {
  var f= obj(o);
  f.run=function(){
    return this.name+'方法';
  }
  return f;
}
var box={
  name:'jack',
  age:100,
  family:['哥哥','姐姐','妹妹']
};
var box1= create(box);
alert(box1.run());
  • 函數的繼承五(寄生組合繼承)
//臨時中轉函數
function obj (o) {    
  function F () {}     
    F.prototype=o;    
    return new F();   
}
//寄生函數
function create (box,desk) {
  var f= obj(box.prototype);
  f.constructor=desk;   //調整原型構造指針
  desk.prototype=f;
}

function Box(name,age){
  this.name=name;
  this.age=age;
}
Box.prototype.run=function  () {
  return this.name+this.age+'運行中。。。';
}

function Desk(name,age){
  Box.call(this,name,age);   //對象冒充
}
//通過寄生組合繼承來實現繼承
create(Box,Desk);  //這句話代替了Desk.prototype= new Box();

var desk = new Desk('KKK','25');
alert(desk.run());
alert(desk.constructor);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章