ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

清晰易懂!讲解JS赋值、浅拷贝和深拷贝

2021-05-08 22:03:43  阅读:249  来源: 互联网

标签:obj1 obj2 console log JS let 易懂 拷贝


一些问题

// 赋值1
let obj1 = {
    a: 1,
    b: 2
}

let obj2 = obj1
obj2.a = 3

console.log(obj1) // ?
console.log(obj2) // ?
// 赋值2
let obj1 = {
    a: 1,
    b: 2,
    c: {
    	q: 6
    }
}

let obj2 = obj1
obj2.a = 3
obj2.c.q = 7

console.log(obj1) // ?
console.log(obj2) // ?
// 浅拷贝1
let obj1 = {
    a: 1,
    b: 2
}
let obj2 = Object.assign({}, obj1)
obj2.a = 3

console.log(obj1) // ?
console.log(obj2) // ?
// 浅拷贝2
let obj1 = {
    a: 1,
    b: 2,
    c: {
    	q: 6
    }
}

let obj2 = Object.assign({}, obj1)
obj2.a = 3
obj2.c.q = 7

console.log(obj1) // ?
console.log(obj2) // ?
// 深拷贝
let _ = require('lodash');
let obj1 = {
    a: 1,
    b: 2,
    c: {
    	q: 6
    }
};
let obj2 = _.cloneDeep(obj1);
obj2.a = 3
obj2.c.q = 7

console.log(obj1) // ?
console.log(obj2) // ?

JS数据类型及相关概念

数据类型

JS有两种数据类型:基本类型、引用类型。 基本类型:String Number Boolean undefined null symbol 引用类型:Object Array Function Date

数据在内存中的存储

JS定义变量的时候,变量会被存入内存栈中,但基本类型和引用类型的存储有区别: 基本类型存储在栈内存中; 引用类型存储在堆内存中,栈中存储了指向数据的指针(内存地址)。 即:定义一个新变量拷贝数据时,基本类型是拷贝原始数据,引用类型则不是。

正是因为这个问题,新手容易遇到一个问题:拷贝一个对象(引用类型)后,对新对象进行修改,再使用原对象后会发现原对象也变了。 解决这个问题的办法是学习赋值、浅拷贝和深拷贝的使用场景,不同场景灵活处理引用类型。

对象的赋值、浅拷贝、深拷贝

赋值没有创建新对象,仅仅是拷贝了原对象的指针。 浅拷贝是创建一个新对象,这个对象仅对原对象的属性进行拷贝,属性值是基本类型时,拷贝的是原数据,属性值是引用类型时,拷贝的是指针。因此,如果原对象的属性有引用类型数据,无论修改新对象还是原对象的引用类型数据,另一个都会随之改变。 深拷贝也是创建一个新对象,但不仅对原对象的属性进行拷贝,还在堆内存中开辟一个新的地址用来存储新对象,所以新对象和原对象没有关联,修改其中一个另一个不会变化

问题解答

// 赋值1
let obj1 = {
    a: 1,
    b: 2
}

let obj2 = obj1
obj2.a = 3

console.log(obj1) // {a: 3, b: 2}
console.log(obj2) // {a: 3, b: 2}
// 赋值2
let obj1 = {
    a: 1,
    b: 2,
    c: {
    	q: 6
    }
}

let obj2 = obj1
obj2.a = 3
obj2.c.q = 7

console.log(obj1) // {a: 3, b: 2, c: {q: 7}}
console.log(obj2) // {a: 3, b: 2, c: {q: 7}}
// 浅拷贝1
let obj1 = {
    a: 1,
    b: 2
}
let obj2 = Object.assign({}, obj1)
obj2.a = 3

console.log(obj1) // {a: 1, b: 2}
console.log(obj2) // {a: 3, b: 2}
// 浅拷贝2
let obj1 = {
    a: 1,
    b: 2,
    c: {
    	q: 6
    }
}

