谈到检测JaveScript中数据的类型,那么我们先了解一下JaveScript中数据有哪些类型
这里不考虑ES6新增第七种Symbol数据类型,它的实例是唯一且不可改变的类型的值以及BigInt,他 是一种数字类型的数据
目录
JaveScript的数据类型
基本数据类型
- Number 数字类型
- 根据 ECMAScript 标准,JavaScript 中只有一种数字类型:基于 IEEE 754 标准的双精度 64 位二进制格式的值(-(253 -1) 到 253 -1),他除了可以表示我们常见的一些数值外,还包含了一些特殊的带符号的值:+Infinity(正无穷),-Infinity (负无穷)和 NaN (非数值)
- String 字符串类型
- 用于表示文本数据。字符串的长度是它的元素的数量。JavaScript 字符串是不可更改的。这意味着字符串一旦被创建,就不能被修改。但是,可以基于对原始字符串的操作来创建新的字符串,如获取一个字符串的子串可通过选择个别字母或者使用 String.substr()截取,两个字符串的连接使用连接操作符 (+) 或者 String.concat()拼接
- Boolean 布尔类型
- 布尔表示一个逻辑实体,可以有两个值:true 和 false。
- underfined类型
- 一个没有被赋值的变量会有个默认值 undefined
- null 类型
- null 类型只有一个值: null
引用数据类型
- Object 对象
- Function 函数,这里也可以归纳为object,因为所有函数都是对象
这里我们基本弄清了数据的基本类型,下面开始讲解怎么检测他们的类型
数据的类型检测
1. typeof()
- typeof 操作符返回一个字符串,表示未经计算的操作数的类型
- 返回值,见下表
该方法比较适合判断基本类型,要注意的是null返回的是object
2. 验证原型对象 --获取对象的隐式原型
- Object.getPrototypeOf() ,返回给定对象的原型。如果没有继承的属性,则返回null
- Object.prototype.isPrototypeOf() ,返回一个布尔值,表示指定的对象是否在本对象的原型链中
原型链发生改变时尽量不要用
3.验证构造函数
- 对象.constructor ,返回创建实例对象的 Object 构造函数的引用。注意,此属性的值是对函数本身的引用,而不是一个包含函数名称的字符串。对原始类型来说,如1,true和"test",该值只可读
- instanceof 运算符,他用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
原型链发生改变时尽量不要用
4. 检查内部属性class每个对象创建时使用的类型的属性 Object.prototype.toString()方法
5. ES5中的新增方法
如is Array()判断是不是数组类型等等,这里可以直接查询官网
Object.prototype.toString.call()这里用call()是为了改变this指向,这里用apply也可达到这种效果,把要检测的对象放进括号
上面都是枯燥的文字,下面上个小例子,分别演示2,3,4方法,输出直接放在后面,以便直接对比
var obj1 = {};
var obj2 = [1, 2]
var obj3 = {};
// 这一步相当于把obj3.__proto__=obj2;
Object.setPrototypeOf(obj3, obj2)
// 2验证原型对象
// 获取对象的隐式原型
// 当用这种方法的时候 当隐式原型改变的这里无法验证
// Object.getPrototypeOf() 返回给定对象的原型。如果没有继承的属性,null则返回
console.log(Object.getPrototypeOf(obj1) === Array.prototype) //false
console.log(Object.getPrototypeOf(obj2) === Array.prototype) //true
console.log(Object.getPrototypeOf(obj3) === Array.prototype) //false
console.log(Object.getPrototypeOf(obj3) === Object.prototype) //false
// Object.prototype.isPrototypeOf() 返回一个布尔值,表示指定的对象是否在本对象的原型链中
console.log(Array.prototype.isPrototypeOf(obj1)) //false
console.log(Array.prototype.isPrototypeOf(obj2)) //true
console.log(Array.prototype.isPrototypeOf(obj3)) //true
// 3验证构造函数
// 当用这种方法的时候 当隐式原型改变的这里无法验证
// constructor 返回创建实例对象的 Object 构造函数的引用。
console.log(obj1.constructor === Array) //false
console.log(obj2.constructor === Array) //true
console.log(obj3.constructor === Array) //true
// instanceof判断函数的原型是否在对象的原型链家族上
console.log(obj1 instanceof Array) //false
console.log(obj2 instanceof Array) //true
console.log(obj3 instanceof Array) //true
// 4 检查内部属性class每个对象创建时使用的类型的属性 ,
// toString() 只能是Object.prototype中的toString方法才可以获取
// obj1.toString()"[object Object]" 后一个是构造函数
// call改变this指向
console.log(Object.prototype.toString.call(obj2) === "[object Array]") //true
console.log(Object.prototype.toString.call(obj3) === "[object Array]") // false
console.log(Object.prototype.toString.call(obj1) == "[object Array]") //false