关于上次我总结了typeof 和 instanceof 的区别,今天在前端早读课读到对于typeof和instanceof的原理解析,故在深入学习一下。
typeof和instanceof的主要区别是typeof用于判断number, string, object, boolean, function, undefined,symbol7种基本数据类型,而instanceof用于检测Object对象的引用类型,是对typeof的补充。
在typeof和instanceof的原理解析的文章中对于typeof的本质摘抄如下:
null的低1-3位也是000,所以type of null也是object
而instanceof的原理可以看如下代码:
1 | function new_instance_of(leftVaule, rightVaule) { |
rightVaule与rightProto的原型链中的所有对象进行比较,如果相等就返回true。
也可以使用如下方法可以判断所有类型
1 | Object.prototype.toString.call(1) // "[object Number]" |
2018年5月8号
今天看了一道JS的基础面试题:
问题:如何准确判断一个变量是数组类型
答案:
1 | var arr1 = []; |
从中引出了typeof 和 instanceof 的区别和联系
查看了MDN的官方手册对于两者的用法如下:
- typeof操作符返回一个字符串,表示未经计算的操作数的类型。
用法:
1 | typeof operand |
typeof有如下返回值:
类型 | 结果 |
---|---|
Undefined | “undefined” |
Null | “object”(见下文) |
Boolean | “boolean” |
Number | “number” |
String | “string” |
Symbol (ECMAScript 6 新增) | “symbol” |
宿主对象(由JS环境提供) | Implementation-dependent |
函数对象([[Call]] 在ECMA-262条款中实现了) | “function” |
任何其他对象 | “object” |
从上图可以反映出:typeof operand返回的结果为基本类型,对于引用类型其都返回object,所以var a = [];console.log(a);返回object。
注: 使用typeof操作符的时候,如果检测对象是函数,那么操作符返回"function" ,如果检测对象是正则表达式的时候,在Safari和Chrome中使用typeof的时候会错误的返回"function"。
instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
用法:
1 | object instanceof constructor |
如下是官方例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26// 定义构造函数
function C(){}
function D(){}
var o = new C();
o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype
o instanceof D; // false,因为 D.prototype不在o的原型链上
o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回true
C.prototype instanceof Object // true,同上
C.prototype = {};
var o2 = new C();
o2 instanceof C; // true
o instanceof C; // false,C.prototype指向了一个空对象,这个空对象不在o的原型链上.
D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true
注:如果表达式 obj instanceof Foo 返回true,则并不意味着该表达式会永远返回true,因为Foo.prototype属性的值有可能会改变,改变之后的值很有可能不存在于obj的原型链上,这时原表达式的值就会成为false。另外一种情况下,原表达式的值也会改变,就是改变对象obj的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的proto魔法属性,是可以实现的。比如执行obj.proto = {}之后,obj instanceof Foo就会返回false了。
所以对于typeof和instanceof的用法——typeof一般是检测的是基本数据类型,instanceof主要检测的是引用类型!