# 面向對象與原型
## 一、對象創建
~~~
var box={};
box.name='tianwei';
box.age='30';
box.run=function(){
return this.age+this.name+"運行中..."
}
alert(box.run());
~~~
###1. 工廠模式: 解決多個相似對象聲明代碼重復的問題
~~~
function createObject(name,age){
var obj=new Object();
obj.name=name;
obj.age=age;
obj.run=function(){
return this.name+this.age+"運行中...";
};
return obj;
}
var box1=createObject('田偉',100);
var box2=createObject('寶寶',1000);
alert(box1.run());
alert(box2.run());
~~~
###2. 構造函數模式:解決工廠模式下,不能確定是哪個對象創建的對象實例
a. 構造函數也是函數,但函數名第一個字母大寫
b. 必須new 構造函數() ,才能實例化,第一個字母也是大寫
~~~
function Box(name,age){ //創建對象 后臺自動創建 new Object(),無需像工廠一樣返回對象
this.age=age; //實例屬性
this.name=name;
this.run=function(){ //實例方法
return this.age+this.name+"運行中..."
};
}
var box1=new Box("田偉",100);
var box2 =new Box('嚴慧',200);
alert(box1.run());
alert(box2.run());
//對象冒充
var o = new Object();
Box.call(o,'田偉',500);
alert(o.run());
~~~
實例屬性,實例方法不會共享
刪除實例屬性:delete Box.name;
## 原型
每創建一個構造函數,就會自動生成一個prototype屬性對象。
~~~
function Box(){}
Box.prototype.name="田偉";
Box.prototype.age=100;
Box.prototype.run=function(){
return this.name+this.age+"運行";
}
var box1=new Box(); //原型解決了對象里的函數引用地址共享
var box2=new Box();
box1.run==box2.run;
~~~


### 構造函數+原型組合模式,解決共享問題
~~~
function Box(name,age){ //可變常量部分
this.name=name;
this.age=age;
this.family=[3,5,6];
}
Box.prototype={ //不變的方法部分
constructor:Box,
run:function(){
return this.name+this.age+'運行中....';
}
}
var box1=new Box('tianwei',300);
alert(box1.run());
~~~
### 動態原型模式
把原型封裝到對象中
~~~
function Box(name,age){ //可變常量部分
this.name=name;
this.age=age;
this.family=[3,5,6];
if(typeof this.run!=='function'){ //僅在第一次調用的時候初始化
Box.prototype=function(){
return this.name+this.age+'運行中....';
}
}
}
~~~