定义⼀个json数组并赋值_JS的赋值与深浅拷贝实例
JS的赋值与深浅拷贝实例
赋值
基本类型: 传值,在栈内存中的数据发⽣数据变化的时候,系统会⾃动为新的变量分配⼀个新的之值在栈内存中,两个变量相互独⽴,互不影响的
引⽤类型: 传址,只改变指针的指向,指向同⼀个对象,两个变量相互⼲扰
//基本数据类型赋值
el的用法var a = 10;
var b = a;
a++ ;
console.log(a); // 11
abaconsole.log(b); // 10
//引⽤数据类型赋值
let a = { name: '11' }
let b = a
b.name = '22'
console.log(a.name) // 22
console.log(b.name) // 22
浅拷贝
对于基本类型,浅拷贝是对值的复制,拷贝前后对象的基本数据类型互不影响
对于引⽤类型来说,浅拷贝是对对象地址的复制, 也就是拷贝的结果是两个对象指向同⼀个地址,所以如果其中⼀个对象改变了这个地址,就会影响到另⼀个对象
注意:浅拷贝只复制⼀层对象的属性
实现浅拷贝⽅法
⽅法⼀:Object.assign
*语法:Object.assign(target, ...sources) *
ES6中拷贝对象的⽅法,接受的第⼀个参数target是拷贝后的对象,剩下的参数是要拷贝的对象sources(可以是多个)
例1:
let target = {};
let source = {a:'11',b:{name:'duoduo'}};迪士尼动画片灰姑娘
Object.assign(target ,source);
console.log(target); // { a: '11', b: { name: 'duoduo' } }
例2:
let target = {};
let source = {a:'11',b:{name:'duoduo'}};
Object.assign(target ,source);
source.a = '22';
source.b.name = 'nana'
console.log(source); // { a: '22', b: { name: 'nana' } }
console.log(target); // { a: '11', b: { name: 'nana' } }
Object.assign注意事项
1. 只拷贝源对象的⾃⾝属性(不拷贝继承属性)
2. 它不会拷贝对象不可枚举的属性
3. undefined和null⽆法转成对象,它们不能作为Object.assign参数,但是可以作为源对象
4. 属性名为Symbol 值的属性,可以被Object.assign拷贝。
⽅法⼆:Array.prototype.slice
实现原数组的浅拷贝
var a = [ 1, 3, 5, { x: 1 } ];
var b = Array.prototype.slice.call(a);
b[0] = 2;
console.log(a); // [ 1, 3, 5, { x: 1 } ];
console.log(b); // [ 2, 3, 5, { x: 1 } ];
// 从输出结果可以看出,浅拷贝后,数组a[0]并不会随着b[0]改变⽽改变
// 说明a和b在栈内存中引⽤地址并不相同。
var a = [ 1, 3, 5, { x: 1 } ];
var b = Array.prototype.slice.call(a);
b[3].x = 2;
成本会计
console.log(a); // [ 1, 3, 5, { x: 2 } ];
console.log(b); // [ 1, 3, 5, { x: 2 } ];
// 从输出结果可以看出,浅拷贝后,数组中对象的属性会根据修改⽽改变
// 说明浅拷贝的时候拷贝的已存在对象的对象的属性引⽤。
⽅法三:at
let array = [{a: 1}, {b: 2}];
let array1 = [{c: 3},{d: 4}];
let at(array1);
array1[0].c=123;
console.log(array2);// [ { a: 1 }, { b: 2 }, { c: 123 }, { d: 4 } ]
console.log(array1);// [ { c: 123 }, { d: 4 } ]
⽅法四:...扩展运算符
语法:var cloneObj = { ...obj };
var a = [ 1, 3, 5, { x: 1 } ];
var b = {...a};
b[0] = 2;
console.log(a); // [ 1, 3, 5, { x: 1 } ];
console.log(b); // [ 2, 3, 5, { x: 1 } ];
// 从输出结果可以看出,浅拷贝后,数组a[0]并不会随着b[0]改变⽽改变
// 说明a和b在栈内存中引⽤地址并不相同。
var a = [ 1, 3, 5, { x: 1 } ];
var b = {...a};
b[3].x = 2;
console.log(a); // [ 1, 3, 5, { x: 2 } ];
console.log(b); // [ 1, 3, 5, { x: 2 } ];
// 从输出结果可以看出,浅拷贝后,数组中对象的属性会根据修改⽽改变
// 说明浅拷贝的时候拷贝的已存在对象的对象的属性引⽤。
其他⽅法:
//浅拷贝实现
var obj = { a:1, arr: [2,3] };
var shallowObj = shallowCopy(obj);
function shallowCopy(src) {
var dst = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
dst[prop] = src[prop];
}
}
return dst;
}
完美的英文单词shallowObj.arr[1] = 5;
obj.arr[1] // = 5
深拷贝
深拷贝开辟⼀个新的栈,两个对象对应两个不同的地址,修改⼀个对象的属性,不会改变另⼀个对象的属性
注意:深拷贝对对象中的⼦对象进⾏递归拷贝,拷贝前后两个对象互不影响
实现⽅法:
⽅法⼀:JSON.par(JSON.stringify())
JSON.stringify()是前端开发过程中⽐较常⽤的深拷贝⽅式。
原理是把⼀个对象序列化成为⼀个JSON字符串,将对象的内容转换成字符串的形式再保存在磁盘上,再⽤JSON.par()反序列化将JSON字符串变成⼀个新的对象
let arr = [1, 2, {name: ' duoduo'}];
express yourlflet newarr = JSON.par(JSON.stringify(arr));
newarr[2].name = 'nana';
console.log(newarr); // [ 1, 2, { urname: 'nana' } ]
console.log(arr); // [ 1, 2, { urname: 'duoduo' } ]
JSON.stringify()实现深拷贝注意点
1. 拷贝的对象的值中如果有函数,undefined,symbol则经过JSON.stringify()序列化后的JSON字符串中这个键值对会消失
2. ⽆法拷贝不可枚举的属性,⽆法拷贝对象的原型链
3. 拷贝Date引⽤类型会变成字符串
4. 拷贝RegExp引⽤类型会变成空对象
5. 对象中含有NaN、Infinity和-Infinity,则序列化的结果会变成null
6. ⽆法拷贝对象的循环应⽤(即obj[key] = obj)
gsm modem
⽅法⼆:jquery 的 $.extend
英语一和英语二的区别var $ = require('jquery');
白色的英文var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = $.extend(true, {}, obj1);
赋值、深拷贝、浅拷贝
浅拷贝和**深拷贝区别
浅拷贝只复制⼀层对象的属性,⽽深拷贝则递归复制了所有层级
dtd