zoukankan      html  css  js  c++  java
  • 对象的浅拷贝与深拷贝(部分整理)

    PS:本文整理的为部分对象的浅拷贝与深拷贝(与基本数据类型的概念不一样。eg:就浅拷贝来说,如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。)

    浅拷贝

    Object.assign():

    方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性。

    语法:Object.assign(target, ...sources)
    target:目标对象
    sources: 源对象
    返回值: 目标对象
    Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象(浅拷贝)。该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。如果合并源包含getter,这可能使其不适合将新属性合并到原型中。为了将属性定义(包括其可枚举性)复制到原型,应使用Object.getOwnPropertyDescriptor()和Object.defineProperty() 。
    String类型和 Symbol 类型的属性都会被拷贝。
    在出现错误的情况下,例如,如果属性不可写,会引发TypeError,如果在引发错误之前添加了任何属性,则可以更改target对象。
    注意,Object.assign 不会在那些source对象值为 null 或 undefined 的时候抛出错误。

    PS: 新补充: 拷贝的是属性,如果只是一层对象,浅拷贝无问题,值不会相互影响,若是有第二层对象,拷贝之后也会相互影响。

    深拷贝

    使用JSON.parse(),JSON.stringify()实现对对象的深拷贝(此处不讲遍历)

    概念:根据不包含引用对象的普通数组深拷贝得到启发,不拷贝引用对象,拷贝一个字符串会新辟一个新的存储地址,这样就切断了引用对象的指针联系。

          var test={
                a:"ss",
                b:"dd",
                c:[
                  {dd:"css",ee:"cdd"},
                  {mm:"ff",nn:"ee"}
               ]
          };
          var test1 = JSON.parse(JSON.stringify(test));//拷贝数组,注意这行的拷贝方法
          console.log(test);
          console.log(test1);
          test1.c[0].dd="change"; //改变test1的c属性对象的d属性
          console.log(test);  //不影响test
          console.log(test1);
    

    根据测试结果,test1已经从test复制一份,并且test1改变其中属性的值时,对原来的对象test没有造成影响。

    JSON.parse(),JSON.stringify()兼容性问题

    可以通过为IE7以及IE7以下版本的IE浏览器引入json2.js,使用json2.js来解决JSON的兼容性问题

    <!--[if lt IE 7]>
    <script src="具体放路径/json2.js"></script> 
    <![endif]-->
    

    json2.js的github地址为:https://github.com/douglascrockford/JSON-js

    JSON.stringify()的作用是将 JavaScript 对象转换为 JSON 字符串,
    JSON.parse()可以将JSON字符串转为一个对象。
    

    PS:本文所介绍的对象的深拷贝与浅拷贝并不完整,之后如有新内容会更新整理。

  • 相关阅读:
    所谓guard进程不能启动
    文件拒绝访问
    (转)Android 自定义 spinner (背景、字体颜色)
    (转)安装Android SDK时遇到Failed to rename directory
    (转)Download interrupted: Connection to https://dl-ssl.google.com refused
    安卓中Activity的onStart()和onResume()的区别是什么
    Could not find class 'org.ksoap2.serialization.SoapObject
    Android三种左右滑动效果 手势识别(转)
    The method of type must override a superclass method解决方式(转)
    MySQL插入中文时出现ERROR 1406 (22001): Data too long for column 'name' at row 1 (转)
  • 原文地址:https://www.cnblogs.com/Carmena/p/14079362.html
Copyright © 2011-2022 走看看