天天看點

說透js的原型和原型鍊

1. 什麼是原型?

給其它對象提供共享屬性的對象,簡稱為原型。 你可以暫且吧原型了解為一個對象, 把__proto__了解為原型,吧prototype了解為原型,那麼你要問我為什麼要搞兩個原型,那麼你得聽我慢慢道來

2. 原型有什麼用?

  1. 可以讓所有的對象執行個體共享它所包含的屬性和方法,
  2. 繼承 ⇒ JavaScript的繼承就是基于原型的繼承

3. 了解原型之前你需要知道的幾個東西

3.1 構造函數丶執行個體對象丶原型對象分别是什麼? 他們之間又有什麼關系?

我們先來看一段代碼

function Person(name, age) {
	this.name = name
	this.age = age
}
let p = new Person('pcy', 18)
console.log(p.__proto__)
console.log(Person.prototype);
console.log(p.__proto__ === Person.prototype); //true
           

上面代碼的Person就是構造函數 p代表執行個體對象 p.__proto__代表原型對象

用一張圖來展示他們的關系

說透js的原型和原型鍊
上圖可以看出, 構造函數通過new建立執行個體對象,執行個體對象通過__proto__可以通路原型對象,然後原型對象有一個constructor,這個constructor是原型對象自帶的,constructor裡儲存了指向構造函數的一些資訊, 在構造函數建立的時候,原型對象就建立了,然後構造函數的prototype指向了原型對象. 是以console.log(p.proto === Person.prototype); //true

3.2 什麼是__proto__ ?

__proto__被稱為隐式原型, 每個對象都有這麼一個屬性. 你可以在控制台輸入{}, 然後回車, 你會發現列印出[[prototype]], 是一個對象, 這個[[prototype]]其實就是原型

說透js的原型和原型鍊

我們可以通過__proto__通路這個對象,你會發現為什麼我們明明隻是建立一個對象.卻可以使用toString,valueOf等方法,因為這些方法都在原型上

let obj = {}
console.log(obj.__proto__);
           
說透js的原型和原型鍊

3.3 什麼是prototype?

prototype被稱為顯式原型, 每個函數都有這麼一個屬性

let fn = function F() { }
console.log(fn.prototype);
           
說透js的原型和原型鍊

3.4 __proto__和prototype的關系?

總結一下, 函數的原型叫prototype, 被構造函數建立的對象的原型叫__proto__, 函數.prototype === 執行個體對象.proto

4. 什麼是原型鍊

原型鍊定義如何查找對象的屬性

比如現在有一個對象obj,我要查找obj的某個屬性,先看obj自身有沒有這個屬性,如果沒有就去obj.__proto__上看看有沒有,沒有就去建立obj的構造函數的prototype的__proto__上找,這一層一層的查找鍊路,被稱為原型鍊.

function Parent(name){
	this.name = name;
}

var obj = new Parent('Ann');

console.log(obj.name); // Ann

console.log(obj.father); // undefined
           

查找會走如何步驟

說透js的原型和原型鍊

關于原型鍊,你也可以參考下面這這張圖, 左邊半部分就和我3-1下面那張圖意思差不多, 整張圖一起看,就是一個完整的原型鍊

說透js的原型和原型鍊

5. 結語

如果這篇文章幫到了你,歡迎點贊👍和關注⭐️。

文章如有錯誤之處,希望在評論區指正🙏🙏。

繼續閱讀