JS判断数据类型

JS基本数据类型

基本数据类型

String、Number、Boolean、Undefined未定义、null空、symbol表示独一无二的值(es6引入的新的原始数据基本类型)。

  • Number:返回的特殊值NaN,表示不是数值,用于表示本来要返回的数值的操作失败了。
  • String:字符串是不可变的,一旦创建,值就不能变了。做的字符串操作是先对原字符串进行销毁再创建的。
  • null:null值表示一个空对象指针,typeof null 结果是object。
  • Symbol(符号):是原始值,且实例是唯一、不可变的。用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。

引用类型

引用类型

  • 对象Object
  • 数组Array
  • 函数Function

函数存在三种常见的表达方式:

  1. 函数声明 function sum(a,b){return a+b;}
  2. 函数表达式 let sum = function(a,b){return a+b};
  3. 箭头函数 let sum = (a,b)=>{return a+b;}

方式1 Object.prototype.toString.call()

这是最准确的方式。

简单示例

1
2
3
4
5
6
7
8
9
if(Object.prototype.toString.call(data) === '[object Array]'){
console.log('数据为数组类型'
}
if(Object.prototype.toString.call(data) === '[object Object]'){
console.log('数据为对象类型'
}
if(Object.prototype.toString.call(data) === '[object String]'){
console.log('数据为字符串类型'
}

简单封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const isType = function(type){
return function(data){
return Object.prototype.toString.call(data) === '[object ' + type + ']';
}
}
const isObject = isType( 'Object' );
const isFunction = isType( 'Function' );
const isString = isType( 'String' );
const isArray = isType( 'Array' );
const isNumber = isType( 'Number' );
// 验证
console.log( isObject( {name: 'Anne'} ) ); // 输出:true
console.log( isFunction( ()=>console.log('123') ) ); // 输出:true
console.log( isString( '123' ) ); // 输出:true
console.log( isArray( [ 1, 2, 3 ] ) ); // 输出:true
console.log( isNumber( 123 ) ); // 输出:true

我们还可以用循环语句,来批量注册这些 isType 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
const Type = {};
const type = [ 'Object', 'Function', 'String', 'Array', 'Number' ];
for (let i = 0; i < type.length; i++) {
(function (i) {
Type['is' + type[i]] = function (data) {
return Object.prototype.toString.call(data) === '[object '+ type[i] +']'
}
})(i)
}
// 验证
console.log(Type.isArray([1,2,3])); // 输出:true
console.log(Type.isArray(123)); // 输出:false
console.log(Type.isNumber(123)); // 输出:true

示例

img

从实例我们可以看出该方法能判断基本类型也能判断 ArrayFunction

对于Object对象:

image-20221130182326746

实例可见,对于Object对象,可以直接使用 toString() 方法,对于其他内置对象,Object.prototype.toString.call() 方法都能准确的判断出其类型。

结论:

Object.prototype.toString.call() 方法是判断类型的最准确的方法!

方式2 typeof

typeof并不能准确的判断出arraynull,返回的都是object。

typeof对于一些类型的处理只返回了处于其原型链最顶端的object类型。
引用类型除了function返回function类型之外,其他都返回object。

  • NaN的数据类型是number
  • 数组Array和日期Date的数据类型是object
  • 不能检测出null,检测null的数据类型是object

示例

img

注意最后两个typeof nulltypeof [] 返回的都是object

调用方式

1
2
3
4
5
6
7
if(typeof("123") === "string"){
console.info("string");
}

if(typeof "123" === "string"){
console.info("string");
}

方式3 constructor

constructor无法判断nullundefined,会报错。

原型prototype的一个属性,函数被定义的时候,js引擎会为函数添加原型prototype,并且这个prototypeconstructor属性指向函数应用。
使用:

1
2
[].constructor ==Array //true
new Date().constructor == Date //true

示例

img

从实例我们可以看出:constructor判断undefined和null时,会报错。

结论:

constructor能判断基本数据类型string、number、boolean和对象类型(array、function等等),

但是它不能判断undefined和null。所以它判断类型值也不十分准确!

方式4 instanceof

instanceof不能判断基本数据类型。

用来判断A是否为B的实例,A instanceof B,如果A是B的实例,返回true否则返回false。

instanceof检测的是原型。
在这里插入图片描述

可以看出[] 的原型指向Array.prototype,间接指向Object.prototype,因此

[] instanceof Array 返回true,[] instanceof Object 也返回true。

示例

img

从上面的实例我们可以看出,

基本数据类型的值不能用 instanceof 判断类型,由于undefined和null没有构造函数,所以使用 instanceof 会报错!

而由基本数据包装类创建的对象可以用 instanceof 判断类型。

判断是否为数组

1
2
3
4
let arr = [];
Array.isArray(arr) === true;
arr.constructor === Array;
Object.prototype.toString.call(arr) === "[object Array]";