這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

原型和原型鏈
1. 原型
每個JS物件一定對應一個原型物件,并從原型物件繼承屬性和方法
1.1 __proto__
物件的__proto__屬性值就是物件的原型物件
此屬性是過時的語法,現在建議使用Object.getPrototypeof(obj)
函式也是物件,因此也有__proto__屬性
1.2 Prototype
函式的prototype屬性值就是函式的原型物件
定義:給其他物件提供共享屬性的物件,prototype 本身也是物件,只是被用以承擔某個職能
當說 prototype 物件時,實際上說的是 “xxx 函式物件的 prototype 物件”
1.3 constructor
每個原型都有一個 constructor 屬性指向關聯的建構式
實體訪問 constructor 屬性是獲取的原型物件的建構式
function Person(age) {
this.age = age;
}
let p = new Person(50);
console.log(Person.prototype.constructor === Person); // true
console.log(p.constructor === Person); // true 會查找原型物件
對于參考型別來說 constructor 屬性值是可以修改的,但是對于基本型別來說是只讀的,因為創建他們的是只讀的原生建構式(native constructors)
2. 原型鏈
每個物件擁有一個原型物件,通過 __proto__ 指標指向上一個原型 ,并從中繼承方法和屬性,同時原型物件也可能擁有原型,這樣一層一層,最終指向 null,這種關系被稱為原型鏈 (prototype chain),通過原型鏈一個物件會擁有定義在其他物件中的屬性和方法,
因此,當讀取實體的屬性時,如果找不到,就會查找與物件關聯的原型中的屬性,如果還查不到,就去找原型的原型,一直找到最頂層為止,
2.1 原型鏈知識點
-
原型鏈的盡頭(root)是
Object.prototype,所有物件(除null)均從Object.prototype繼承屬性 -
Object.prototype.__proto__值是null,原型鏈終止 -
Function.prototype和Function.__proto__為同一物件意味著:
Object/Array/String等等建構式本質上和Function一樣,均繼承于Function.prototype -
Function.prototype直接繼承root(Object.prototype) -
繼承的原型鏈:
Object.prototype(root)<---Function.prototype<---Function|Object|Array... -
物件的
__proto__指向自己建構式的prototype -
ES規范定義物件字面量({})的原型就是
Object.prototype
2.2 Object和Function的雞和蛋的問題
Function.prototype是個不同于一般函式(物件)的函式(物件)Function.prototype像普通函式一樣可以呼叫,但總是回傳undefined,- 普通函式實際上是
Function的實體,即普通函式繼承于Function.prototype,func.__proto__ === Function.prototype, Function.prototype繼承于Object.prototype,并且沒有prototype這個屬性,func.prototype是普通物件,Function.prototype.prototype是null,- 總結,
Function.prototype其實是個另類的函式,可以獨立于/先于Function產生,
- Object本身是個(構造)函式,是Function的實體,即
Object.__proto__就是Function.prototype
問題總結:
先有Object.prototype(原型鏈頂端),Function.prototype繼承Object.prototype而產生,最后,Function和Object和其它建構式繼承Function.prototype而產生
2.3 原型鏈圖解
原型和原型鏈經典關系圖

自己畫的原型圖
圖解描述:
Person、Object、Function是函式物件,具備prototype屬性,其他物件是只有__proro__
獲取原型物件
Person.__proto__及Object.__proto__與Function.__proto__相等,是? () { [native code] }
Person.__proto__及Object.__proto__與Function.__proto__的原型物件為Object.prototype
Function.__proto__和Function.prototype值相等,為空函式: ? () { [native code] }
Person.constructor、Object.constructor與Function值相等,為: ? Function() { [native code] }

原型鏈代碼輸出結果
function Person(name) {
this.name = name
}
var p2 = new Person('king');
console.log(p2.__proto__) //Person.prototype
console.log(p2.__proto__.__proto__) //Object.prototype
console.log(p2.__proto__.__proto__.__proto__) // null
console.log(p2.__proto__.__proto__.__proto__.__proto__)
//null后面沒有了,報錯
console.log(p2.__proto__.__proto__.__proto__.__proto__.__proto__)
//null后面沒有了,報錯
console.log(p2.constructor)//Person
console.log(p2.prototype)//undefined p2是實體,沒有prototype屬性
console.log(Person.constructor)//Function 一個空函式
console.log(Person.prototype)
//列印出Person.prototype這個物件里所有的方法和屬性
console.log(Person.prototype.constructor)//Person
console.log(Person.prototype.__proto__)// Object.prototype
console.log(Person.__proto__) //Function.prototype
console.log(Function.prototype.__proto__)//Object.prototype
console.log(Function.__proto__)//Function.prototype
console.log(Object.__proto__)//Function.prototype
console.log(Object.prototype.__proto__)//null
console.log(Function); // ? Function() { [native code] } 空函式,名為Function
console.log(Object.constructor); // ? Function() { [native code] }
console.log(Person.constructor); // ? Function() { [native code] }
console.log(Function === Object.constructor); // true
console.log(Function === Person.constructor); // true
console.log(Function.__proto__); // ? () { [native code] }
console.log(Function.prototype); // ? () { [native code] }
console.log(Function.__proto__ == Function.prototype); // true
console.log(Function.__proto__.__proto__ === Object.prototype) // true
console.log(Function.prototype.__proto__ === Object.prototype) // true
本文轉載于:
https://juejin.cn/post/7086376102238617614
如果對您有所幫助,歡迎您點個關注,我會定時更新技術檔案,大家一起討論學習,一起進步,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/498877.html
標籤:JavaScript
