1. 有哪些数据类型
JS 中共有7种数据类型,包括基本类型(原始类型)和引用类型。
- 其中,基本数据类型有7种,分别是:string、number、boolean、undefined、null、symbol、bigInt
symbol 是 ES6 新增的数据类型,表示独一无二的值,通过 symbol() 函数生成(不能通过 new 调用) - 引用类型有object、function、array
2. 怎么区分数据类型
(1)typeof
通过 typeof 运算符(返回字符串),可以准确的判断基础数据类型和function,但不能区分object类型的具体类型,比如 Array 、Date 以及自定义类
typeof (() => {}) // function
typeof [] // object
// 实现typeof
function _typeof(params) {
const res = Object.prototype.toString.call(params).slice(8, -1)
let map = {
Number: 'number',
Array: 'object',
String: 'string',
Object: 'object',
Null: 'null',
undefined: 'undefined',
Symbol: 'symbol',
Boolean: 'boolean',
Function: 'function'
}
return map[res]
}
(2)instanceof
通过 instanceof 关键字来实现(返回布尔值),本意是用来判断 A 是否为 B 的实例对象。能够正确判断[] 是Array的实例对象,但不能辨别 [] 不是Object的实例对象。不能判断基本数据类型
(() => {}) instanceof Object // true
[] instanceof Object // true
// 实现instanceof
function new_instance_of(leftVaule, rightVaule) {
let rightProto = rightVaule.prototype;
leftVaule = leftVaule.__proto__;
while (true) {
if (leftVaule === null) {
return false;
}
if (leftVaule === rightProto) {
return true;
}
leftVaule = leftVaule.__proto__
}
(3)constructor
constructor 原本就是用来进行对象类型判断的,但是还有一个作用就是:每一个对象实例都可以通过 constrcutor 对象访问它的构造函数
判断引用类型,不能判断基本数据类型
let arr = function fn() {}
console.log(arr.constructor); // ƒ Function() { [native code] }
console.log(Function.prototype.constructor === Function); // true
以上这三种方法都不是区分数据类型的最佳实现
(4)Object.prototype.toString()
Object.prototype.toString.call({}) // '[object Object]'
Object.prototype.toString.call([]) // '[object Array]'
Object.prototype.toString.call(() => {}) // '[object Function]'
Object.prototype.toString.call('seymoe') // '[object String]'
Object.prototype.toString.call(1) // '[object Number]'
Object.prototype.toString.call(true) // '[object Boolean]'
Object.prototype.toString.call(Symbol()) // '[object Symbol]'
Object.prototype.toString.call(null) // '[object Null]'
Object.prototype.toString.call(undefined) // '[object Undefined]'
Object.prototype.toString.call(new Date()) // '[object Date]'
Object.prototype.toString.call(Math) // '[object Math]'
Object.prototype.toString.call(new Set()) // '[object Set]'
Object.prototype.toString.call(new WeakSet()) // '[object WeakSet]'
Object.prototype.toString.call(new Map()) // '[object Map]'
Object.prototype.toString.call(new WeakMap()) // '[object WeakMap]'
// 更显眼的方式
function checkType(obj) {
return Object.prototype.toString.call(obj).slice(8,-1)
}