总结
- typeof 检测数据类型
优点:可以准确的判断简单数据类型(Number、String、Boolean、undefined、null)
缺点:判断复杂数据类型比较模糊(Function、Object) - instanceof 检测数据类型
优点:可以准确的判断复杂数据类型(Array、Object)
缺点:不能准确的判断简单数据类型(Number、Boolean、String) - constructor 检测数据类型
优点:可以检测简单数据类型以及复杂数据类型
缺点:由于可以修改原目标原型对象可能会使检测结果出现偏差(无法检测null和undefined) - Object.prototype.toString.call() 检测数据类型
优点:可以检测所有数据类型
缺点:方法有点长
检测数据类型的四种方式
第一种:typeof 检测数据类型
typeof操作符在进行数据类型判断的时候,可以准确的判断简单数据类型,但对于null、arr以及obj的判断则全是object。对于Array、Object等一些构造函数的判断则是function。因此,typeof操作符判断基本数据类型是准确的,但是对于复杂数据类型的判断是模糊的、不准确的。
console.log(typeof num); //number
console.log(typeof str); //string
console.log(typeof boolean); //boolean
console.log(typeof arr); //object
console.log(typeof Array); //function
console.log(typeof obj); // object
console.log(typeof Object); // function
console.log(typeof testFunction); //function
console.log(typeof testClass); //function
console.log(typeof undefined); //undefined
console.log(typeof null); //object
console.log(typeof xxx); // undefined
第二种:instanceof 检测数据类型
局限性:1.不能处理基本数据类型, 2.只要在当前实例的原型链(proto)出现的类返回值都是true(用户可能会手动修改原型链的指向,xxx.proto = example.prototype)
console.log(num instanceof Number); //false
console.log(new Number(num) instanceof Number); //true
console.log(str instanceof String); //false
console.log(new String(str) instanceof String); //true
console.log(boolean instanceof Boolean); //false
console.log(undefined instanceof Object); //false
console.log(null instanceof Object); //false
console.log(obj instanceof Object); //true
console.log(arr instanceof Array); //true
instanceof 底层代码
function Instanceof (source, target) {
// 基本数据类型以及 null 直接返回 false
if (!['function', 'object'].includes(typeof source) || source === null) return false
// getProtypeOf 是 Object 对象自带的一个方法,能够拿到参数的原型对象
let proto = Object.getPrototypeOf(source)
while (true) {
// 查找到尽头,还没找到
if (proto == null) return false
// 找到相同的原型对象
if (proto == target.prototype) return true
proto = Object.getPrototypeOf(proto)
}
}
第三种:constructor 检测数据类型
constructor主要是利用原型上的prototype.constructor指向实例的构造函数来进行判断的
第四种:Object.prototype.toString.call() 检测数据类型
在所有的数据类型中,他们的原型都有toString方法,除Object.prototype.toString不是把数据值转换成字符串而是检测当前实例隶属类的详细信息,其它的都是转换成字符串。
let _obj = {}
_obj.toString.call(100)方法等价于Object.prototype.toString.call(100),
原理:改变this为100,100也是一个Number实例,让里面的this变成Number类实例,都是借住Object.prototype.toString方法执行。
JavaScript 规定了几种数据类型?
Javascript是一种弱类型或者说动态语言。最新的ECMAScript标准定义了7种数据类型。6 种原始类型: Boolean Null Undefined Number String Symbol(es6新增) Object BigInt
那function是不是一种数据类型?
按照spec,typeof只是一个运算符,其返回值并不能作为JS数据类型的依据
函数也是引用类型为什么typeof返回function而不是object?
ECMA-262中规定任何在内部实现call方法的对象都应该在应用typeof操作符时返回"function"
创建值的两种方式?(不管那种方式都是Number类的实例)
let n =12
let num= new Number();