js数据类型赋值,浅拷贝,深拷贝

直接上代码是我的风格

一,赋值

  1. 基本数据类型的赋值
    var a = 10;
    var b = a;
    b = 24;
    console.log(a); // 10  a不受b的影响。
    console.log(b) // 24
    // 基本数据类型赋值时。。是copy一份10的值。
    // 当b=24时。a不受b的影响。
复制代码
  1. 复杂数据类型的赋值
    var obj = {
        age: 12
    }
    var obj1 = obj;
    obj1.age = 18;
    console.log(obj); // {age: 18}
    console.log(obj1); // {age: 18}
    // 复杂数据类型赋值时。。是copy一份引用地址如0x1111。
    // 当obj1 = obj;时。obj和obj1引用一样。指向同一片堆内存空间。
    // 所以当obj1.age = 18时。同样也会更改obj2。
复制代码

二,浅拷贝与深拷贝

注意: 浅拷贝和深拷贝都主要针对复杂数据类型
  1. 浅拷贝:浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。
  2. 深拷贝:但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

二,浅拷贝与赋值

  1. 浅拷贝
    // 直接上代码吧
    function shallowCopy(oldObj) {
        var newObj = {};
        for(var prop in oldObj) {
            // 所有继承了 Object 的对象都会继承到 hasOwnProperty 方法。
            // 这个方法可以用来检测一个对象是否含有特定的自身属性;如果有返回true。否则返回false
            // 和 in 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。
            if(oldObj.hasOwnProperty(prop)){
                newObj[prop] = oldObj[prop]
            }
        }
        return newObj;
    }
    // 浅拷贝
    var obj1 = {
        a: 1, 
        b: [2,3,4], 
        c: [[5,6]] // 注意:这里多一层引用数据类型
    }
    var obj2 = shallowCopy(obj1); 
    
    obj2.a = 18;
    obj2.b = ['二', '三', '四'];
    obj2.c[0] = ['五', '六'];
    
    console.log('obj1===',obj1) 
    console.log('obj2===',obj2) 
    
    // 如果对象只有一层。。深拷贝 和 浅拷贝一样。
    
    
复制代码

  1. 赋值
     // 赋值
    var obj1 = {
        a: 1, 
        b: [2,3,4], 
        c: [[5,6]] // 注意:这里多一层引用数据类型
    }
    var obj3 = obj1;
    
    obj3.a = 18;
    obj3.b = ['二', '三', '四'];
    obj3.c[0] = ['五', '六'];
    
    console.log('obj1===',obj1) 
    console.log('obj3===',obj3) 
    
    // 共享一片内存。所有值都会改变。
    
复制代码

三,浅拷贝实现方式

  1. 自己封装
     function shallowCopy(oldObj) {
        var newObj = {};
        for(var prop in oldObj) {
            // 所有继承了 Object 的对象都会继承到 hasOwnProperty 方法。
            // 这个方法可以用来检测一个对象是否含有特定的自身属性;如果有返回true。否则返回false
            // 和 in 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。
            if(oldObj.hasOwnProperty(prop)){
                newObj[prop] = oldObj[prop]
            }
        }
        return newObj;
    }
复制代码
  1. 使用Object.assign()
    var pj = { a: {a: "彭彭", b: 39} };
    var pj1 = Object.assign({}, obj);
    pj1.a.a = "wade";
    console.log(pj.a.a); //wade
    
复制代码

注意:当object只有一层的时候,是深拷贝

    var pj = { a: {a: "彭彭", b: 39} };
    var pj1 = Object.assign({}, obj);
    pj1.a.a = "wade";
    console.log(pj.a.a); //wade
    
复制代码
  1. 数组的浅拷贝
    // 第一种
    let arr = [1, 3, {
        username: '彭彭'
    }];
    let arr2=arr.concat();    
    arr2[2].username = '君';
    
    console.log(arr[2].username); // 君
    
    // 第二种
    let arr = [1, 3, {
        username: ' 彭彭'
    }];
    let arr3 = arr.slice();
    arr3[2].username = '君';
    console.log(arr[2].username); // 君
    
    // 一般很少用到数组的拷贝。
    // 数组浅拷贝和对象是一样的
复制代码

原数组的元素会按照下述规则拷贝:

  • 如果该元素是个对象引用(不是实际的对象),slice 会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。
  • 对于字符串、数字及布尔值来说(不是 String、Number 或者 Boolean 对象),slice 会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。

四,深拷贝

  1. JSON.parse(JSON.stringify())
    var pj = {
        name: '彭彭',
        handle: function(){} 
    };
    
    var deepPj = JSON.parse(JSON.stringify(pj)); // {name: "彭彭"}。。这种方式弊端在于无法拷贝方法。
复制代码
  1. 自觉手动封装了
    function deepCopy(oldObj) {
        var newObj;
        var oldObjType = Object.prototype.toString.call(oldObj).slice(8, -1);
        if(oldObjType === 'Object'){
            newObj = {};
        }else if(oldObjType === 'array'){
            newObj = [];
        }else{
            return oldObj;
        }
        
        for(let prop in oldObj){
            let value = oldObj[prop];
            let valueType = Object.prototype.toString.call(value).slice(8, -1);
            if (valueType === 'Object' || valueType = 'Array') {
                deepCopy(value);
            } else {
                newObj[prop] = value;
            }
        }
        
        return newObj;
    }
复制代码
  1. 借用第三方库 函数库lodash
  • 该函数库也有提供_.cloneDeep用来做 Deep Copy
var _ = require('lodash');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f); // false
复制代码

参考文章:juejin.im/post/5b5dcf…

转载于:https://juejin.im/post/5cc6fcc56fb9a0323968962a

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值