前言
JavaScript是web前端广泛应用的语言之一,在网页应用制作、脚本制作、小程序等诸多领域具有不可替代的的地位。笔者学习了一端时间的前端,颇感JS知识点的繁碎,故将学习到的一些知识、思考和感悟记录下来。
JS基本类型
JavaScript的基本类型分为原始基本类型和引用数据类型:
原始基本类型:
- number
- string
- boolean
- null
- undefined
- symbol
引用数据类型:
- Object
- Function
- Array
- Date
- RegExp
注意:ES5中没有symbol类型
类型检测
类型检测有5中常见的方法:
- typeof
- instanceof
- Object.prototype.toString
- constructor
- duck type
1.typeof 判断基本类型
使用关键字 typeof 返回的是类型名仅包括以下 7 种:number、string、boolean、undefined、symbol、object、function 。
null和大部分的引用类型都不能用 typeof 进行判断。
let num = 32 let str = "32" let bool = true let nul = null let undef = undefined let sym = Symbol() const obj = new Object() const arr = new Array() const fun = new Function() const date = new Date() const reg = new RegExp() console.log(typeof num) //number console.log(typeof str) //string console.log(typeof bool) //boolean console.log(typeof nul) //object console.log(typeof undef) //undefined console.log(typeof sym) //symbol console.log(typeof obj) //object console.log(typeof arr) //object console.log(typeof fun) //function console.log(typeof date) //object console.log(typeof reg) //object
注意:用typeof判断null、Array、Date、RegExp等类型结果均为object
2.instanceof 判断引用数据类型
instanceof利用的是变量的__proto__属性指向原型的prototype属性进行类型判断,需要注意的是,如果对基本数据类型使用直接赋值的方法,则__proto__属性是不存在的,我们需要使用构造函数。
const obj = new Object() const arr = new Array() const fun = new Function() const date = new Date() const reg = new RegExp() console.log(obj instanceof Object) //true console.log(arr instanceof Array) //true console.log(fun instanceof Function) //true console.log(date instanceof Date) //true console.log(reg instanceof RegExp) //true let num1 = 32 let num2 = new Number(32) console.log(num1 instanceof Number) //false console.log(num2 instanceof Number) //true
另外,虽然 instanceof 能够判断出arr是Array的实例,但它认为也是Object的实例,这对判断一个未知引用类型并不友好。
const arr = new Array() console.log(arr instanceof Array) //true console.log(arr instanceof Object) //true
原因是 arr.__proto__的__proto__属性指向Object的原型对象。
对于这种情况,可以换用 constructor 进行判断。
注意:不同window或iframe间的对象检测不能使用instanceof !
3.Object.prototype.toString 判断类型
toString() 是 Object 的原型方法,每一个继承 Object 的对象都有 toString 方法。
所有使用 typeof 返回值为 object 的对象都包含一个内部属性[[class]],这个属性无法直接访问,一般通过Object.prototype.toString()来查看。
如果 toString 方法没有重写的话,默认返回当前对象的 [[Class]],其格式为[object Xxx],其中 Xxx 为对象的类型。但除了 Object 类型的对象外,其他类型直接使用 toString 方法时,会直接返回都是内容的字符串,所以我们需要使用call或者apply方法来改变toString方法的执行上下文。
let num = 32 let str = "32" let bool = true let nul = null let undef = undefined let sym= Symbol() const obj = new Object() const arr = new Array() const fun = new Function() const date = new Date() const reg = new RpgExp() console.log(Object.prototype.toString.apply(num)) //"[object Number]" console.log(Object.prototype.toString.apply(str)) //"[object String]" console.log(Object.prototype.toString.apply(bool)) //"[object Boolean]" console.log(Object.prototype.toString.apply(nul)) //"[object Null" console.log(Object.prototype.toString.apply(undef)) //"[object Undefined]" console.log(Object.prototype.toString.apply(sym) //"[object Symbol]" console.log(Object.prototype.toString.call(obj)) //"[object Object]" console.log(Object.prototype.toString.call(arr)) //"[object Array]" console.log(Object.prototype.toString.call(fun)) //"[object Function]" console.log(Object.prototype.toString.call(date)) //"[object Date]" console.log(Object.prototype.toString.call(reg) //"[object RegExp]"
Object.prototype.toString可以判断null,但习惯上我们用 null===null来判断是否为null。
4.constructor判断类型
constructor属性会返回变量的构造函数,当然也可以利用字符串截取获取构造函数名称进行判断来获取布尔值,如” “.constructor === String。
let num = 32 let str = "32" let bool = true let nul = null let undef = undefined let sym= Symbol() const object = new Object() const arr = new Array() const fun = new Function() const date = new Date() const reg = new RegExp() console.log(num.constructor) //ƒ Number() { [native code] } console.log(str.constructor) //ƒ String() { [native code] } console.log(bool.constructor) //ƒ Boolean() { [native code] } console.log(nul.constructor) //Uncaught TypeError: Cannot read property 'constructor' of null console.log(undef.constructor) //Uncaught TypeError: Cannot read property 'constructor' of undefined console.log(sym.constructor) //ƒ Symbol() { [native code] } console.log(obj.constructor === Object) //true console.log(arr.constructor === Array) //true console.log(fun.constructor === Function) //true console.log(date.constructor === Date) //true console.log(reg.constructor === RegExp) //true
无法用constructor判断null和undefined,但可以避免使用instanceof时arr的原型对象既可以为Array也可以是Object。
5.duck type 利用特征来判断类型
在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由”当前方法和属性的集合”决定。
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
在鸭子类型中,关注点在于对象的行为,能作什么;而不是关注对象所属的类型。
例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为”鸭子”的对象,并调用它的”走”和”叫”方法。
随后,在使用鸭子类型的函数中,可以接受一个任意类型的对象,并调用它的”走”和”叫”方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的”走”和”叫”方法的对象都可被函数接受。
比如判断一个对象是否是数组,可以看这个对象是否拥有push()等方法
总结
到此这篇关于JavaScript类型检测的文章就介绍到这了,更多相关JavaScript类型检测内容请搜索NICE源码以前的文章或继续浏览下面的相关文章希望大家以后多多支持NICE源码!