美文网首页
前端基础进阶(二): 深浅拷贝

前端基础进阶(二): 深浅拷贝

作者: 娜妹子辣辣妹子娜 | 来源:发表于2020-01-15 16:24 被阅读0次

深拷贝与浅拷贝

基本类型的拷贝

先来看一段非常经典的代码

var a = 1;
var b = a;
a = 200;
console.log(a);      //200
console.log(b);      //1

我们应该知道基本类型“按值传递”,引用类型“按引用传递”,数值作为基本类型是保存在栈内存中,可以直接拿来用的,赋值是什么那么之后就一直是什么,不会受到传递元素的改变带来的影响,所以这里就不难理解上面的代码得到的值的原因了。

引用类型的拷贝

简单说,引用类型是生成一个指针保存的堆内存中,当给引用类型赋值时,我们写的内容是在栈内存中,也就是说我们拿到的其实是一个指针(不会直接拿到栈内存中的内容)。这个指针是指向栈内存中这个引用类型的代码。

浅拷贝针对对象中的基本类型的值生效,但是对引用类型中还有引用类型的情况就会失效。
所谓的深浅拷贝是相对与typeof === 'object' 而言的,数组是用堆对应保存的。
浅拷贝:拷贝了对象的存放地址,只是指向相同而已 (只解决了第一层,对象中还有对象就不适用了)
深拷贝:完全复制了一个独立的个体

  • 浅拷贝方法:(直接 =,Object.assign...大部分都是浅拷贝)

=

 let arr1 = [1,3,5];
 let arr2 = arr1;
 arr1[0] = 10;
 console.log(arr2) // [10,3,5]
var obj1 = {
       name: '张三'
}

var obj2 = obj1;
obj2.name = '李四';

console.log(obj1.name); // '李四'

Object.assign

var obj1 = {
       name: '张三'
}

var obj2 = Object.assign({}, obj1);
obj2.name = '李四';
console.log(obj1.name);  // '张三'

至此,浅拷贝成功,但存在兼容性问题,比如低端的安卓机等,这个需要注意。但细心的朋友肯定会再做一个测试,如下:

var obj1 = {
       name: '张三',
       friends: {
          name: '刘备',
          age: 33
      }
}

var obj2 = Object.assign({}, obj1);
obj2.name = '李四';
obj2.friends.name = '关羽';
console.log(obj1.name);  // '张三'
console.log(obj1.friends.name);  // '关羽'

是的,到这一步,我们失败了,对象中嵌套对象时,Object.assign()只能拷贝一层,那如何解决呢?其实就要用到深拷贝的方法了:

var obj1 = {
       name: '张三',
       friends: {
          name: '刘备',
          age: 33
      }
}

var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.name = '李四';
obj2.friends.name = '关羽';
console.log(obj1.name);  // '张三'
console.log(obj1.friends.name);  // '刘备'
  • 深拷贝方法:
    Json.parse(Json.stringify())
var obj1 = {
       name: '张三',
       friends: {
          name: '刘备',
          age: 33
      }
}

var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.name = '李四';
obj2.friends.name = '关羽';
console.log(obj1.name);  // '张三'
console.log(obj1.friends.name);  // '刘备'

$.extend
...运算符

 let arr = [1,3,5];
 let arr1 = [...arr];

返回新数组方法 slice() 、 contat()、 map()

  let arr1 = [2,5,7];
  let arr2 = arr1.slice(0);
  let arr3 = arr1.contat();
  let arr4 = arr1.map(x => x);
  arr2[0] = 4;
 arr1[0] = 99;
console.log(arr1,arr2) // [99,5,7]  [4,5,7] 

for-in连原型链也一并复制的方法

 let arr = [1,3,5];
 let arr2 = [] ;
 for(var key in arr) {
  arr2[key] = arr[key]
}

封装方法

   /**
     * 判断对象类型
     * @param {Object} object
     * @return {String} object type
     */
    getType(object) {
        var toString = Object.prototype.toString;
        var map = {
            '[object Boolean]': 'boolean',
            '[object Number]': 'number',
            '[object String]': 'string',
            '[object Function]': 'function',
            '[object Array]': 'array',
            '[object Date]': 'date',
            '[object RegExp]': 'regExp',
            '[object Undefined]': 'undefined',
            '[object Null]': 'null',
            '[object Object]': 'object'
        };
        if (object instanceof Element) {
            return 'element';
        }
        return map[toString.call(object)];
    },
       /**
     * 对象的深度拷贝
     * @param data 需要拷贝的元数据
     * @return {any} 返回拷贝后的新数据
     */
    deepClone(data) {
        const type = this.getType(data);
        let obj;

        if (type === 'array') {
            obj = [];
        } else if (type === 'object') {
            obj = {};
        } else {
            //不再具有下一层次
            return data;
        }
        if (type === 'array') {
            for (let i = 0, len = data.length; i < len; i++) {
                obj.push(this.deepClone(data[i]));
            }
        } else if (type === 'object') {
            for (let key in data) {
                obj[key] = this.deepClone(data[key]);
            }
        }

        const constructor = data.constructor;
        if (constructor) {
            return Object.assign(new constructor(), obj);
        }
        return obj;
    },

相关文章

  • 前端基础进阶(二): 深浅拷贝

    深拷贝与浅拷贝 基本类型的拷贝 先来看一段非常经典的代码 我们应该知道基本类型“按值传递”,引用类型“按引用传递”...

  • 前端基础进阶系列

    前端基础进阶(一):内存空间详细图解前端基础进阶(二):执行上下文详细图解前端基础进阶(三):变量对象详解前端基础...

  • JS文集的目录

    js基础心法 深浅拷贝(递归)深浅拷贝(首层浅拷贝) js 数据处理 数组对象查找的常见操作数组对象去重的常见操作...

  • 学习图谱

    前端整体 基础学习路线 进阶学习路线 整体学习路线 「前端进阶」2018/2019 史上最全的前端学习路线 How...

  • Java 最近遇到的面试题

    JAVA 基础 java 对象拷贝深浅拷贝 对象何时进入老年代 Minor GC 和 Full GC 有什么不同 ...

  • 2018-08-29

    深浅拷贝 1.根据拷贝内容的不同,分为深浅拷贝 深拷贝:内容...

  • 01前端基础---JS数据类型&深浅拷贝

    一、JS数据类型:基本数据类型:Number(数字)、String(字符串)、Boolean(布尔值)、Null、...

  • JS基础心法-深浅拷贝

    一、复制 浅拷贝 浅拷贝的意思就是只复制引用,而未复制真正的值。 上面的代码是最简单的利用 = 赋值操作符实现了一...

  • js的深浅拷贝

    js的深浅拷贝可以分为数组的深浅拷贝和对象的深浅拷贝 一、数组的深浅拷贝如果只是简单的将数组中的元素付给另外一个数...

  • Python—浅拷贝与深拷贝

    浅拷贝 深拷贝 深浅拷贝的作用

网友评论

      本文标题:前端基础进阶(二): 深浅拷贝

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