当前位置 : 主页 > 网络编程 > 其它编程 >

JS拷贝对象浅克隆深克隆深拷贝与浅拷贝,实现深拷贝的几种方法

来源:互联网 收集:自由互联 发布时间:2023-07-02
JS拷贝对象浅克隆深克隆深拷贝浅拷贝对象简介js程序中都是用对象结构来描述显示中一个事物对象就是一组属性和方法的集合。面向对象三大特点:封装继 JS拷贝对象 浅克隆深克隆 深拷
JS拷贝对象浅克隆深克隆深拷贝浅拷贝对象简介js程序中都是用对象结构来描述显示中一个事物对象就是一组属性和方法的集合。面向对象三大特点:封装继

JS拷贝对象 浅克隆深克隆 深拷贝浅拷贝

对象简介

js程序中都是用对象结构来描述显示中一个事物对象就是一组属性和方法的集合。

面向对象三大特点: 封装继承多态。

克隆对象

浅克隆是克隆 一层深层次的对象级别的就克隆引用地址 深克隆是克隆 多层每一级别的数据都会克隆出来 浅克隆就是克隆了一层除了对象是克隆的引用类型地址其他都是 按值传递有自己的内存空间

点击进入查看按值传递

实现浅克隆方法

for in循环

  • 定义一个克隆函数用循环一个一个把对象中的属性赋值强行添加给新对象
  • 创建一个对象对象的属性有字符串对象数组
  • 调用克隆函数把刚刚创建的对象放进去
  • 分别输出得到对象的三个属性值
  • 更改克隆生成的对象中的a,b,c
  • 看看原来的对象是否变化
  • //------------------1------------------function clone(initalObj) {var obj {};for ( var i in initalObj) {obj[i] initalObj[i];}return obj;}//------------------2------------------var obj {a: "hello",b:{a: "world",b: 21},c:["Bob", "Tom", "Jenny"]};//------------------3------------------var cloneObj clone(obj);//------------------4------------------console.log(cloneObj.a);console.log(cloneObj.b);console.log(cloneObj.c);//------------------5------------------cloneObj.a "changed";cloneObj.b.a "changed";cloneObj.b.b 25;cloneObj.c[3] "Lilei";//------------------6------------------console.log(obj.a); //helloconsole.log(obj.b); //{a:"changed",b:25}console.log(obj.c); //[Bob,Tom,Jenny,Lilei]

    通过以上代码可以看出来obj.b 属性的属性值被 修改 cloneObj.b 值的时候修改 c 和 b 是同样的结果

    事实上就是for in循环 克隆引用类型的时候复制的都是引用地址

    ES6中的Object.assign方法

    Object.assign(target, ...sources)//参数//target目标对象//sources任意多个源对象//返回值//目标对象会被返回

    Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

    但是 Object.assign() 进行的是浅克隆克隆的是对象的属性的引用而不是对象本身。

    var obj {a: "LiLei",b: {a: "LiXiaolei",b: 21,},};var cloneObj Object.assign({}, obj);cloneObj.a "changed";cloneObj.b.a "changed";console.log(obj.a); //LiLeiconsole.log(obj.b.a); // "changed"var obj2 { a: 1, b: 2, c: 3 };var cloneObj2 Object.assign({}, obj2);cloneObj2.b 10;console.log(obj2);// { a: 1, b: 2, c: 3 }console.log(cloneObj2);// { a: 1, b: 10, c: 3 }

    可以看到修改cloneObj2.b原来obj2没有发生变化

    实现深克隆方法

    递归拷贝

    定义函数在函数执行前判断类型

    是否为null、是就直接返回null

    是否为数组是数组利用slice方法放到一个新数组返回

    在遍历的时候判断是否为引用类型如果原对象中当前值是原始类型就可以直接赋值否则当前属性不是原始类型的值再次调用clone函数继续复制当前属性值

    var LiMing{sname:LiMing,sage:11,score:null,firends:["jack","rose"],address:{prov:北京,city:北京,area:朝阳,street:成寿寺}}function clone(obj){if(objnull){return null;}if({}.toString.call(obj)"[object Array]"){var newArr[];newArrobj.slice();return newArr;}var newobj{};//遍历对象中的每个属性for(var key in obj){//如果原对象中当前值是原始类型就可以直接赋值if(typeof obj[key]!"object"){//在新对象中添加和原对象中同名的属性newobj[key]obj[key];//因为原始类型复制就是复制副本}else{//否则当前属性不是原始类型的值再次调用clone函数继续复制当前属性值newobj[key]clone(obj[key])}}return newobj;}var LiMingclone(LiMing);

    JSON.parse(JSON.stringify(obj));

    JSON.stringify() 方法用于将 Javascript 值(通常为对象或数组)转换为 JSON 字符串。 JSON.parse() 方法用于将一个 JSON 字符串转换为对象。

    用JSON.stringify把对象转成字符串再用JSON.parse把字符串转成新的对象。

    建议先看下 JSON.stringify()方法 --> 传送门

    var obj1 { LiLei: { age: 21 } };var obj2 JSON.parse(JSON.stringify(obj1));obj2.LiLei.age 25;console.log(obj1);// { LiLei: { age: 21 } }console.log(obj2);// { LiLei: { age: 25 } }console.log(obj1 obj2);// falseconsole.log(obj1.body obj2.body);// false

    可以看到克隆出来的对象和原对象除了长的相似别的已再无关系。

    注: 使用 JSON.stringify()方法时undefined、任意的函数以及 symbol 值出现在非数组对象的属性值中时会被忽略出现在数组中时被转换成 null。函数、undefined 被单独转换时会返回 undefined。 请看下边的例子

    var obj1 { LiLei: { age: 21 },isLilei: new RegExp(/\w/),money:undefined,speak:function(){console.log(I am ${this.sname}) },car:["二手奥拓",[五菱之光],new RegExp(/\w/),undefined,function haha(){console.log("hello")}],};var obj2 JSON.stringify(obj1); //{"LiLei":{"age":21},"isLilei":{},"car":["二手奥拓",["五菱之光"],{},null,null]}

    在这里插入图片描述 从以上结果可知这种方法能正确处理的对象只有 Number, String, Boolean即那些能够被 json 直接表示的数据结构。

    Object.create()方法

    Object.create(proto[, propertiesObject]) 仅靠父对象就可以创建子对象的一个方法。

    Object.create(proto[, propertiesObject])//参数//proto新创建对象的原型对象//propertiesObject可选。如果没有指定为 undefined则是要添加到新创建对象的不可枚举默认属性即其自身定义的属性而不是其原型链上的枚举属性对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数。//返回值//一个新对象带着指定的原型对象和属性。

    如下代码

    var obj {x: 1,y: {a: 1,b: 0,c: [1, 2, 3]}};var obj2 Object.create(obj);console.log(obj2 obj); //falseconsole.log(obj2);

    在这里插入图片描述

    在输出结果中可以看到obj2自己并没有属性属性全部都是继承于父对象

    上一篇:mongdb全文索引
    下一篇:没有了
    网友评论