let obj2 = Object.assign({}, obj1)
obj2.a = 3
obj2.c.q = 7

console.log(obj1) // {a: 1, b: 2, c: {q: 7}}
console.log(obj2) // {a: 3, b: 2, c: {q: 7}}
// 深拷贝
let _ = require('lodash');
let obj1 = {
    a: 1,
    b: 2,
    c: {
    	q: 6
    }
};
let obj2 = _.cloneDeep(obj1);
obj2.a = 3
obj2.c.q = 7

console.log(obj1) // {a: 1, b: 2, c: {q: 6}}
console.log(obj2) // {a: 3, b: 2, c: {q: 7}}

使用场景

原对象仅使用一次(被修改也不产生副作用),用赋值。

原对象需多次使用(被修改会导致后续使用数据不准确),且属性只有基本类型,无引用类型,用浅拷贝。

原数据需多次使用(被修改会导致后续使用数据不准确),且属性含有引用类型,用深拷贝。

浅拷贝的实现

Object.assign()

如上面的例子,Object.assign()是浅拷贝

concat

es5的浅拷贝方法

扩展运算符

es6的浅拷贝方法

slice

JS数组的方法

let arr1 = [1, 2, { username: 'Kobe' }];
let arr2 = arr.slice();
arr2[2].username = 'Wade'

console.log(arr1[2]); // { username: 'Kobe' }
console.log(arr2[2]); // { username: 'Wade' }

lodash的clone()

let _ = require('lodash');
let obj1 = {
    a: 1,
    b: 2,
};

var obj2 = _.clone(obj1);

手写实现

function shallowClone(source) {
    var target = {};
    for(var i in source) {
        if (source.hasOwnProperty(i)) {
            target[i] = source[i];
        }
    }
    return target;
}

let obj1 = {...}
let obj2 = shallowClone(obj1)

深拷贝的实现

JSON.parse(JSON.stringfy())

let obj1 = {a: 1, b: 2}
let obj2 = JSON.parse(JSON.stringify(obj1))

注意:慎用,因为如果对象中有方法,这样深拷贝会丢失方法。如:

let obj1 = {a: 1, b: 2, c: function() {return '看方法在不在'}}
let obj2 = JSON.parse(JSON.stringify(obj1))

console.log(obj1); // {a: 1, b: 2, c: ƒ}
console.log(obj2); // {a: 1, b: 2}

lodash的deepClone()

let _ = require('lodash');
let obj1 = {
    a: 1,
    b: 2,
    c: {
    	q: 6
    }
};
let obj2 = _.cloneDeep(obj1);

jquery.extend()

// 用法:$.extend(deepCopy, target, object1, [objectN]) // 第一个参数为true,就是深拷贝

let $ = require('jquery');
let obj1 = {
    a: 1,
    b: 2,
    c: {q: 6}
};
let obj2 = $.extend(true, {}, obj1);

总结

如果你已经下定决心要转行做编程行业,在最开始的时候就要对自己的学习有一个基本的规划,还要对这个行业的技术需求有一个基本的了解。有一个已就业为目的的学习目标,然后为之努力,坚持到底。如果你有幸看到这篇文章,希望对你有所帮助,祝你找到满意的工作。

不管你是零基础的萌新,还是想转行的小伙伴 ,只要你想了解前端,精通前端,都欢迎你们加入我们的前端自学团。

在这里,你可以找到志同道合的朋友,相互激励的学习伙伴,还能得到大神的经验分享,和加入项目实战的机会。 想加入自学团的小伙伴赶快行动起来吧 ~

想学习前端web和需要PDF文档的朋友都可以加入这边的企鹅裙,前面:938,,中间:051,,最后:673

裙里从学生到大佬都有,还有资源免费分享,不见不散哦!

标签:obj1,obj2,console,log,JS,let,易懂,拷贝
来源: https://www.cnblogs.com/qianduanpiaoge/p/14746575.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有