淺談 OOP JavaScript [3] -- 原型

上一章咱們談了構造函數,他的惟一特色就是比較了地址不相同,由於你們知道引用類型是比較的引用。咱們來談談原型。數組

原型函數

咱們每建立一個函數都有一個原型(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

相關文章
相關標籤/搜索