上一章咱們談了構造函數,他的惟一特色就是比較了地址不相同,由於你們知道引用類型是比較的引用。咱們來談談原型。數組
原型函數
咱們每建立一個函數都有一個原型(prototype)屬性,這個屬性是一個對象,他的特色是共享。也就是說不用在構造函數中定義對象實例,而是直接將這些添加到原型當中。this
function Create () {} //聲明一個構造函數 Create.prototype.a = 'abc'; //在原型中添加屬性 Create.prototype.b = 10; Create.prototype.c = function () { //在原型中添加方法 return this.a + this.b; }; var create = new Create(); alert(create.c()); //返回abc10
咱們此次再來比較一下原型中方法的地址是否一致:spa
var create = new Create(); var create1 = new Create(); alert(create.c == create1.c); //true
是否是還沒明白?咱們用一張圖來告訴你們:
prototype
這個__proto__就至關於指針,指向了原型對象的constructor,而constructor就至關於將構造函數對象和原型對象相關聯。
那麼咱們要用構造函數對象去給重寫屬性或者方法會怎麼樣呢?指針
var create = new Create(); create.a = 'EFD'; alert(create.a); //返回EFD
真的將原型對象裏面的a給覆蓋了麼?並無:code
var create1 = new Create(); alert(create.a); //返回abc
原型模式的執行過程:對象
1.先去查找構造函數裏面的屬性和方法 ,若是有就當即返回。
2.若是構造函數實例裏面沒有,就去原型裏面查找,若是有就當即返回。blog
由於咱們在構造函數添加了屬性,因此它會自動去查找,構造函數裏面的屬性也就當即返回了!字符串
原型的字面量
在原型中,咱們也可使用字面量的方式去建立,可讓屬性和方法體現出更好的封裝效果。
function Create(a,b){}; //聲明一個構造函數 Create.prototype = { //字面量方式 a:'abc', b:10, c:function () { return this.a + this.b; } };
不知道你們有沒有發現,咱們用字面量的方式是這樣的:Create.prototype ={};
你們都知道,用一個{}就等同於new Create();這樣,咱們就至關於新聲明的一個對象,咱們原型對象裏面的constructor還會指向Create麼?
var create = new Create(); alert(create.constructor == Create); //false alert(create.constructor == Object); //true
(咱們來解釋一下爲何用create.constructor,由於咱們打印constructor就會將整個構造函數打印出來,由於上面講過它是將構造函數對象和原型對象相關聯的屬性。)
經過上面的例子能夠看出,它已經指向了新的實例對象。
constructor的巧妙用法:
咱們可使用constructor來強制指回原來的實例對象:
function Create(a,b){}; Create.prototype = { constructor:Create, a:'abc', b:10, c:function () { return this.a + this.b; } };
原型對象的重寫問題:
你們都知道,構造函數的屬性和方法重寫是無傷大雅的,可是原型對象中能夠重寫麼?
function Create(a,b){}; Create.prototype = { constructor:Create, a:'abc', b:10, c:function () { return this.a + this.b; } }; Create.prototype = { a:'EFD', }; var create = new Create(); alert(create.c()); //create.c is not a function
不難看出,咱們重寫了原型會將以前的原型指向切斷!!!
原型模式的缺點:
其實它的缺點也是它優勢:共享。
咱們在字面量裏面給原型對象添加一個數組就很容易的看出來了:
function Create(a,b){}; Create.prototype = { constructor:Create, a:'abc', b:10, c:[第一個,第二個,第三個], d:function () { return this.a + this.b + this.c; } }; var create = new Create(); create.c.push('第四個'); alert(create.run()); //返回abc10第一個第二個第三個第四個
咱們看得出這時候push添加已經生效了,在數組的末尾添加了「第四個」
咱們再來實例一個對象就能看得出他的共享問題了:
var create1 = new Create(); alert(create1.run()); //返回abc10第一個第二個第三個第四個
這就是共享問題。下面新實例化一個對象也會將上面添加的字符串給共享到這裏來。
這一章就到這裏。歡迎全部閱讀文章的人指正錯誤!
Brian Lee