JS经常使用的深、浅拷贝

在JS中,数据类型分为基本数据类型和引用数据类型两种。对于基本数据类型来讲,它的值直接存储在栈内存中,而对于引用类型来讲,它在栈内存中只是存储了一个指向对内存的引用,而真正的数据存储在堆内存中。javascript

object、array 这两个就是引用类型,当我门直接去拷贝的话(copyObj = obj), 拷贝的是指obj的引用,当你修改copyObj时候,obj也会同时改变;数组也同样道理。vue

深拷贝

所谓的深拷贝,要实现的效果是无论对象或数组里面嵌套了多少层引用类型,都能拷贝出来,而非只拷贝它的引用java

要实现深拷贝的方法经常使用有一下方法:数组

一、JSON.parse、JSON.stringify

let obj2 = JSON.parse(JSON.stringify(obj1))
复制代码

缺点:undefined、function、symbol 会在转换过程当中被忽略函数

二、递归深拷贝

// 不支持循环引用
function deepCopy (src) {
    if (!src || typeof src !== 'object') return src // 判断是否为array || object
    let temp = Array.isArray(src) ? [] : {}
    for (let key in src) {
        if (src.hasOwnProperty(key)) { // 过滤继承来的属性
            if (src[key] && typeof src[key] === 'object') { // 若属性也是引用类型
                temp[key] = deepCopy(src[key]) // 递归克隆
            } else {
                temp[key] = src[key] // 非引用类型就直接拷贝
            }
        }
    }
    return temp
}

let obj2 = deepCopy(obj1)
复制代码

浅拷贝

那么浅拷贝,简单引用类型直接赋值post

或者引用类型的首层进行了深拷贝,可是属性中还有引用类型,只是拷贝它的引用,这样的状况下,也为浅拷贝ui

如下浅拷贝方法,都只是实现了首层的深拷贝,当嵌套引用类型就要只会拷贝它的引用spa

一、ES6扩展运算符

let obj2 = {...obj1} // 对象浅拷贝
let arr2 = [...arr1] // 数组浅拷贝
复制代码

二、Object.assign()

let obj2 = Object.assign({}, obj1)
复制代码

三、遍历

let shallowCopy = obj => {
  let temp = {}
  // 遍历对象
  for (let key in obj) {
    // 只复制自己拥有的属性(非继承过来的属性)枚举属性
    if (obj.hasOwnProperty(key)) {
      temp[key] = obj[key]
    }
  }
  return temp
}
let obj2 = shallowCopy(obj1)
复制代码

三、concat()

let arr2 = [].concat(arr1)
复制代码

相关连接:code

JS的防抖、节流函数对象

八步开发一个vue的组件库

VUE的实现原理(数据劫持、观察者模式)

Javascript实现简单的冒泡排序、插入排序

一个很是简单的-发布订阅模式

相关文章
相关标签/搜索