typeof和instanceof
typeof
释义
- 是一个一元运算符,放在一个运算符之前,运算符可以是任意类型
typeof 来判断number, string, object, boolean, function, undefined, symbol 这七种类型- 局限性:判断引用类型时候,返回都是
object
实现原理机制
- js在底层存储变量的时候,会在变量的机器码的低位1-3位存储其类型信息
- 000: 对象
- 010:浮点数
- 100: 字符串
- 110: 布尔
- 1: 整数
- 对于undefined和null比较特殊
null: 所有机器码均为0,直接被当做对象来看待undefined:用-2^30整数来表述
- 还有一个判断类型的方法:
Object.prototype.toString-
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
释义
- instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的prototype属性,用于判断一个变量是否某个对象的实例
- 判断规则:instanceof运算符的第一个变量是一个对象,暂称为A;第二个变量一般是个函数,暂称为B。沿着A的
_proto_这条线来找,同时沿着B的prototype这条线来找,如果两条线能找到同一个引用,就返回true,如果终点都没有哦重合就返回false
instanceof 操作符的实现原理
- 根据ECMAScript语言规范,整理了一下代码
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__
}
}
-
原理就是只要右边变量的
prototype在左边变量的原型链上即可。因此,instanceof在查找的过程中会遍历左边变量的原型链,直到找到右边变量的prototype,如果查找失败则会范湖false- 示例
function Foo() {} Object instanceof Object // true Function instanceof Function // true Function instanceof Object // true Foo instanceof Foo // false Foo instanceof Objet // true Foo instanceof Function // true-
Object instanceof Object- Object 的 prototype 属性是 Object.prototype, 而由于 Object 本身是一个函数,由 Function 所创建,所以 Object.proto 的值是 Function.prototype,而 Function.prototype 的 proto 属性是 Object.prototype,所以我们可以判断出,Object instanceof Object 的结果是 true 。用代码简单的表示一下
- Function instanceof Function 和 Function instanceof Object 的运行过程与 Object instanceof Object 类似
leftValue = Object.__proto__ = Function.prototype; rightValue = Object.prototype; // 第一次判断 leftValue != rightValue leftValue = Function.prototype.__proto__ = Object.prototype // 第二次判断 leftValue === rightValue // 返回 true -
Foo instanceof Foo- 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 // 返回 falseFoo instanceof Object
leftValue = Foo, rightValue = Object leftValue = Foo.__proto__ = Function.prototype rightValue = Object.prototype // 第一次判断 leftValue != rightValue leftValue = Function.prototype.__proto__ = Object.prototype // 第二次判断 leftValue === rightValue // 返回 trueFoo instanceof Function
leftValue = Foo, rightValue = Function leftValue = Foo.__proto__ = Function.prototype rightValue = Function.prototype // 第一次判断 leftValue === rightValue // 返回 true -
主要的作用就是判断一个实例是否属于某种类型
let person = function () {}
let nicole = new person()
nicole instanceof person // true
- 也可以判断一个实例是否是其父类型或者祖先类型的实例
let person = function () {}
let pro = function () {}
pro.prototype = new person()
let n = new pro()
n instanceof person // true
n instanceof pro // true