Open SlowSoulWen opened 4 years ago
优化一下 instanceOf
的写法 👇
function instanceOf(object, constroctor) {
let leftProto = object.__proto__;
let rightPrototype = constroctor.prototype;
if (!leftProto || !rightPrototype) {
return false;
}
while(leftProto) {
if (leftProto === rightPrototype) {
return true;
}
leftProto = leftProto.__proto__;
}
return false
}
typeof
typeof 操作符返回一个字符串,表示未经计算的操作数的类型。
通常而言
typeof
只能用来检测基本类型,以及一些特定的类型比如function
,其他的对象都会返回object
。注意:除了Function之外,所有构造函数的类型(通过new生成的类型)都是“object”
JS在底层存储变量的时候,会在变量的机器码的低位1-3位存储其类型信息:
由于
null
对应的机器码为0,所以typeof
在做判断的时候,就会把null
当做对象来看待。instanceof
instanceof
运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。注意:多个窗口意味着多个全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。所以在存在
iframe
的情况下,慎重使用instanceof
。instanceof
的实现原理不难,只要判断右值构造函数的prototype
在左值的原型链上,则返回true
。关于原型链的问题盗一张图来解释会更明白:
有几个比较重要的点:
__proto__
属性,叫做隐式原型,指向了构造该对象的构造函数的原型
。prototype
,叫做原型属性,这个属性是个对象,它存放了所有实例共享的属性和方法(我们经常用fun.prototype.sayHi = function() {}
给实例添加方法)。constructor
,它指回了原构造函数。手写代码实现
instanceof
功能:Object.prototype.toString
Object.prototype.toString
就比较牛叉了,属于万金油式的存在,是唯一一个能够准确判断内建类型的方法。关于
Object.prototype.toString
的原理,这里贴一下ECMAScript 5
对该方法的解释:[[Class]] 一个字符串值,表明了该对象的类型. 然后给了一段解释:
所有内置对象的[[Class]]属性的值是由本规范定义的.所有宿主对象的[[Class]]属性的值可以是任意值,甚至可以是内置对象使用过的[[Class]]属性的值.[[Class]]属性的值可以用来判断一个原生对象属于哪种内置类型.需要注意的是,除了通过Object.prototype.toString方法之外,本规范没有提供任何其他方式来让程序访问该属性的值。
ECMAScript 6
对Object.prototype.toString
又做了进一步的定义与修改,且改动较大,但是在使用上没有明显区别(相关链接)