轉自https://blog.csdn.net/qq_38722097/article/details/80717240 www.cnblogs.com/yalong/p/10…html
typeof通常被用於判斷一個變量的類型,咱們能夠利用typeof來判斷number、string、object、boolean、function、undefined、symbol這七種類型。當判斷不是object時其它都好說。、數組
typeof 不存在的變量 = 「undefined」bash
typeof 對象 = 「object」函數
typeof null = "object"測試
typeof 數組 = 「object」ui
typeod 方法的實例(好比 new Array()) =「object」spa
js在底層存儲變量的時候,會在變量的機器碼的低位1-3位存儲其類型信息.net
可是,對於undefined和null來講,這兩個的信息存儲比較特殊。 null全部機器碼均爲0,undefined爲-2^30整數,因此typeof判斷時null均爲0,所以被當作對象。 因此通常用typeof判斷基本數據類型。 還能夠經過Object.prototype.toString來判斷prototype
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('hi') // "[object String]"
Object.prototype.toString.call({a:'hi'}) // "[object Object]"
Object.prototype.toString.call([1,'a']) // "[object Array]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(() => {}) // "[object Function]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(Symbol(1)) // "[object Symbol]"
複製代碼
instanceof主要做用就是判斷一個實例是否屬於某種類型code
let person = function(){
}
let no = new person()
no instanceof person//true
複製代碼
原理大概以下
function new_instance_of(leftVaule, rightVaule) {
let rightProto = rightVaule.prototype; // 取右表達式的 prototype 值
leftVaule = leftVaule.__proto__; // 取左表達式的__proto__值
while (true) {
if (leftVaule === null) {
return false;
}
if (leftVaule === rightProto) {
return true;
}
leftVaule = leftVaule.__proto__
}
}
複製代碼
其實 instanceof 主要的實現原理就是隻要右邊變量的 prototype 在左邊變量的原型鏈上便可。所以,instanceof 在查找的過程當中會遍歷左邊變量的原型鏈,直到找到右邊變量的 prototype,若是查找失敗,則會返回 false,告訴咱們左邊變量並不是是右邊變量的實例。
同時還要了解js的原型繼承原理
咱們知道每一個 JavaScript 對象均有一個隱式的 proto 原型屬性,而顯式的原型屬性是 prototype,只有 Object.prototype.proto 屬性在未修改的狀況下爲 null 值。根據圖上的原理,咱們來梳理上面提到的幾個有趣的 instanceof 使用的例子。
由圖可知,Object 的 prototype 屬性是 Object.prototype, 而因爲 Object 自己是一個函數,由 Function 所建立,因此 Object.proto 的值是 Function.prototype,而 Function.prototype 的 proto 屬性是 Object.prototype,因此咱們能夠判斷出,Object instanceof Object 的結果是 true 。用代碼簡單的表示一下
leftValue = Object.__proto__ = Function.prototype;
rightValue = Object.prototype;
// 第一次判斷
leftValue != rightValue
leftValue = Function.prototype.__proto__ = Object.prototype
// 第二次判斷
leftValue === rightValue
// 返回 true
複製代碼
Function instanceof Function 和 Function instanceof Object 的運行過程與 Object instanceof Object 相似,故再也不詳說。
Foo 函數的 prototype 屬性是 Foo.prototype,而 Foo 的 proto 屬性是 Function.prototype,由圖可知,Foo 的原型鏈上並無 Foo.prototype ,所以 Foo instanceof Foo 也就返回 false 。
leftValue = Foo, rightValue = Foo
leftValue = Foo.__proto = Function.prototype
rightValue = Foo.prototype
// 第一次判斷
leftValue != rightValue
leftValue = Function.prototype.__proto__ = Object.prototype
// 第二次判斷
leftValue != rightValue
leftValue = Object.prototype = null
// 第三次判斷
leftValue === null
// 返回 false
複製代碼
leftValue = Foo, rightValue = Object
leftValue = Foo.__proto__ = Function.prototype
rightValue = Object.prototype
// 第一次判斷
leftValue != rightValue
leftValue = Function.prototype.__proto__ = Object.prototype
// 第二次判斷
leftValue === rightValue
// 返回 true
複製代碼
leftValue = Foo, rightValue = Function
leftValue = Foo.__proto__ = Function.prototype
rightValue = Function.prototype
// 第一次判斷
leftValue === rightValue
// 返回 true
複製代碼
function instance_of(L, R) {//L 表示左表達式,R 表示右表達式
var O = R.prototype;
L = L.__proto__;
while (true) {
if (L === null)
return false;
if (O === L) // 這裏重點:當 O 嚴格等於 L 時,返回true
return true;
L = L.__proto__;
}
}
// 開始測試
var a = []
var b = {}
function Foo(){}
var c = new Foo()
function child(){}
function father(){}
child.prototype = new father()
var d = new child()
console.log(instance_of(a, Array)) // true
console.log(instance_of(b, Object)) // true
console.log(instance_of(b, Array)) // false
console.log(instance_of(a, Object)) // true
console.log(instance_of(c, Foo)) // true
console.log(instance_of(d, child)) // true
console.log(instance_of(d, father)) // true
複製代碼
function instance_of(L, R) {//L 表示左表達式,R 表示右表達式
var O = R;
L = L.__proto__;
while (true) {
if (L === null)
return false;
if (O === L.constructor) // 這裏重點:當 O 嚴格等於 L 時,返回 true
return true;
L = L.__proto__;
}
}
// 開始測試
var a = []
var b = {}
function Foo(){}
var c = new Foo()
function child(){}
function father(){}
child.prototype = new father()
var d = new child()
console.log(instance_of(a, Array)) // true
console.log(instance_of(b, Object)) // true
console.log(instance_of(b, Array)) // false
console.log(instance_of(a, Object)) // true
console.log(instance_of(c, Foo)) // true
console.log(instance_of(d, child)) // false 這裏就是沒法用於判斷繼承的
console.log(instance_of(d, father)) // true
複製代碼