###1、检测对象类型最推荐的用法
Object.prototype.toString.call(obj) === “[object Object]”
//首先先测试一下
console.log(Object.prototype.toString.call("jerry"));//[object String]
console.log(Object.prototype.toString.call(12));//[object Number]
console.log(Object.prototype.toString.call(true));//[object Boolean]
console.log(Object.prototype.toString.call(undefined));//[object Undefined]
console.log(Object.prototype.toString.call(null));//[object Null]
console.log(Object.prototype.toString.call({name: "jerry"}));//[object Object]
console.log(Object.prototype.toString.call(function(){}));//[object Function]
console.log(Object.prototype.toString.call([]));//[object Array]
console.log(Object.prototype.toString.call(new Date));//[object Date]
console.log(Object.prototype.toString.call(/\d/));//[object RegExp]
function Person(){};
console.log(Object.prototype.toString.call(new Person));//[object Object]
那为什么不直接用obj.toString()呢?
console.log("jerry".toString());//jerry
console.log((1).toString());//1
console.log([1,2].toString());//1,2
console.log(new Date().toString());//Wed Dec 21 2016 20:35:48 GMT+0800 (中国标准时间)
console.log(function(){}.toString());//function (){}
console.log(null.toString());//error
console.log(undefined.toString());//error
原因:
这是因为toString为Object的原型方法,而Array ,function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串…),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object上原型toString方法。
###3、检测对象是否为数组
//第一种
Object.prototype.toString.call(myObj)
//第二种
Array.isArray(myObj)
//第三种(不推荐使用 在多个frame或多个window之间的交互 会出现失效问题 因此最安全的做法使用上两种)
myObj instanceof Array
###4、深度判等
//结构和数据完全相等,而不要求同一引用
export function deepEqual (o1, o2) {
if (typeof o1 !== 'object' || typeof o2 !== 'object') { return o1 === o2 }
// 完全遍历 o1,保证 o2 的数据结构可以覆盖 o1的,也就是说 o2的数据结构大于等于 o1的
for (var p in o1) {
if (!deepEqual(o1[p], o2[p])) { return false }
}
// 保证 o2中存在的数据结构在 o1中也存在,结合上一步,即可证明二者数据结构完全一致
for (var q in o2) {
if (!(q in o1)) { return false }
}
return true
}
###5、深度覆盖
将源对象的值覆盖目标对象,相同结构相同参数部分直接覆盖,其它部分保持不变,例如: 修改前:
target = {x: 1, y: {a: 1, b:1 }, z: 1};
source = {x: 2, y: {a: 2}};
修改后:
target = {x: 2, y: {a: 2, b:1 }, z: 1}
实现:
function deepAssign (target, ...sources) {
if (typeof target !== 'object') {
console.error('[deepAssign] bad parameters, target should be an object, parameters:', arguments)
return target
}
for (let source of sources) {
if (source != null && typeof source !== 'object') {
console.warn('[deepAssign] bad parameters, source should all be object, parameters:', arguments)
continue
}
for (var p in source) {
if (typeof target[p] === 'object' && typeof source[p] === 'object') { deepAssign(target[p], source[p]) }
else { target[p] = source[p] }
}
}
return target
}