浅拷贝,就是基本类型进行传值操作,而引用类型则是传地址操作。基本类型进行浅拷贝之后互不影响,大路朝天,各走一边。引用类型进行浅拷贝之后则是牵一发而动全身,一改则全都改动
浅拷贝用的还算是比较多吧,所以整理一下浅拷贝的方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
/*
第一 =运算符 复制该对象的引用,而不是对于对象内部的复制(这个貌似不算是)
第二 利用for...in 遍历自身和继承的可枚举属性,除Symbol外===》特别注意会涉及到继承的属性
第三 利用for...of配合Object.entries 只复制可枚举的,不包含symbol和不可枚举以及继承的属性
第四 利用for...of配合Object.keys 只复制可枚举的,不包含symbol和不可枚举以及继承的属性
第五 利用for...of配合Object.getOwnPropertyNames 复制可枚举和不可枚举属性,但不包含symbol和继承的属性
第六 利用for...of配合Reflect.ownKeys 复制全部属性,包含不可枚举和symbol,但不包含继承的属性
第七 Object.assign() 复制可枚举属性和symbol,不包含继承的属性和不可枚举的属性
第八 解构赋值(...运算符) 复制可枚举属性和symbol,不包含继承的属性和不可枚举的属性
第九 Object.getOwnPropertyDescriptors方法配合Object.defineProperties
复制可枚举和不可枚举属性以及symbol,但不包含继承的属性
第十 Object.create方法配合Object.getOwnPropertyDescriptors
复制可枚举和不可枚举属性以及symbol,但不包含继承的属性
*/
//下面是测试
// //第一种 =运算符
// let peo={
// qwer:"cc"
// }
// let obj={
// __proto__:peo,
// a:1,
// stu:{
// b:1
// }
// }
// Object.defineProperty(obj,"three",{
// enumerable:false,
// value:"3",
// writable:true,
// configurable:true
// })
// //浅拷贝
// let no2=obj;
// console.log(no2);
// /*
// {a: 1, stu: {…}, three: "3"}
// a: 2
// stu: {b: 2}
// three: "3"
// __proto__: Object
// */
// //改动
// obj.a=2;
// obj.stu.b=2;
// //测试
// console.log(no2.a+"==="+obj.a);//2===2
// console.log(no2.stu.b+"==="+obj.stu.b);//2===2
//================================================================
//第二种 遍历方式
// let peo={
// qwer:"cc"
// }
// let obj={
// __proto__:peo,
// first:"1",
// stu:{
// two:"2"
// }
// }
// Object.defineProperty(obj,"three",{
// enumerable:false,
// value:"3",
// writable:true,
// configurable:true
// })
// let new_obj={};
//利用for...in
//(遍历自身和继承的可枚举属性,除Symbol外)===》特别注意会涉及到继承的属性
// for(let key in obj){
// new_obj[key]=obj[key];
// }
// console.log(new_obj);
// /*
// {first: "1", stu: {…}, qwer: "cc"}
// first: "1"
// qwer: "cc"
// stu: {two: "2"}
// __proto__: Object
// */
// //改动
// obj.first="a";
// obj.stu.two="b";
// obj.qwer="c";
// new_obj.qwer="d";
// //测试
// console.log(new_obj.first+"==="+obj.first);//1===a
// console.log(new_obj.stu.two+"==="+obj.stu.two);//b===b
// console.log(new_obj.qwer+"==="+peo.qwer+"==="+obj.qwer);//d===cc===c
//============================================================================
//利用for...of配合Object.entries
//Object.entries() 方法会返回由自身可枚举属性(不包含继承的)的键值对数组
// for (let [key,value] of Object.entries(obj)) {
// new_obj[key]=value;
// }
// console.log(new_obj);
/*
{first: "1", stu: {…}}
first: "1"
stu: {two: "2"}
__proto__: Object
*/
// //改动
// obj.first="a";
// obj.stu.two="b";
// //测试
// console.log(new_obj.first+"==="+obj.first);//1===a
// console.log(new_obj.stu.two+"==="+obj.stu.two);//b===b
//================================================================
//利用for...of配合Object.keys
//Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组
// for (let key of Object.keys(obj)) {
// new_obj[key]=obj[key];
// }
// console.log(new_obj);
// /*
// {first: "1", stu: {…}}
// first: "1"
// stu: {two: "b"}
// __proto__: Object
// */
// //改动
// obj.first="a";
// obj.stu.two="b";
// //测试
// console.log(new_obj.first+"==="+obj.first);//1===a
// console.log(new_obj.stu.two+"==="+obj.stu.two);//b===b
//================================================================
//利用for...of配合Object.getOwnPropertyNames
//Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名
//(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组
// for (let key of Object.getOwnPropertyNames(obj)) {
// new_obj[key]=obj[key];
// }
// console.log(new_obj);
// /*
// {first: "1", stu: {…}, three: "3"}
// first: "1"
// stu: {two: "2"}
// three: "3"
// __proto__: Object
// */
// //改动
// obj.first="a";
// obj.stu.two="b";
// obj.three="c";
// //测试
// console.log(new_obj.three+"==="+obj.three);//3===c
// console.log(new_obj.first+"==="+obj.first);//1===a
// console.log(new_obj.stu.two+"==="+obj.stu.two);//b===b
//================================================================
//利用for...of配合Reflect.ownKeys
//静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组
//包含可枚举和不可枚举的属性,甚至包含Symbol属性,但是不包含继承的属性
// for (let key of Reflect.ownKeys(obj)) {
// new_obj[key]=obj[key]
// }
// console.log(new_obj);
// /*
// {first: "1", stu: {…}, three: "3"}
// first: "1"
// stu: {two: "2"}
// three: "3"
// __proto__: Object
// */
// //改动
// obj.first="a";
// obj.stu.two="b";
// obj.three="c";
// //测试
// console.log(new_obj.three+"==="+obj.three);//3===c
// console.log(new_obj.first+"==="+obj.first);//1===a
// console.log(new_obj.stu.two+"==="+obj.stu.two);//b===b
//================================================================
//第三种 Object.assign()
//Object.assign(target, ...sources)
//用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象
//如果目标源与源对象有同名属性,或多个源对象有同名属性,则后面的会覆盖前面的
//只复制源对象自身的可枚举属性和symbol,不包含继承的属性和不可枚举的属性
// let peo={
// qwer:"cc"
// }
// let sym=Symbol("sym");
// let obj={
// __proto__:peo,
// first:1,
// stu:{
// two:2
// }
// }
// obj[sym]="sym";
// Object.defineProperty(obj,"three",{
// enumerable:false,
// value:"3",
// writable:true,
// configurable:true
// })
// // 浅拷贝
// let new_obj=Object.assign({},obj);
// console.log(new_obj);
// /*
// {first: 1, stu: {…}, Symbol(sym): "sym"}
// first: 1
// stu: {two: "b"}
// Symbol(sym): "sym"
// __proto__: Object
// */
// //改动
// obj.first="a";
// obj.stu.two="b";
// //测试
// console.log(new_obj.first+"==="+obj.first);//1 === a
// console.log(new_obj.stu.two+"==="+obj.stu.two);//b === b
//《ES标准入门》中说这个assin有一个小缺陷==》无法复制属性的赋值方法和取值方法(setter和getter方法)
//但是,我试了下,可以复制
// let obj={
// get first(){
// return this._first_;
// },
// set first(value){
// this._first_=value;
// }
// }
// obj.first="1";
// let new_obj=Object.assign({},obj);
// console.log(new_obj);//{first: "1", _first_: "1"}
// console.log(Object.getOwnPropertyDescriptor(new_obj,"first"));
// //{value: "1", writable: true, enumerable: true, configurable: true}
//=======================================================================
// //第四种 解构赋值(...运算符)
// //只能复制自身的可枚举的属性和symbol,不包含自身继承的和不可枚举的属性
// let peo={
// qwer:"cc"
// }
// let sym=Symbol("sym");
// let obj={
// __proto__:peo,
// first:1,
// stu:{
// two:2
// }
// }
// obj[sym]="sym";
// Object.defineProperty(obj,"three",{
// enumerable:false,
// value:"3",
// writable:true,
// configurable:true
// })
// //浅拷贝
// let { ...new_obj } = obj;
// console.log(new_obj);
// /*
// {first: 1, stu: {…}, Symbol(sym): "sym"}
// first: 1
// stu: {two: "b"}
// Symbol(sym): "sym"
// __proto__: Object
// */
// //改动
// obj.first="a";
// obj.stu.two="b";
// //测试
// console.log(new_obj.first+"==="+obj.first);//1 === a
// console.log(new_obj.stu.two+"==="+obj.stu.two);//b === b
//================================================================
//第五种
//Object.getOwnPropertyDescriptors方法配合Object.defineProperties
//Object.getOwnPropertyDescriptors() 方法用来获取一个对象的所有自身属性的描述符
//Object.defineProperties() 方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象
//只能复制自身的属性(包括不可枚举的属性以及symbol),但不可复制继承的属性
// let peo={
// qwer:"cc"
// }
// let sym=Symbol("sym");
// let obj={
// __proto__:peo,
// first:"1",
// stu:{
// two:"2"
// }
// }
// obj[sym]="sym";
// Object.defineProperty(obj,"three",{
// enumerable:false,
// value:"3",
// writable:true,
// configurable:true
// })
// // console.log(obj.qwer);//cc
// //浅复制
// let new_obj=Object.defineProperties({},Object.getOwnPropertyDescriptors(obj));
// console.log(new_obj);
// /*
// {first: "1", stu: {…}, three: "3", Symbol(sym): "sym"}
// first: "1"
// stu: {two: "b"}
// Symbol(sym): "sym"
// three: "3"
// __proto__: Object
// */
// //改动
// obj.first="a";
// obj.stu.two="b";
// obj.three="c"
// //测试
// console.log(new_obj.three+"==="+obj.three);//3===c
// console.log(new_obj.first+"==="+obj.first);//1===a
// console.log(new_obj.stu.two+"==="+obj.stu.two);//b===b
//==========================================================================
//第六种
//Object.create方法配合Object.getOwnPropertyDescriptors
//Object.getOwnPropertyDescriptors() 方法用来获取一个对象的所有自身属性的描述符
//Object.create(proto[, propertiesObject])
/*propertiesObject
可选。如果没有指定为 undefined,则是要添加到新创建对象的可枚举属性(即其自身定义的属性,
而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应
Object.defineProperties()的第二个参数*/
//只能复制自身的属性(包括不可枚举的属性以及symbol),但不可复制继承的属性
// let peo={
// qwer:"cc"
// }
// let sym=Symbol("sym");
// let obj={
// __proto__:peo,
// first:"1",
// stu:{
// two:"2"
// }
// }
// obj[sym]="sym";
// Object.defineProperty(obj,"three",{
// enumerable:false,
// value:"3",
// writable:true,
// configurable:true
// })
// //浅复制
// let new_obj=Object.create({},Object.getOwnPropertyDescriptors(obj));
// console.log(new_obj);
// /*
// {first: "1", stu: {…}, three: "3", Symbol(sym): "sym"}
// first: "1"
// stu: {two: "b"}
// Symbol(sym): "sym"
// three: "3"
// __proto__: Object
// */
// //改动
// obj.first="a";
// obj.stu.two="b";
// obj.three="c"
// //测试
// console.log(new_obj.three+"==="+obj.three);//3===c
// console.log(new_obj.first+"==="+obj.first);//1===a
// console.log(new_obj.stu.two+"==="+obj.stu.two);//b===b
</script>
</body>
</html>
有问题欢迎交流,可以随时补充
觉得不错,可以点个赞,谢谢啦