JS53 判断变量类型
总结了几种判断JavaScript中变量类型的方法。
学到了
instanceof在iframe中的问题,去美团面试又被拒了吧。(2018.12.13)知其然不知其所以然,只知道可以用
intanceof和constructor,区别又不知道,去头条面试又被拒了吧(2018.12.3)
总结
最常用的判断方法是Object.prototype.slice.call(),其他判断的方法都有着各种问题:
Array.isArray判断数组,需要ES6的支持typeof有各种特殊情况instanceof对于字面量不适用,并且在iframe场景中有问题constructor是可以手动改写的
Object.prototype.toString也有着风险:Object.prototype.toString的结果可以使用Symbol.toStringTag定义(2019.02.01)
方法1 typeof
不太靠谱的方法,对于基本类型是可以的
1 | typeof 123 |
对于引用类型行不通,判断结果都是object
1 | typeof [] |
方法2:instanceof
instanceof运算符用来验证原型对象与实例对象之间的关系。
==当a.___proto___ === A.prototype成立时,instanceof返回true==
1 | var a = [], |
但是注意:
1 instanceof只对引用类型有效,==对于基本类型字面量是无效的==,因为基本类型不是对象,不存在原型链的继承关系
1 | [] instanceof Array; |
2 instanceof存在继承关系,==对于引用类型都是Object的实例==
1 | [] instanceof Array; |
3 instanceof在iframe的场景中有可能出现误判
1 | const a = [1, 2, 3]; |
可以认为宿主和iframe是两套JS的执行环境,环境中的Array是不同的,所以判断会出现问题。
方法3:constructor
实质上实例是没有constructor属性的,其constructor属性是继承自原型的:
1 | function Person(){}; |
应用时:
1 | var a = [], |
它的主要问题是:constructor是可以手动更改的,当通过原型继承时,constructor会被改写
1 | function Person() {}; |
instacnceof和constructor的区别
instanceof是操作符,而constructor是继承构造函数的原型的一个属性instanceof对于基本类型的字面量是无效的(返回false),基本类型的字面量的constructro不存在instancoeof存在继承性,引用类型都是Object的实例,而constructor是可以认为改写的
1 | undefined instanceof Object; |
方法4 Array.isArray()
ES6的Array.isArray()方法可以来判断数组的类型
1 | var a = [], |
方法5 toString方法
首先要知道,调用Object.prototype.toString返回结果都是[object xxx]的格式,例如:
1 | Object.prototype.toString.call({}) |
构造一个函数,isType,传入要验证的类型,返回值是一个新的函数:
1 | function isType(type) { |
这是一个比较稳妥的判断方法。
Object.prototype.toString也有着风险:Object.prototype.toString的结果可以使用Symbol.toStringTag定义:
1 | var o = { [Symbol.toStringTag]: "MyObject" }; |
参考
- JavaScript高级程序设计(第3版)
- 掘金 - 高阶函数,你怎么那么漂亮呢!