原型和原型鏈


一般會問的問題:

  1. 創建對象有幾種方法
  2. 原型、構造函數、實例、原型鏈
  3. instanceof 的原理
  4. new 運算符

創建對象有幾種方法

 

原型關系

  • 每個class(class 實際是函數,是語法糖)都有顯示原型 prototype
  • 每個實例都有隱式原型 __proto__
  • 實例的 __proto__ 指向對應class 的 prototype

 

 

基於原型的執行規則

  • 獲取屬性 xialuo.name 或執行方法 xialuo.sayhi() 時
  • 先在自身屬性和方法尋找
  • 如果找不到則自動去 __proto__ 中尋找

 

原型、構造函數、實例、原型鏈

  • 原型鏈:從一個實例對象往上找構造這個實例的相關聯的對象,然后這個關聯的對象再往上找它又有創造它的上一級的原型對象,以此類推,一直到 Object.prototype 原型對象終止,這個鏈條就斷了,也就是說 Object.prototype 是整個原型鏈的頂端。通過什么往上找?就是通過 prototype 和 __proto__.
  • 原型:構造函數都有一個 prototype 屬性,這是在聲明一個函數時js 自動增加的,這個 prototype 指的就是原型對象。原型對象怎么區分被哪個構造函數引用?就是通過 constructor(構造器),原型對象中會有一個構造器,這個構造器會默認聲明的那個函數。
  • 構造函數:任何一個函數只要被 new 去操作(使用)就是構造函數,構造函數也是函數
  • 實例:只要是對象就是一個實例
  • 構造函數可以使用new 生成實例

 

 

 

通過原型鏈的方式找到原型對象,原型對象的方法是被不同的實例所共有的,這就是原型鏈的一個工作原理
1、構造函數(函數)才有propotype 的,對象沒有 propotype,
2、只有實例對象有 __proto__的,函數既是函數又是對象

 

 

 

 原型鏈

  • 如果實例中有自身屬性則直接使用自身的屬性(如圖中 xialuo),如果沒有則會再自身的隱式原型鏈中去找,一直找到最頂級 Object 為止,如果都找不到,則最后返回的null
  • 每個構造函數都有一個顯示原型prototype (如 Student, People),且每個顯示原型都會對應有一個隱式原型__proto__,而他的隱式原型的父級又有個顯示原型,他們都是一級級往上找的,然后一直找到樹形結構的第一層(Object)為終點
  • instanceof 是為判斷此實例或構造函數是否是父級繼承的,如(xialuo instanceof People  // true, xialuo instanceof Array  // false)

 

 

 

 

 

 

 

instanceof 原理:
實例對象的 __proto__ 和構造函數本身沒有什么關聯,它關聯的是構造函數 prototype 下面的一個屬性即 prototype 所引用的原型對象

是判斷 實例對象.__proto__ 和 構造函數.prototype是不是一個引用(即引用同一個地址)

 

 

 

 

 

 

new 運算符

new 構造函數的原理:

生成一個空對象(Object.create)

將空對象的__proto__指向構造函數的prototype  var o = Object.create(func.prototype)

執行構造函數,this 上下文指向空對象  var k = func.call(o)

若構造函數返回的是對象,那么這個對象將取代原來的空對象

if(typeof k === 'object') {

return k

} else {

return o

}

 

 

題目

如何准確判斷一個變量是不是數組?

答案:用 instanceof, 如 a instanceof Array

手寫一個簡易的 jQuery,考慮插件和擴展性

 1 class jQuery {
 2     constructor(selector) {
 3         const result = document.querySelectorAll(selector)
 4         const length = result.length
 5         for(let i = 0; i < length; i++) {
 6             this[i] = result[i]
 7         }
 8         this.length = length
 9         this.selector = selector
10     }
11     get(index) {
12         return this[index]
13     }
14     each(fn) {
15         for(let i = 0; i < this.length; i++) {
16             const elem = this[i]
17             fn(elem)
18         }
19     }
20     
21     on(type, fn) {
22         return this.each(elem => {
23             elem.addEventlistener(type, fn, false)
24         })
25     }
26 }
27 
28 jQuery.propotype.dialog = function(info) {
29     alert(info)
30 }
31 
32 class myJQuery extends jQuery {
33     constructor(selector) {
34         supper(selector)
35     }
36     addClass(className) {
37     }
38     style(data) {
39     }
40 }

 

 

class的原型本質,怎么理解?

答案:

  • 上面原型和原型鏈的圖示
  • 屬性和方法的執行規則


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM