JavaScript数据类型判断

321 阅读3分钟

JavaScript之数据类型判断

在 ECMAScript 规范中,共定义了 7 种数据类型,分为基本类型引用类型两大类,如下所示:

基本类型:String、Number、Boolean、Symbol、Undefined、Null

引用类型 :Object

基本类型: 存储在

引用类型: 存储在

引用类型除了包括Object外,还包括Array、Function、Date等等。

1、typeof


typeof 是一个操作符,其右侧跟一个一元表达式,并返回这个表达式的数据类型。返回的结果用该类型的字符串(全小写字母)形式表示,包括以下 7 种:numberbooleansymbolstringobjectundefinedfunction 等。

let num = 18;
let str = "yhd";
let show = true;
let sym = Symbol();
let data = undefined;
let info = null;

console.log(typeof num); // number
console.log(typeof str); // string
console.log(typeof show); // boolean
console.log(typeof sym); // symbol
console.log(typeof data); // undefined
console.log(typeof info); // object


let fun = function add() {};
let arr = ["yhd", "gsr"];
let obj = {name: "yhd", age: "23"};
let date = new Date();


console.log(typeof fun); // function
console.log(typeof arr); // object
console.log(typeof obj); // object
console.log(typeof date); // object

typeof判断总结:

  • 对于基本类型,除 null 以外,均可以返回正确的结果。
  • 对于引用类型,除function 以外,均返回 object 类型。
  • 对于 null ,返回 object 类型。
  • 对于 function,返回  function 类型。

2、instanceof

instanceof 可以正确判断对象的数据类型,用来判断 A 是否为  B 的实例,表达式为: A instanceof B,如果 A B 的实例,则返回 true,否则返回 false。因为内部机制是通过判断对象的原型链中是不是能找到类型的 prototype

let fun = function add() {};
let arr = ["yhd", "gsr"];
let obj = {name: "yhd", age: "23"};
let date = new Date();

console.log(fun instanceof Function); // true
console.log(arr instanceof Array); // true
console.log(obj instanceof Object); // true
console.log(date instanceof Date); // true

console.log(arr instanceof Object) // true
console.log(fun instanceof Object); // true
console.log(date instanceof Object); // true

instanceof 能够判断出 arr Array的实例,但他也认为 arr 也是 Object 的实例,为什么呢?

原因

​ 从 instanceof 中能够判断出 arr.__proto__ 指向 Array.prototype,而 Array.prototype.__proto __ 又指向了Object.prototype,最终 Object.prototype.__proto__ 指向了null,标志着原型链的结束。因此,arr、Array、Object 就在内部形成了一条原型链。

在原型链上,arr__proto__ 直接指向Array.prototype,间接指向 Object.prototype。function、date同理。

instanceof总结:

instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。


3、constructor

当一个函数被定义时,JS引擎会为函数添加 prototype 原型,然后再在 prototype上添加一个 constructor 属性,并让其指向他的构造函数

let num = 18;
let str = "yhd";
let show = true;
let sym = Symbol();
let data = undefined;
let info = null;

console.log(num.constructor); // ƒ Number() { [native code] }
console.log(str.constructor); // ƒ String() { [native code] }
console.log(show.constructor); // ƒ Boolean() { [native code] }
console.log(sym.constructor); // ƒ Symbol() { [native code] }
console.log(data.constructor); // Cannot read property 'constructor' of undefined
console.log(info.constructor); // Cannot read property 'constructor' of null

let fun = function add() {};
let arr = ["yhd", "gsr"];
let obj = {name: "yhd", age: "23"};
let date = new Date();

console.log(fun.constructor); // ƒ Function() { [native code] }
console.log(arr.constructor); // ƒ Array() { [native code] }
console.log(obj.constructor); // ƒ Object() { [native code] }
console.log(date.constructor); // ƒ Date() { [native code] }

constructor总结:

  • nullundefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
  • 函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object

4、toString

toString()Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object xxx] ,其中 xxx 就是对象的类型。

对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

Object.prototype.toString.call(1);    // [object Number]
Object.prototype.toString.call('');   // [object String]
Object.prototype.toString.call(true); // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(undefined); // [object Undefined]
Object.prototype.toString.call(null); // [object Null]

Object.prototype.toString(Object); // [object Object]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new Date()) ; // [object Date]

Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]

Object.prototype.toString.call(NaN) ; // [object Number]

toString()总结:

什么类型都可以精准判断