JS实现深拷贝、instanceof、判断是否为数组

JS深拷贝

JS中拷贝对象可以按照拷贝的程度可以分为浅拷贝和深拷贝,有些时候我们需要拷贝之后的对象和拷贝之前的对象解耦,即脱离联系,也就是改变其中一者,另一者不会变化,典型的场景有:状态的回溯。如果我们对状态对象使用浅拷贝,则无法对状态进行回溯,但如果使用深拷贝,则可以很容易的对状态进行回溯和跟踪。实现深拷贝,主要由以下两种方式:(值得一提的是,JS原生数组中的 concat、slice 方法还有 Object.assign 方法都是一层拷贝,即浅拷贝)

  1. JSON (缺点:无法拷贝函数)
function copy(o) {
    return JSON.parse(JSON.stringify(o))
}
  1. 递归实现
var deepCopy = function(obj) {
    if (typeof obj !== 'object') return obj
    var newObj = (Object.prototype.toString.call(obj) === '[object Array]') ? [] : {}
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = (typeof obj[key] !== 'object') ? obj[key]: deepCopy(obj[key])
        }
    }
    return newObj
}

instanceof

instanceof 是用来判断对象是是某类的实例,或者是否是某类的子类的实例,它的实现原理可以是下面这样,L 表示实例,R 表示某类。

function instanceOf(L, R) {
    R = R.prototype
    L = L.__proto__
    while (true){
        if (L === null)
            return false
        if (R === L) 
            return true
        L = L.__proto__
    }
}

判断是否为数组

JS中数组也属于对象,所以无法通过 typeof 直接判断,这个时候就得采用其他方式,主要有一下几种方式:

  1. 使用 instanceof
var arr = []
console.log(arr instanceof Array)
  1. 使用 constructor
var arr = []
console.log(arr.constructor === Array)
  1. 判断对象是否有 push 等数组的一些方法
var arr = []
console.log(!!arr.push && !!arr.concat)
  1. 使用对象的 toString
var arr = []
console.log(Object.prototype.toString.call(arr) === '[object Array]')
  1. 使用 ES5 中的 Array.isArray 方法
var arr = []
console.log(Array.isArray(arr))

方法 1-3 有兼容性问题,方法 5 可能不兼容老款浏览器,所以最好使用方法 4

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 0. 写在前面 当你开始工作时,你不是在给你自己写代码,而是为后来人写代码。 —— Nichloas C. Zak...
    康斌阅读 5,372评论 1 42
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,148评论 1 32
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,664评论 8 265
  • 一晃便是冬天,那年那月,那时间,都是一去不复返,而我们却是曾今,擦肩而过,留下了印痕,偶然回想,似是存在。 ...
    铭悦阅读 522评论 0 2
  • 坐上这个出租车,内心突然涌现出一些落寞!不知自己在奔向什么!还有,今天为什么会有这么多的累!
    花样儿阅读 172评论 0 0