JS原型的動態性及例項與原型的關係

2021-07-30 08:33:28 字數 2472 閱讀 1345

今天再讀了《js高程》的第六章,有了些深入的感悟和理解,總結分享一下。

建立物件的方式有很多,有一種是動態原型模式,最實用的是建構函式與原型組合的模式,原型的動態性在這兩個模式裡都有所體現,我本人的理解是:前者的「動態」是通過一些判斷,看方法是否存在來決定是否對原型進行初始化,同時,在建構函式內部對原型的修改會立即體現在所有的例項中,後者的「動態」是主要是說無論是先建立例項還是先修改原型,對原型物件所做的修改都會立即反應在例項中,針對後者來個栗子(栗子1):

function

person(){}

var p = new

person();

person.prototype.sayhello = function

()p.sayhello();

//彈出:hello

其實,例項與原型之間的關聯紐帶就是乙個定向指標,因此,我感覺建構函式與例項某種程度上是平等關係,只不過建構函式擁有原型指過來的乙個指標(constructor)。

function

person(){}

person.prototype =

}var p = new

person();

p.sayname();

//彈出:"tom"

那好,既然上邊說了,原型有動態性,那我這樣寫(栗子3):

function

person(){}

var p = new

person();

person.prototype =

}p.sayname();

//error

按理說,我例項呼叫了原型上的方法,應該彈出「tom」啊,事實上卻報錯:「undefined is not a function」。

其實,這已經不再是原型動態不動態的問題了,而是例項與新、舊原型物件之間的問題。另外原型與例項間關係,我們可以用isprototypeof或者instanceof等來判斷。

我們都看到了,栗子1與栗子2、3對原型的修改方式是不一樣的,栗子1相當於純粹的給原型這個物件新增了乙個方法,而栗子2、3用的是字面量法建立了乙個新的原型(相當於新建乙個物件),完完全全,徹徹底底地覆蓋了原來的原型物件,只不過用一句「constructor:person;」偽裝了一下,仔細的讀者或許會發現我在第二段的說明是給"修改"這個詞加粗了,栗子1只是「修改」,栗子2、3是「新建覆蓋」。

栗子2中建立例項物件時,原來的原型已經被新建的原型覆蓋了,因此能夠訪問到這個方法。而栗子3中,當建立例項時,它的指標指向的還是之前的原型,即便後來又新建了乙個原型物件,這個指標依然沒變,一次在原來原型上是訪問不到這個方法的,故報錯。語言的描述顯得很乾巴巴,我們再來個栗子(栗子4):

function

person(){}

person.prototype =

}

var proto =person.prototype;

var p = new

person();

p.syahello();

//hello

alert(person.prototype.isprototypeof(proto)); //

false

alert(person.prototype.isprototypeof(p)); //

true

alert(proto.isprototypeof(p)); //

true

上述**非常清晰的告訴我們:proto裡儲存的始終是原來的原型物件,而alert裡的person.prototype是已經被覆蓋了的新的原型物件,p此時訪問的也是新的原型物件。

最後來個栗子(栗子5):

function

person(){}

person.prototype =

}

p.syahello();

//error

alert(person.prototype.isprototypeof(proto)); //

false

alert(person.prototype.isprototypeof(p)); //

false

alert(proto.isprototypeof(p)); //

true

上述**非常清晰的告訴我們:proto裡儲存的依然是原來的原型物件,p此時訪問的還是原來的原型物件。

綜上,個人感覺這兩部分的內容不應該放在一塊兒說,很容易讓人迷糊,其次,看問題,一定能進得去、跳的出,遇到死角,站在更高的角度看一下,就會有新的發現,自己在看這塊兒時一直拐不過來彎兒,分明前邊說了有動態性,後邊確沒有體現,並且還相違背,這分明不合理,後來才發現,這其實是兩碼事兒,應該分開來理解。

JS原型的動態性

由於在原型中查詢成員的過程是一次搜尋,所以我們對原型物件所做的任何修改都能立即從例項上反映出來 但不包括對原型物件的重寫,下面會介紹到 即使是對原型的修改操作在建立例項之後。如下面的示例所示 function wede wede.prototype.name wede s name wede s n...

js中的原型及原型鏈

1.什麼是原型 a.每乙個物件都有原型,使用屬性 proto 引用,除了null 用於指向建立它的建構函式的prototype b.原型就是該物件表示從 繼承。通過它可以實現屬性繼承。2.proto 和prototype 的區別 proto 是每乙個物件都有的屬性。原型鏈中真正起作用的是 proto...

JS中的原型及原型鏈

什麼是原型?原型的作用 資料共享 1.1原型的資料共享 在建構函式內部新增say方法 function person name 例項化 var p newperson 小明 var p1 newperson 小紅 console.log p.say p1.say false 總結 不同例項上的同名方...