方式一:通过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:如何判断一个对象是一个空对象?

  1. 通过Reflect.ownKeys的长度为零。Reflect.ownKys()可以返回一个由目标对象自身的属性组成的数组。
const obj = {};

console.log(Reflect.ownKeys(obj).length === 0);  // true
  1. 通过JSON.stringify()
const obj = {};

console.log(JSON.stringify(obj) === '{}');  // true

RQ2:有什么方法可以获取对象的key?

  1. 使用Object.keys()
  2. 使用Reflect.ownKeys()

RQ3:对象的中括号运算符和点运算符有什么区别?

中括号中可以用变量,但是点后面不能是一个变量。

const obj = {};

obj.name = '111';
const myName = 'name'
console.log(obj.myName); // undefined
console.log(obj[myName]);  // 111