学习记录

###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
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值