前言
在 JavaScript 中,数据类型分为两大类,一种是根底数据类型,另一种则是简单数据类型,又叫援用数据类型
- 根底数据类型:数字 Number 字符串 String 布尔 Boolean Null Undefined Symbols BigInt
- 援用数据类型:日期 Dete,对象 Object,数组 Array, 办法 Function, 正则 regex, 带键的汇合:Maps, Sets, WeakMaps, WeakSets
根底数据类型和援用数据类型的区别,在之前深拷贝的文章中提到过,这里不做具体赘述。
传送门:javaScript 中深拷贝和浅拷贝简略梳理
常见的几种数据校验形式
接下来会针对上面几种数据类型,进行校验
// 根本数据类型
let str = "abc";
let num = 123;
let boo = true;
let undef = undefined;
let testNull = null;
let symb = Symbol("user");
let bigInt = BigInt(9007199254740999);
// 简单 - 援用数据类型
let arr = [1, 2, 3, 4];
let func = function () {};
let obj = {};
let date1 = new Date();
let setObj1 = new Set();
let setObj2 = new Set([1, 2, 3]);
let mapObj = new Map();
typeof 操作符
typeof 操作符,会返回一个字符串,示意未经计算的操作数的类型
/**
* typeof 操作符
*
* 返回一个字符串,示意未经计算的操作数的类型。*
* */
console.log(typeof str); // string
console.log(typeof num); // number
console.log(typeof boo); // boolean
console.log(typeof undef); // undefined
console.log(typeof testNull); // object
console.log(typeof symb); // symbol
console.log(typeof bigInt); // bigint
console.log(typeof Object(bigInt)); // object
console.log(typeof arr); // object
console.log(typeof func); // function
console.log(typeof obj); // object
console.log(typeof date1); // object
console.log(typeof setObj1); // object
console.log(typeof setObj2); // object
console.log(typeof mapObj); // object
小结
应用 typeof 操作符的时候,咱们能够看到一些较为非凡的状况:
- null,数组 array,set,map 返回的是对象 object
instanceof
instanceof 用于检测构造函数的 prototype 属性是否呈现在某个实例对象的原型链上。
/**
*
* instanceof
*
* 用于检测构造函数的 prototype 属性是否呈现在某个实例对象的原型链上。*
* */
console.log(str instanceof String); // false
console.log(new String("abc") instanceof String); // true
console.log(num instanceof Number); // false
console.log(new Number(123) instanceof Number); // true
console.log(boo instanceof Boolean); // false
console.log(new Boolean(true) instanceof Boolean); // false
console.log(undef instanceof undefined);
// Uncaught TypeError: Right-hand side of 'instanceof' is not an object
console.log(testNull instanceof null);
// Uncaught TypeError: Right-hand side of 'instanceof' is not an object
console.log(symb instanceof Symbol); // false
// Symbol 不是构造函数,没有 new 操作符
console.log(bigInt instanceof BigInt); // false
console.log(Object(BigInt("22")) instanceof Object); // true
console.log(Object(BigInt("22")) instanceof BigInt); // true
console.log(arr instanceof Array); // true
console.log(arr instanceof Object); // true
console.log(func instanceof Function); // true
console.log(func instanceof Object); // true
console.log(obj instanceof Object); // true
console.log(obj instanceof Function); // false
console.log(null instanceof Object); // false
console.log(date1 instanceof Object); // true
console.log(setObj1 instanceof Object); // true
console.log(setObj2 instanceof Object); // true
console.log(mapObj instanceof Object); // true
console.log(setObj1 instanceof Array); // false
console.log(setObj2 instanceof Array); // false
console.log(mapObj instanceof Array); // false
constructor
/**
* constructor
*
* 返回创立实例对象的 构造函数的援用。*
* 留神,此属性的值是对函数自身的援用,而不是一个蕴含函数名称的字符串
*
* 构造函数.prototype.constructor()
*
* */
// 根本数据类型
let str = "abc";
let num = 123;
let boo = true;
let undef = undefined;
let testNull = null;
let symb = Symbol("user");
let bigInt = BigInt(9007199254740999);
// 简单 - 援用数据类型
let arr = [1, 2, 3, 4];
let func = function () {};
let obj = {};
let date1 = new Date();
function constructorFn() {this.name = "11";}
let con1 = new constructorFn();
let setObj1 = new Set();
let setObj2 = new Set([1, 2, 3]);
let mapObj = new Map();
console.log(str.constructor); // String
console.log(num.constructor); // Number
console.log(boo.constructor); // Boolean
// console.log(testUndefined.constructor); // Cannot read property 'constructor' of undefined
// console.log(testNull.constructor); // Cannot read property 'constructor' of null
console.log(symb.constructor); // Symbol
console.log(bigInt.constructor); // BigInt
console.log(arr.constructor); // Array
console.log(func.constructor); // Function
console.log(obj.constructor); // Object
console.log(date1.constructor); // Date
console.log(constructorFn.constructor); // Function
console.log(con1.constructor); // constructorFn
console.log(setObj1.constructor); // Set
console.log(setObj2.constructor); // Set
console.log(mapObj.constructor); // Map
/**
*
* 构造函数校验
*
* */
console.log(Function.constructor); // Function
console.log(Object.constructor); // Function
console.log(Array.constructor); // Function
console.log(Date.constructor); // Function
Object.prototype.toString.call && Object.prototype.toString.apply
Object.prototype.toString()
在应用 Object.prototype.toString.call 或者 Object.prototype.toString.apply 查看数据类型之前,咱们先理解一下 Object.prototype.toString 和 JavaScript 中的构造函数 Function 的原型办法 apply 和 call:
/**
* 返回一个示意该对象的字符串
*
* Object.prototype.toString()
*
* 每个对象都有一个 toString() 办法,当该对象被示意为一个文本值时,或者一个对象以预期的字符串形式援用时主动调用。* 默认状况下,toString() 办法被每个 Object 对象继承。*
* 如果此办法在自定义对象中未被笼罩,toString() 返回 "[object type]",其中 type 是对象的类型。以下代码阐明了这一点:*
* */
let isObj = {name: "zhangsan"};
let isBoolean = true;
let isNumber = new Number(123);
let isString = "abc";
let isFun = new Function();
console.log(isObj.toString()); // [object Object]
console.log(isBoolean.toString()); // true
console.log(isNumber.toString()); // 123
console.log(isString.toString()); // abc
console.log(new Date().toString()); // Thu Apr 28 2022 16:37:19 GMT+0800 (中国规范工夫)
console.log(isFun.toString()); // function anonymous() {}
call && apply
/**
*
* call() 应用一个指定的 this 值和独自给出的一个或多个参数来调用一个函数,function.call(thisArg, arg1, arg2, ...)
*
* apply() 应用一个指定的 this 值和独自给出的一个或多个参数来调用一个函数,unc.apply(thisArg, [argsArray])
*
* */
// call 根本应用;
function a() {console.log(this);
}
function b() {console.log(this);
}
a.call(b); // function b() {}
b.call(a); // function a() {}
- call 和 apply 最简略的例子表明了,扭转了以后办法的 this 指向
- 同时这两个办法的区别在于传参的形式
Object.prototype.toString 联合 Function.prototype.call && apply
/**
*
* 应用 toString() 检测对象类型能够通过 toString() 来获取每个对象的类型。* 为了每个对象都能通过 Object.prototype.toString() 来检测,* 须要以 Function.prototype.call() 或者 Function.prototype.apply() 的模式来调用,传递要查看的对象作为第一个参数,称为 thisArg。*
* 那么 Object.prototype.toString 相当于 原生构造函数的实例化对象 isNumber,传参数给 Object.prototype.toString 执行
* 实际上相当于 toString.call(new ***);
*
* */
let str = "abc";
let num = 123;
let boo = true;
let undef = undefined;
let testNull = null;
let symb = Symbol("user");
let bigInt = BigInt(9007199254740999);
// 简单 - 援用数据类型
let arr = [1, 2, 3, 4];
let func = function () {};
let obj = {};
let date1 = new Date();
function testFun() {}
let newTest = new testFun();
let newFun = new Function();
let setObj1 = new Set();
let setObj2 = new Set([1, 2, 3]);
let mapObj = new Map();
console.log(Object.prototype.toString.apply(new String("sss"))); // [object String]
console.log(Object.prototype.toString.apply(str)); // [object String]
console.log(Object.prototype.toString.call(num)); // [object Number]
console.log(Object.prototype.toString.call(boo)); // [object Boolean]
console.log(Object.prototype.toString.call(undef)); // [object Undefined]
console.log(Object.prototype.toString.call(testNull)); // [object Null]
console.log(Object.prototype.toString.call(symb)); // [object Symbol]
console.log(Object.prototype.toString.call(Object(bigInt))); // [object BigInt]
console.log(Object.prototype.toString.call(bigInt)); // [object BigInt]
console.log(Object.prototype.toString.apply(arr)); // [object Array]
console.log(Object.prototype.toString.call(func)); // [object Function]
console.log(Object.prototype.toString.call(obj)); // [object Object]
console.log(Object.prototype.toString.call(date1)); // [object Date]
console.log(Object.prototype.toString.call(testFun)); // [object Function]
console.log(Object.prototype.toString.call(newTest)); // [object Object]
console.log(Object.prototype.toString.call(newFun)); // [object Function]
console.log(Object.prototype.toString.call(setObj1)); // [object Set]
console.log(Object.prototype.toString.call(setObj2)); // [object Set]
console.log(Object.prototype.toString.call(mapObj)); // [object Map]
其余校验数据类型的办法:
判断是否是数组:
console.log(Array.isArray([1, 2])); // true
判断一个对象是否是空对象
// 判断空对象
function isEmptyObj(obj) {for (name in obj) {console.log(name);
return false; // 不是空对象
}
return true;
}
console.log(isEmptyObj({})); // true
总结
- 不论是 typeof 操作符,还是其余的操作方法,都有各自的缺点
- 在日常的开发过程中,咱们须要晓得以后操作的是对象,还是构造函数生成的对象或者办法,能力针对以后须要判断的数据类型,采纳最适宜的办法
- Object.prototype.toString.call 或者 Object.prototype.toString.apply 应该是最欠缺的办法,在咱们不确定是否是援用类型或者根本数据类型的时候,倡议作为首选
- 在理解这些判断数据类型的形式之前或者说存有疑难:为什么 array 数组在应用 instanceof 和 typeof 校验 Object 的时候都成立,这时候须要去理解一下援用数据类型的具体内容
- 以上判断数据类型的办法,能够在我的项目开发过程中,能够写入到 utils 公共办法当中,作为开发中进行应用。
- 更多用法期待补充。
源码地址
-
码云 https://gitee.com/lewyon/vue-note
-
githup https://github.com/akari16/vue-note
文章集体博客地址:深度解析 javaScript 常见数据类型查看校验
欢送关注公众号:程序猿布欧,不定期更新一些前端入门文章
创作不易,转载请注明出处和作者。