JS開發者應懂的33個概念系列5(下)--typeof 與 instanceof && 23--原型繼承與原型鏈

JS開發者應懂的33個概念系列5(下)--typeof 與 instanceof && 23--原型繼承與原型鏈bash

typeof的原理

typeof能夠用來判斷原始值的類型,以及區分對象值和原始值.咱們能夠利用 typeof 來判斷number, string, object, boolean, function, undefined, symbol 這七種類型。函數

一個 js 的變量,在它的底層實現中, 類型信息是怎麼實現的呢?也就是說js 在底層是怎麼存儲數據的類型信息呢?typeof也就是經過類型信息進行判斷的。ui

js 在底層存儲變量的時候,會在變量的機器碼的低位1-3位存儲其類型信息:spa

  • 000 object
  • 010 浮點數
  • 100 string
  • 110 boolean
  • 1 整數

對於 undefinednull 來講,這兩個值的信息存儲是有點特殊的。prototype

  • null:全部機器碼均爲0
  • undefined:用 −2^30 整數來表示

因此,typeof在判斷 null的時候就出現問題了,因爲 null 的全部機器碼均爲0,所以直接被當作了對象來看待。因此,在判斷變量類型的時候,避免對null進行判斷。code

typeof null   // "object"
複製代碼

instanceof的原理

在 JavaScript 中,判斷一個變量的類型嚐嚐會用 typeof 運算符,在使用 typeof 運算符時採用引用類型存儲值會出現一個問題,不管引用的是什麼類型的對象,它都返回 "object"cdn

直接上硬貨:對象

function instance_of(L, R) {//L 表示左表達式,R 表示右表達式
 var O = R.prototype;// 取 R 的顯示原型
 L = L.__proto__;// 取 L 的隱式原型
 while (true) { 
   if (L === null) 
     return false; 
   if (O === L)// 這裏重點:當 O 嚴格等於 L 時,返回 true 
     return true; 
   L = L.__proto__; 
 } 
}
複製代碼

instanceof 在查找的過程當中會遍歷左邊變量原型鏈,直到找到右邊變量的 prototype,若是查找失敗,則會返回 false,告訴咱們左邊變量並不是是右邊變量的實例。blog

劃重點,原型鏈繼承

原型鏈

function Person() {}
var Student = new Person()
複製代碼

先不着急解釋原型鏈,先看一下什麼是原型?

原型

  • 每個構造函數都擁有一個prototype屬性,這個屬性指向一個對象,也就是原型對象。好比:構造函數Personprototype即是指向Person.prototype對象。
  • 原型對象默認擁有一個constructor屬性,指向它的那個構造函數(也就是說構造函數和原型對象是互相指向的關係)。好比:Person.prototype.constructor指向Person
  • 每一個對象類型好比(Student,Person.prototype,Function.prototype)都擁有一個隱藏的屬性[[prototype]],指向它的原型對象,這個屬性能夠經過 Object.getPrototypeOf(obj)obj.__proto__來訪問。
  • 實際上,構造函數的prototype屬性與它建立的實例對象的[[prototype]]屬性指向的是同一個對象,即Student.__proto__ === Person.prototype

JavaScript中,全部的對象都是由它的原型對象繼承而來,反之,全部的對象均可以做爲原型對象存在。

訪問對象的屬性時,JavaScript會首先在對象自身的屬性內查找,若沒有找到,則會跳轉到該對象的原型對象中查找,也就是經過__proto__進行查找。

因此呢,原型鏈就是你查找過程所經歷的地方。

最後來個例子:

console.log(Object instanceof Object);//true 
console.log(Function instanceof Function);//true 
console.log(Function instanceof Object);//true 
 
複製代碼

在複習一遍:

Object instanceof Object?

var O = Object.prototype;
var L = Object.__proto__; // L是Function.prototype
while(true) // 進入循環
L = Object.__proto__.__proto__ // L是Object.prototype
while(true) // 從新進入循環
O === L 
return true複製代碼

總結口訣

  • Object.__proto__ === Function.prototype其中Object是構造函數
  • 指向Function.prototype是構造函數的__proto__屬性
  • 指向Object.prototype是原型對象的__proto__屬性
  • Object.prototype.__proto__null
  • *.prototype.constructor指向它的構造函數*
  • Object.prototype除了constructor__proto__外,還有toString(),valueOf()等屬性,下屬原型對象能夠經過原型鏈繼承這些屬性。

相關文章
相關標籤/搜索