方式一:通过constructor
通过constructor可以直接找到元素的构造函数类型,这种方法能够区分引用数据类型到底是哪种类型,请看下面的例子。
const arr = [1,2,3,5];
const date = new Date();
const num = 666;
const map = new Map();
const set = new Set();
const reg = new RegExp();
const str = '111';
const sym = Symbol(66);
const func = function(){}
// 需要注意的是null和undefined没有constructor
console.log(arr.constructor === Array); // true
console.log(date.constructor === Date); // true
console.log(num.constructor === Number); // true
console.log(map.constructor === Map); // true
console.log(set.constructor === Set); // true
console.log(reg.constructor === RegExp); // true
console.log(str.constructor === String); // true
console.log(sym.constructor === Symbol); // true
console.log(func.constructor === Function); // true
需要特别注意的是null和undefined没有constructor属性。
方式二:使用instanceof来判断引用类型到底属于哪种类型
const arr = [1,2,3,5];
const date = new Date();
const map = new Map();
const set = new Set();
const reg = new RegExp();
const func = function(){}
console.log(arr instanceof Array); // true
console.log(date instanceof Date); // true
console.log(map instanceof Map); // true
console.log(set instanceof Set); // true
console.log(reg instanceof RegExp); // true
console.log(func instanceof Function); // true
需要特别注意的是:instanceof 不适用于判断基本类型。
方式三:使用typeof来判断基本数据类型
需要注意的是typeof能够帮助我们判断出基本数据类型和函数,但是引用数据类型一般是object。
const arr = [1,2,3,5];
const date = new Date();
const num = Number(666);
const map = new Map();
const set = new Set();
const reg = new RegExp();
const str = '111';
const sym = Symbol(66);
const func = function(){}
// 需要注意的是null和undefined没有constructor
console.log(typeof arr); // object
console.log(typeof date); // object
console.log(typeof num); // number
console.log(typeof map); // object
console.log(typeof set); // object
console.log(typeof reg); // object
console.log(typeof str); // string
console.log(typeof sym); // symbol
console.log(typeof func); //function
方式四:通过Object.prototype.toString.call()精准确定类型(强烈推荐)
需要注意的是这个方法输出的是一个字符串,这个字符串object是小写的,后面的是大写的。
const arr = [1,2,3,5];
const date = new Date();
const num = Number(666);
const map = new Map();
const set = new Set();
const reg = new RegExp();
const str = '111';
const sym = Symbol(66);
const func = function(){}
console.log(Object.prototype.toString.call(arr)); // [object Array]
console.log(Object.prototype.toString.call(date)); // [object Date]
console.log(Object.prototype.toString.call(num)); // [object Number]
console.log(Object.prototype.toString.call(map)); // [object Map]
console.log(Object.prototype.toString.call(set)); // [object Set]
console.log(Object.prototype.toString.call(reg)); // [object RegExp]
console.log(Object.prototype.toString.call(str)); // [object String]
console.log(Object.prototype.toString.call(sym)); // [object Symbol]
console.log(Object.prototype.toString.call(func)); // [object Function]
问题汇总
RQ1:如何判断一个对象是一个空对象?
- 通过Reflect.ownKeys的长度为零。Reflect.ownKys()可以返回一个由目标对象自身的属性组成的数组。
const obj = {};
console.log(Reflect.ownKeys(obj).length === 0); // true
- 通过JSON.stringify()
const obj = {};
console.log(JSON.stringify(obj) === '{}'); // true
RQ2:有什么方法可以获取对象的key?
- 使用Object.keys()
- 使用Reflect.ownKeys()
RQ3:对象的中括号运算符和点运算符有什么区别?
中括号中可以用变量,但是点后面不能是一个变量。
const obj = {};
obj.name = '111';
const myName = 'name'
console.log(obj.myName); // undefined
console.log(obj[myName]); // 111