美文网首页
浅拷贝和深拷贝

浅拷贝和深拷贝

作者: 双面小Q | 来源:发表于2018-08-20 23:33 被阅读0次

本文参考:


浅拷贝

最简单的浅拷贝就是赋值操作

var obj1 = ['lee', {age: 22}];
var obj2 = obj1;

obj2[0] = 'json';
console.log(obj1[0]); // json

obj2[1].age = 20;
console.log(obj1[1].age); // 20
  • 对于基本数据类型,两个变量不会相互影响
  • 对于引用数据类型,两个变量共用同一块堆内存,会相互影响
赋值内存分析

浅拷贝是只复制第一层得到的新实例

var obj1 = ['lee', {age: 22}];
var obj2 = obj1.slice();

obj2[0] = 'json';
console.log(obj1[0]); // lee

obj2[1].age = 20;
console.log(obj1[1].age); // 20
  • 对于基本数据类型,会在堆中重新开辟一块内存,修改后不会相互影响
  • 对于引用数据类型,因为只拷贝了一层,所以指针还是指向同一块堆内存,会相互影响
浅拷贝内存分析

深拷贝

深拷贝是递归复制了所有层级得到的新实例

var obj1 = ['lee', {age: 22}];
var obj2 = JSON.parse(JSON.stringify(obj1));

obj2[0] = 'json';
console.log(obj1[0]); // lee

obj2[1].age = 20;
console.log(obj1[1].age); // 22
  • 由于对整个对象及其子对象进行了递归复制,所以无论是基本数据类型还是引用数据类型,内存上都会重新创建,两个对象不会相互影响
深拷贝内存分析

实现方法

数组浅拷贝

  1. Array.prototype.slice()
var obj1 = ['lee', {age: 22}];
var obj2 = obj1.slice();
  1. Array.prototype.concat()
var obj1 = ['lee', {age: 22}];
var obj2 = obj1.concat();
  1. Array.from(obj)
var obj1 = ['lee', {age: 22}];
var obj2 = Array.from(obj1);
  1. Array.prototype.map(callback)
var obj1 = ['lee', {age: 22}];
var obj2 = obj1.map(item => item);

浅拷贝

  1. Object.assign([], obj)Object.assign({}, obj)
var obj1 = ['lee', {age: 22}];
var obj2 = Object.assign([], obj1);

var obj1 = { a: 0, b: { c: 0 } };
var obj2 = Object.assign({}, obj1);
  1. [...obj]{...obj}
var obj1 = ['lee', {age: 22}];
var obj2 = [...obj1];

var obj1 = { a: 0, b: { c: 0 } };
var obj2 = {...obj1}
  1. 自己动手实现
function shallowClone (obj) {
  if (!obj || typeof obj !== 'object') {
    throw new Error('arguments error');
  }
  var targetObj = Array.isArray(obj) ? [] : {};
  for (var key in obj) {
    if(obj.hasOwnProperty(key)) {
      targetObj[key] = obj[key];
    }
  }
  return targetObj;
}
  1. jQuery.extend([], obj)jQuery.extend({}, obj)
var obj1 = ['lee', {age: 22}];
var obj2 = $.extend([], obj1);

var obj1 = { a: 0, b: { c: 0 } };
var obj2 = $.extend({}, obj1);
  1. lodash.clone(obj)
var obj1 = ['lee', {age: 22}];
var obj2 = _.clone(obj1);

var obj1 = { a: 0, b: { c: 0 } };
var obj2 = _.clone(obj1);

深拷贝

  1. JSON.parse(JSON.stringify(obj))
var obj1 = ['lee', {age: 22}];
var obj2 = JSON.parse(JSON.stringify(obj1));

缺点:由于JSON.stringify()方法在序列化JS对象时,会忽略所有函数和原型成员,导致拷贝丢失。
这种实现方法能够处理JSON格式所能表示的所有数据类型,但是对RegexpFunction等类型无法进行深拷贝,同时也无法正确处理对象内部循环应用的问题。

  1. 自己动手实现
function deepClone(obj) {
  if (!obj || typeof obj !== 'object') {
    throw new Error('arguments error');
  }
  var targetObj = Array.isArray(obj) ? [] : {};
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      if (obj[key] && typeof obj[key] === 'object') {
        targetObj[key] = Array.isArray(obj[key]) ? [] : {};
        targetObj[key] = deepClone(obj[key]);
      } else {
        targetObj[key] = obj[key];
      }
    }
  }
  return targetObj;
}

缺点:与jQuery中的extend方法实现思路一样,不能处理对象内部循环引用的问题,对DateFunction类型的值没有实现真正的深拷贝,但这些类型的值重新定义时,一般都是直接覆盖,不会影响原对象,所以从一定程度上来讲也算是实现了深拷贝。

  1. jQuery.extend(true, [], obj)jQuery.extend(true, {}, obj)
var obj1 = ['lee', {age: 22}];
var obj2 = $.extend(true, [], obj1);

var obj1 = { a: 0, b: { c: 0 } };
var obj2 = $.extend(true, {}, obj1);

jQuery.extend 源码实现
缺点:无法处理对象内部循环引用的问题

  1. lodash.cloneDeep(obj)
var obj1 = { a: 0, b: { c: 0 } };
var obj2 = _.cloneDeep(obj1)

lodash.cloneDeep 源码实现

相关文章

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • iOS面试题-第二页

    11.深拷贝和浅拷贝的理解. 深拷贝;拷贝的内容. 浅拷贝:拷贝的指针. 深拷贝如: NSMutableDicti...

  • iOS - copy 与 mutableCopy

    一说到拷贝,就不得不提浅拷贝和深拷贝。 何谓浅拷贝?何谓深拷贝? 往简单的说: 浅拷贝:拷贝地址。 深拷贝:拷贝内...

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • iOS--拷贝相关题

    1、什么是深拷贝什么是浅拷贝?浅拷贝和深拷贝的区别 * 浅拷贝(shallow copy):指针拷贝,对于被拷贝对...

  • copy和mutableCopy的区别

    copy和mutableCopy的区别 深拷贝和浅拷贝的区别 在OC中对象的拷贝方式有两种:深拷贝和浅拷贝.浅拷贝...

  • 2018-10-10函数基础

    深拷贝和浅拷贝 深拷贝 copy.deepcopy(对象)浅拷贝 copy.copy(对象)深拷贝: 将对象对应的...

  • Objective-C中的浅拷贝和深拷贝

    Objective-C中的浅拷贝和深拷贝 Objective-C中的浅拷贝和深拷贝

  • JavaScript的深拷贝和浅拷贝

    原文 博客原文 大纲 前言1、对深拷贝和浅拷贝的初步认识2、深拷贝和浅拷贝的区别3、浅拷贝存在的缺陷4、深拷贝的实...

  • java中的深拷贝和浅拷贝

    简单记录一下java中的深拷贝和浅拷贝,深拷贝和浅拷贝只是针对对象而言的. 1 深拷贝代码 2 浅拷贝代码 3 测...

网友评论

      本文标题:浅拷贝和深拷贝

      本文链接:https://www.haomeiwen.com/subject/istriftx.html