数据类型检测的方法有哪些

118 阅读1分钟

数据类型的检测方法

(1)typeof

console.log(typeof 2); // number 
console.log(typeof true); // boolean 
console.log(typeof 'str'); // string 
console.log(typeof []); // object 
console.log(typeof function(){}); // function 
console.log(typeof {}); // object 
console.log(typeof undefined); // undefined 
console.log(typeof null); // object

注意其中数组、对象、null都会被判断为object,其他判断都正确。

(2)instanceof

instanceof可以正确判断对象的类型,判断机制是检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

console.log(2 instanceof Number); // false 
console.log(true instanceof Boolean); // false 
console.log('str' instanceof String); // false 

console.log([] instanceof Array); // true 
console.log(function(){} instanceof Function); // true 
console.log({} instanceof Object);

不难看出,instanceof 只能用于引用数据类型的判断。

需要注意的是,如果使用 [].__proto__ = {} 之后,[] instanceof Array 就会返回 false 了,这也属于其缺点

(3)constructor

所有对象(除了使用 Object.create(null) 创建的对象除外)都将具有 constructor 属性。
在没有显式使用构造函数的情况下,创建的对象(例如对象和数组文本)将具有 constructor 属性,这个属性指向该对象的基本对象构造函数类型。(也就是使用字面量的方式创建)

const o = {}
o.constructor === Object // true

const o = new Object
o.constructor === Object // true

const a = []
a.constructor === Array // true

const a = new Array
a.constructor === Array // true

const n = new Number(3)
n.constructor === Number // true

改变constructor

  • 改变基本类型constructor,除了 null 和 undefined(因为这两者没有相应的构造函数),也就是无法更改,其余(如 StringNumberBoolean 等)都可更改,但是不会保留这些更改(也不会抛出异常)。
let val = null;
val.constructor = 1; // Cannot set properties of null (setting 'constructor')

val = 'abc';
val.constructor = Number; // val.constructor依旧是String
  • 改变引用数据类型constructor

即使改变引用数据类型constructor 的属性,也不会影响 instanceof 运算符

let a = [];
a.constructor = String
a.constructor === String // true
a instanceof String // false
a instanceof Array // true

(4)Object.prototype.toString.call().slice(8,-1)

Object.prototype.toString.call('1').slice(8,-1)  // String
Object.prototype.toString.call(1).slice(8,-1)  // Number
Object.prototype.toString.call(true).slice(8,-1) //Boolean
Object.prototype.toString.call(Symbol()).slice(8,-1)  // Symbol
Object.prototype.toString.call([]).slice(8,-1) // Array
......