爲何須要prototype

首先,上一篇文章詳細分析了原型屬性自身屬性的區別,但爲了讓你們更明白一點,因此這裏講一下爲何須要原型。但要講原型就必須講構造函數,講構造函數就必須講對象。首先來看看對象程序員

新建一個對象的方法:

1.new Object:


var newObj = new Object; newObj.name = "keti"; newObj.color = "red"; newObj.changeColor = function(color){ newObj.color = color; }

這種方法看上去很蠢,因此咱們找到另外一種方法:使用literal直接建立,看上去要優雅得多:架構

2.literal


var newObj = { name: "keti"; color: "red"; changeColor: function(color){ newObj.color = color; } }

使用literal來常見對象彷佛很不錯,比較直觀,兩個卷括號括起來就是個對象嘛,多清晰明瞭。可是若是你要建立一系列結構相似的對象,難道要這樣一個個寫嗎?做爲程序員咱們的遵循的理念就是儘量減小重複,也就是著名的DRY(Don't Repeat Youself)。因此咱們是沒法容忍這麼愚蠢的事情發生的,所以就有了構造函數,跟類有點類似,但咱們這裏不討論類。構造函數就是創建一個模板,不綁定數據,只提供架構,你只需把相關數據填充到模板裏就能夠生成一個新的對象了:函數

3.構造函數

function NewObj(name,color){
    this.name = name;
    this.color = color;
    this.changeColor = function(c){
        this.color = c;
    }
}
var newObj1 = new NewObj("keti","red");

上面代碼中,new是一個構造器,NewObj是咱們建立好的模板,填入數據,賦給變量newObj1,ok,新的對象就這樣生成了。this

到此建立對象的方法彷佛已經很不錯了,但仔細觀察咱們還發現了新的問題:對於changeColor()這個方法事實上對全部instance來講是相同的,也就是說能夠共享,不像name和color那樣須要綁定給每一個instance。而構造函數這種形式每次都會把自身的屬性所有copy一份給每一個instance,這就形成了沒必要要的浪費;而且,當咱們想修改這個方法時,就必須從新生成全部的instance才能得到更新,好比說:prototype


function NewObj(name,num){ this.name = name; this.num = num; this.changNum = function(c){ this.num = c; } } var newObj1 = new NewObj("kemi",10); newObj1.changNum(100); newObj1.num; //很明顯是100

我如今想修改changNum()這個函數:指針


function NewObj(name,num){ this.name = name; this.num = num; this.changNum = function(c){ this.num = c*2; } } newObj1.changNum(100); newObj1.num; //依然是100,也就是說這個對象並不受咱們修改的模板影響到

怎麼解決這個問題呢?有一個原型對象。原型對象裏的屬性和方法並非像構造函數自身屬性同樣copy給每一個instance,而是「引用」,也能夠理解爲給每一個instance提供一個指向該原型對象的指針,這樣每一個instance就能找到原型對象裏的屬性,而很明顯,這是一種共享,也就是說,當你修改了這個原型裏的屬性,那麼全部共享該屬性的instance都能得到這個修改。所以,原型剛好解決了上面提到的兩個問題。code


function NewObj(name,num){ this.name = name; this.num = num; } NewObj.prototype.changNum = function(c){ this.num = c; } var newObj1 = new NewObj("kemi",10); newObj1.changNum(100); newObj1.num; //很明顯是100 NewObj.prototype.changNum = function(c){ this.num = c*2; }//咱們從新修改一下這個方法 newObj1.changNum(100); newObj1.num; //變成200了。

爲何通常狀況下會把屬性直接寫在構造函數內,而方法經過prototype添加呢?這兩種方式的區別上面其實已經有所展示了:大部分的instance的屬性都是不一樣的,好比說name,所以在構造函數內經過this直接綁定給instance無疑是個好方案,而方法一般是通用的,使用prototype可讓每一個instance共享同一個方法,而不用每一個都copy一次,又能實現實時更新。對象

相關文章
相關標籤/搜索