We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
number,string,null,undefined,Boolean
symbol
bigint
object,function
数据类型的检测的方法中共有四种typeof, instanceof, Object.prototype.toString.call(), constructor
typeof, instanceof, Object.prototype.toString.call(), constructor
typeof
typeof 检测原理是:在计算机底层 根据js数据类型的二进制的值进行检测的。
根据js数据类型的二进制的值进行检测的
字符串
undefined
let, const
ReferenceError
typeof undefined //"undefined" typeof a // "undefined" typeof b // "ReferenceError" let b typeof 12 //"number" typeof NaN //"number" typeof '' //"string" typeof 1n //"bigint" typeof function(){} //"function"
null
object
typeof [] //"object"
000
00000...
1
010
100
110
-2^30
typeof {} // "object" typeof [] // "object" typeof /^/ // "object"
JS 中虽然函数也是对象,但是 typeOf 判断函数是会调用 call 方法来判断。所以能判断出function
typeOf
call
function
typeof 是根据二进制值来判断数据类型的,null 的二进制值是 000,而 object 类型的二进制值都是 000 开头的,所以 typeof 检测 null 是也被检测成 object,这是一个历史里留下来的bug
instanceof 检测机制是:判断右侧的类型是否出现在左侧实例的原型链上,出现了返回的结果就是true 否则是 false。
instanceof
判断右侧的类型是否出现在左侧实例的原型链上,出现了返回的结果就是true 否则是 false
let ary = [] console.log(ary instanceof Array) // true let reg = /^/ console.log(reg instanceof RegExp) // true
true
Object
// 出现在原型链上的类型都被判断成true let ary = [] console.log(ary instanceof Object) // true function fn(){} fn.prototype = Array.prototype // 原型被修改了 let f = new fn() console.log(f instanceof Array) // true console.log(f instanceof Function) // false // 不能检测基本数组类型 console.log(1 instanceof Number) //false console.log('' instanceof String) //false console.log(false instanceof Boolean) //false
思路:根据左侧实例的原型链上是否出现右侧的类型进行判断结果。即实例.__proto__ === 类.prototype,则是true 否则是 false。对原型和原型链不熟悉的可以看 面试 | 你不得不懂得 JS 原型和原型链。
实例.__proto__ === 类.prototype
function _instanceof(example, classP) { let proto = Object.getPrototypeOf(example), classPrototype = classP.prototype while (true) { if (proto === classPrototype) { return true } if (proto === null) { return false } proto = Object.getPrototypeOf(proto) } _instanceof([], Array) //true _instanceof('', Array) // false _instanceof('', Object) // true
instanceof 检测机制是:constructor 存放的就是构造函数本身,通过存放的构造函数来检测类型。不熟悉 constructor的也可以看 面试 | 你不得不懂得 JS 原型和原型链。
constructor
let ary = [] ary.constructor === Array // true,ary.constructor ==> Array.prototype.constructor ary.constructor === String // false ary.constructor === Object // false let a = 1 a.constructor === Number // true let s = '' s.constructor === String // true
Number.prototype.constructor = 'abc' let a = 1 a.constructor === Number // false
检测机制是:利用 Object.prototype.toString 返回实例所属类的信息,通过改变 toString 中的 this 指向来返回指定参数的类型。
Object.prototype.toString
toString
this
'[object xxx]'
Object.prototype.toString.call(1) //"[object Number]" Object.prototype.toString.call('') //"[object String]" Object.prototype.toString.call(null) //"[object Null]" Object.prototype.toString.call(undefined) //"[object Undefined]" Object.prototype.toString.call(Symbol()) //"[object Symbol]" Object.prototype.toString.call([]) //"[object Array]" Object.prototype.toString.call(function(){}) //"[object Function]" Object.prototype.toString.call({}) //"[object Object]"
isNumber(), isNaN(), Array.isArray()。。。
isNumber()
isNaN()
Array.isArray()
(function () { // jquery 中的 toType let class2type = {}, toString = class2type.toString // 设定类型映射表 let arrType = ['Number', 'String', 'Boolean', 'Symbol', 'Array', 'Date', 'Error', 'RegExp', 'Function', 'Object'] arrType.forEach(item => { class2type[`[object ${item}]`] = item.toLowerCase() }); function toType(checkType) { if (checkType === null || checkType == undefined) { return checkType + '' } return typeof checkType == 'object' || typeof checkType == 'function' ? class2type[toString.call(checkType)] : typeof checkType } window.toType = toType })() toType(1) //"number" toType('') //"string" toType(null) //"null" toType(undefined) //"undefined" toType({}) //"object" toType(function(){}) //"function" toType([]) //"array"
本质上还是利用了Object.prototype.toString.call()
Object.prototype.toString.call()
(function () { function selfType(checkType) { let res = {}.toString.call(checkType).split(' ')[1].split(']')[0].toLowerCase() // 可以使用正则 return res } window.selfType = selfType })() selfType('') //"string" selfType(1) //"number" selfType(null) //"null" selfType(undefined) //"undefined" selfType(function(){}) //"function" selfType({}) //"object"
The text was updated successfully, but these errors were encountered:
No branches or pull requests
JS 中的类型
number,string,null,undefined,Boolean
,es6 新增的symbol
,es11中的
bigint
总共 7 种基本类型object,function
。数据类型的检测方式
一、
typeof
typeof
检测类型后的返回值是一个字符串
,ES5 中对于一个为定义的变量判断类型也会抛出字符串undefined
,而不是报错。但是用let, const
声明的变量也能会导致暂时性死区,抛出ReferenceError
。typeof
可以检测除了null
类型以外的数据型。null
被检测成object
这是一个历史遗留的 bug。typeof
不能检测出具体的object
类型,因为对象类型的二进制开头都是 000。比如typeof [] //"object"
检测数组,正则,日期等。000
对象,00000...
null,1
整数,010
浮点数 ,100
字符串,110
布尔值 ,-2^30
undefinedtypeOf 判断函数为什么可以判断出是 function 类型而不是 object
思考:typeof null 检测出来的结果为什么是 object
思考:0.1 + 0.2 !== 0.3 成立原因
二、滥竽充数的 instanceof
instanceof
判断返回的结果是一个 Boolean 值。instanceof
是用来检测当前的实例是否属于某个类的。可以用来解决typeof
无法检测具体的对象类型的问题。true
,那么Object
类型检测的结果永远都是true
,如果实例的原型被修改了,即使检测的结果是true
,也是不准确的。instanceof
不能检测基本数据类型。思考,模拟实现 instanceof
三、滥竽充数的 constructor
constructor
可以检测基本类型,这点比instanceof
好用constructor
和instanceof
有一样的缺陷,就是constructor
可以被修改也就是重定向四、Object.prototype.toString.call(),标准检测类型
Object.prototype.toString
返回的格式固定是'[object xxx]'
,可以检测任意类型五、其他快捷判断方式
六、封装一个万能的检测方法 toType()
1. jQuery 中的类型检测
2. 自封装一个更简单的 selfType()
The text was updated successfully, but these errors were encountered: