首先,我们知道ECMAScript中有5种简单数据类型:Undefined、Null、Boolean、Number、String和Symbol。还有一种复杂数据类型Object。
js还有三大引用类型:
Array、Object、Function
那么如何去判断一个数据的数据类型呢?
1、typeof
typeof可以帮我们分辨出如下的一些数据类型,大部分是简单数据类型:nudefined、number、string、boolean、object、function。其中null也会被返回object.
let undefined_a;
console.log("undefined_a", typeof undefined_a); //undefined_a undefined
let string_a = "string";
console.log("string_a", typeof string_a); //string_a string
let number_a = 4;
console.log("number_a", typeof number_a); //number_a number
let null_a = null;
console.log("null_a", typeof null_a); //null_a object
let boolean_a = true;
console.log("boolean_a", typeof boolean_a); //boolean_a boolean
let function_a = A;
console.log("function_a", typeof function_a); //function_a function
function A() {
return "d";
}
let Object_a = new A();
console.log("Object_a", typeof Object_a); //Object_a object
let Object_b = { a: "dd" };
console.log("Object_b", typeof Object_b); //Object_b object
var Array_a = [1, 3, 4];
console.log("Array_a", typeof Array_a); // Object_b object
let symbol_a = Symbol(1);
console.log("symbol_a", typeof symbol_a); //symbol_a symbol
这里可以看到null是被返回object,另外我分别通过工厂函数和对象字面量的方式去创建对象,通过typeof也是返回的object。由此可以看到typeof可以帮我们做一部分的类型判断
tips:
这里引发一个小思考为什么null返回的是object呢?undefined和null有什么区别呢?
首先我们看一下nudefined和null。
undefined:在使用var声明变量但是未对其加以初始化时这个变量的值就是undefined
null:一个空指针对象。所以它本质上是一个对象。
2、instanceof
这种方法在使用上和typeof有一定的区别,它是明确要求开发者指定判断类型的类型的
instanceof 运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链。
tips:以下所有都是基于对象检测来说,通过new String(),new Number()等方法等定义的也是对象。
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
console.log("Car", Array_a instanceof Object); //true
console.log("Car", Array_a instanceof Function); //true
const auto = new Car("Honda", "Accord", 1998);
console.log(Car);
console.log(auto);
console.log(auto instanceof Car);
console.log(auto.__proto__ === Car.prototype); //true
console.log(auto.__proto__.__proto__ === Object.prototype); //true
通过定义我们可以知道 instanceof 运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链即 auto.proto === Car.prototype 在实例的原型链上一层层找,这里关于原型链相关知识后期我们在讲。
以下的例子的原理基本类似上面的查找
let Array_a = [1, 3, 4];
console.log("Array_a", Array_a instanceof Object); //true
console.log("Array_a", Array_a instanceof Array); //true
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
console.log("Car", Car instanceof Object); //true
console.log("Car", Car instanceof Function); //true
3、constructor
这里使用constructor来判断数据类型的方法跟上面instanceof有相似,我们知道一个实例对象的constructor指向的是它的构造函数,那么我们可以也可以通过 constructor 去查找它的构造函数来判断数据类型
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
console.log("Car", Car instanceof Object); //true
console.log("Car", Car instanceof Function); //true
const auto = new Car("Honda", "Accord", 1998);
console.log(Car);
console.log(auto);
console.log("constructor", auto.constructor === Car);
console.log(
"constructor",
auto.constructor.constructor === Car.constructor
);
console.log("constructor", auto.constructor === Car);
console.log("constructor", auto.constructor === Object);
4、Object.prototype.toString.call()
最后是通过Object.prototype.toString.call()这样来判断
我们知道Array、Function、Object这些类型本质上是一个对象。这也是为什么使用typeof 这些数据类型都会返回object的原因。
let tostring_a = [1, 2, 3];
console.log(Object.prototype.toString.call(tostring_a)); //[object Array]
let tostring_b = { a: "b" };
console.log(Object.prototype.toString.call(tostring_b)); //[object Object]
let tostring_c = function() {
return "dd";
};
console.log(Object.prototype.toString.call(tostring_c)); //[object Function]
let tostring_d = null;
console.log(Object.prototype.toString.call(tostring_d)); //[object Null]
let tostring_date = new Date();
console.log(Object.prototype.toString.call(tostring_date)); //[object Date]
let tostring_reg = new RegExp();
console.log(Object.prototype.toString.call(tostring_reg)); //[object RegExp]