你真的懂原型麼?

2022-02-07 06:22:11 字數 2382 閱讀 6824

基本看過高程等書的人都可以對原型繼承,原型鏈查詢侃侃而談,**中也可以使用原型完成一些事情,但是,我們對於原型真的徹底搞明白了麼?

我們的原型是乙個物件,構造器函式有乙個屬性指向這個物件,prototype;而我們每次new出來的例項也有乙個屬性指向這個物件,__proto__。為什麼說原型是由構造器確定的,因為在new之後,這個例項的原型就已經確定了,例項的__proto__和構造器的prototype都會指向那個原型物件。

var person=function

(){};

var p=new

person();

console.log(p.__proto__===person.prototype); //

true

person.prototype=

}var t=new

person();

console.log(t.__proto__===person.prototype); //

true

t.say(); //

hello

console.log(p.__proto__===person.prototype); //

false

p.say(); //

報錯

這段**就很好的說明了這個問題。例項p通過構造器函式person建立出來(new)之後,它的__proto__和person的prototype指向同乙個物件,所以console的時候相等。然後,我們改變一下構造器函式person的原型指向,並建立了乙個例項t,我們發現t的__proto__和person的prototype的指向依舊是一致的,但是因為person.prototype已經改變了,而p.__proto__依舊指向原來的原型物件,所以p.__proto__和現在的person.prototype指向的物件並不是同乙個,會返回false。證據就是p.say()會報錯,但是t.say()可以返回正確的值。

看下面的**:

var person=function

(){};

var p=new

person();

person.prototype.say=function

()p.say();

//1

我們先建立了例項,再給原型新增方法,最後呼叫時,依舊可以返回正確結果,這說明p.say()是乙個查詢的過程,它會去原型物件裡查詢相應的方法,如果有返回結果,沒有就會報錯。

那麼,既然是通過例項呼叫的方法,自然也是通過例項的__proto__屬性去訪問到那個原型物件,如何證明?我們看下面的**:

var person=function

(){};

var p=new

person();

person.prototype.say=function

()p.say(); //1

p.__proto__=

}p.say(); //2

當我們重寫p.__proto__之後,相當於p這個例項的原型就是我們重寫的這個物件。無論我們對person.prototype新增任何方法,p這個例項都訪問不到這些方法,因為原型鏈查詢通過的是__proto__屬性,而現在,p.__proto__和person.prototype指向的其實是不同的兩個物件了。

當我們new了乙個例項之後,原型物件就已經存在了,例項的__proto__和構造器的prototype都會指向它。而建立例項之後,我們如果修改了__proto__或者prototype,其實都是在修改那個唯一的原型物件。要是我們重寫了__proto__或者prototype,原型物件依舊存在,但是通過__proto__或者prototype只能訪問到重寫的那個物件。所以我們一直在強調,new是乙個分界線,new的過程就是把例項的__proto__指向構造器的prototype所指向的那個物件。

看點例子:

var person=function

(){};

var p=new

person();

var t=new

person();

p.__proto__.say=function

()p.say(); //1

t.say(); //

1p.__proto__=

}p.say(); //2

t.say(); //

1person.prototype=

}var x=new

person();

p.say(); //2

t.say(); //

1x.say(); //

3

如果你對上述**沒有任何疑問,那麼,你應該是真的懂了原型。

你真的懂學習麼?

目錄 why what how 小結 為啥要學習呢?如果你想變得更優秀,除了學習,你還有其他選擇麼?除了學習,你別無選擇。什麼是學習?官方解釋 個體由經驗或練習引起的在能力或傾向方面的變化,也指變化的過程。是人類和動物普遍具有的活動。按內容可分為認知的 情感的 運動技能的 按是否理解可分為機械學習和...

你真的懂defer了嗎

example1 func f result int return 0 example2 func f r int return t example3 func f r int r return 1 先不要執行 自己在心裡跑一遍結果。然後再去驗證。如果三個都做對了並且不是蒙的.好吧,不用往下看了,你...

你真的懂迴圈嗎

好了今天我來講講什麼是迴圈吧,你又真的懂迴圈嗎?讓我來講講迴圈的細節吧和判斷吧 1 for迴圈樣式 for var i 0 i 5 i 它的條件表示式就是先寫for 在寫內部的條件,在js中宣告變數也是可以不加var直接就可以 for i 0 i 5 i 但這樣寫也有一點不對,因為i時區域性變數最好...