(圖解)Js原型和原型鏈,看完不懂你打我!

2020-09-21 16:00:18

原型 prototype

先跟各位小夥伴說一下,原型不難理解的,難的是運用,這節我們先去理解什麼是原型,希望配合上圖解,大家能很輕鬆理解,步入正題。

要徹底瞭解原型我們要知道以下幾點:

  1. 我們所建立的每一個函數,解析器都會向函數中新增一個屬性 prototype
  2. 這個 prototype 屬性對應著一個物件,這個物件就是我們所謂的原型物件;
  3. 該函數我們以建構函式呼叫時,它所建立的物件中都會有一個隱含屬性 _ _ proto _ _
  4. _ _ proto _ _ 這個屬性也會指向該建構函式的原型物件;

綜上所述:原型物件就相當於一個公共區域,該函數的prototype屬性和該建構函式的 _ _ proto _ _ 屬性,都指向 原型物件

圖解(配合著下面的程式碼更香哦)

在這裡插入圖片描述

程式碼解析

			// 1.函數
			function MyClass(){
			}
			// 2.通過該函數建立兩個 建構函式 fn1  fn2
			var fn1=new MyClass();
			var fn2=new MyClass();
			
			// 3.統一列印結果
			console.log(MyClass.prototype);//列印是一個物件
			console.log(fn1.__proto__);//列印是一個物件
			console.log(fn2.__proto__);//列印是一個物件
			console.log(MyClass.prototype==fn1.__proto__);//true 兩者相同
			console.log(MyClass.prototype==fn2.__proto__);//true 兩者相同
			
			// 向MyClass的原型中新增屬性a
			MyClass.prototype.a=123;
			// 通過該函數建立兩個 建構函式 都可以存取其屬性
			console.log(fn1.a);// 123
			console.log(fn2.a);// 123
			// 結論:通過該函數建立兩個 建構函式 都可以存取該函數原型裡新增的屬性和方法;			

結論: 每一個函數都有一個prototype屬性 ,而該函數以建構函式建立的每一個物件都有一個 _ _ proto _ _ 屬性。prototype屬性對應的值就是原型物件,並且該函數以建構函式建立的物件 _ _ proto _ _ 屬性指向原型物件。

用途:

  1. 試想一下,如果我們在全域性建立一個函數,在多人共同作業開發的情況下如果函數命名相同,後一個函數就會覆蓋前一個函數,所以是將包含特定型別的所有範例共用的屬性和方法封裝在原型物件,這個原型物件就是用來給範例共用屬性和方法的。
  2. 如果一個函數裡面寫了很多屬性和方法,該建立許多個物件的時候,每個物件下都會包含每一個屬性和方法,會造成資源的浪費,而把方法寫在該函數的prototype屬性中,每一個物件不僅可以呼叫,而且也減少了資源的浪費。

原型鏈

上面大家瞭解了原型,現在去了解原型鏈就會輕鬆很多。

簡單來說就是再找一個屬性或者方法時,該級不存在,通過原型物件逐級向上查詢的一個過程。

程式碼邏輯

		// 建立一個建構函式
		function MyClass(){
		}
		var fn=new MyClass();
		
		// 向MyClass的原型中新增一個name屬性
		MyClass.prototype.name="我是原型的小破船";
		console.log(fn.name);// 列印 我是原型的小破船
		
		// 使用物件的hasOwnProperty()來檢查物件自身是否含有該屬性
		console.log(fn.hasOwnProperty("name"));// false
		console.log(fn.__proto__.hasOwnProperty("name"));// true
		// name屬性在fn中是不存在的,而是存在於原型物件中。
		
		// 原型中並沒有hasOwnProperty()方法是怎麼來的呢?
		console.log(fn.__proto__.hasOwnProperty("hasOwnProperty"));// false
		// 原型中不存在
		console.log(fn.__proto__.__proto__.hasOwnProperty("hasOwnProperty")); // true
		// 原型的原型中存在
		console.log(fn.__proto__.__proto__.__proto__); // null
		// 原型的原型中的原型為null

圖片解析

在這裡插入圖片描述
首先需要了解:只要是物件就有原型,原型物件也是物件,所以它也有原型,

結論: 當我們使用一個物件的屬性或方法時,會先在自身中查詢,如果自身有則使用,如果沒有則去原型物件中尋找,如果原型物件中有則使用,如果沒有則去原型物件的原型物件中查詢,如果一直未找到,直到找到object物件的原型(object可以理解為是物件的鼻祖),object物件的原型沒有原型為null。所以這個逐級向上查詢的過程形成的鏈式結構,就是原型鏈!!!

小夥伴們如果看了感覺可以理解,麻煩幫忙點個贊哦,如果還有不懂的地方可以留言哦,共同學習,共同進步,不喜就噴,謝謝!