javaScript 深层复制

在工作中遇到了深浅复制的问题,所以详细总结一下:

深复制和浅复制只针对像 Object, Array 这样的复杂对象的。简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级。

var obj = { a:1, arr: [2,3] };
var shadowObj = shadowCopy(obj);

function shadowCopy(src) {
  var dst = {};
  for (var prop in src) {
    if (src.hasOwnProperty(prop)) {
      dst[prop] = src[prop];
    }
  }
  return dst;
}

这是一种典型的浅复制,shadowCopy方法将对象的各个属性进行依次复制,并不会进行递归复制,而 JavaScript 存储对象都是存地址的,所以浅复制会导致 obj.arr 和 shadowObj.arr 指向同一块内存地址。当其中一个变量对指向的值做了修改,另一个变量在调用时数值也就修改了。

shadowObj.arr[1] = 5;
obj.arr[1]   // = 5

下面给出深复制的代码:

function deepCopy ( obj ) {
         var tmp = {};
         for ( var k in obj ) {
            tmp[ k ] = obj[ k ];
         }
         return tmp;
    }
    //在这个函数中最关键的一步 tmp[ k ] = obj[ k ]
    //所以这里只需要保证 obj[ k ] 这个赋值是一个深度拷贝的对象即可.
    //注意: 函数的目的是得到 obj 的深拷贝副本. 因此递归一下.

    function deepCopy ( obj ) {
        var tmp = {}, k;
            for ( k in obj ) {
                if ( typeof obj[ k ] === ‘object‘ ) {
                    tmp[ k ] = deepCopy( obj[ k ] );
                } else {
                    tmp[ k ] = obj[ k ];
                }
            }
            return tmp;
        }

        // 如果处理这个对象
        var o3 = {
            name: ‘jim‘,
            scores: [
                90,
                95,
                85
            ]
        };

        // 该代码无法处理数组的情况,做如下改动
        function deepCopy ( obj ) {
            var tmp = obj.length >= 0 ?
                        obj instanceof Array ? [] : { length: 0 } :
                        {},
                k;
            for ( k in obj ) {
                if ( typeof obj[ k ] === ‘object‘ ) {
                    tmp[ k ] = deepCopy( obj[ k ] );
                } else {
                    tmp[ k ] = obj[ k ];
                }
            }
            return tmp;
        }

对于深复制,如果对象比较大,层级也比较多,深复制会带来性能上的问题。在遇到需要采用深复制的场景时,可以考虑有没有其他替代的方案。在实际的应用场景中,也是浅复制更为常用。

JSON.parse( JSON.stringify(a) )这种方法比较简单,但同时也存在问题

  • 无法复制函数
  • 原型链没了,对象就是object,所属的类没了。这会抛弃对象的constructor,也就是深复制之后,无论这个对象原本的构造函数是什么,在深复制之后都会变成Object。另外诸如RegExp对象是无法通过这种方式深复制的。
时间: 2024-12-16 20:10:12

javaScript 深层复制的相关文章

深层复制构造函数--初识

浅层复制构造函数会产生迷途指针,进而造成程序崩溃,所以,我们需要用深层复制构造函数来解决这个问题 #include <iostream> using namespace std; class A { public: A() { x = new int; *x = 5; } ~A() { delete x; x = NULL; } //删除指针后,紧接着就要把指针设置为 NULL,养成这样的习惯 A(const A&a) //深层复制构造函数 { cout << "

java数组对象的浅层复制与深层复制

实际上,java中数组对象的浅层复制只是复制了对象的引用(参考),而深层复制的才是对象所代表的值.

[JavaScript] js 复制到剪切板

zeroclipboard官网:https://github.com/zeroclipboard/ZeroClipboard 下载压缩包,得到两个“ZeroClipboard.js”和“ZeroClipboard.swf”两个文件. 首先页面中载入ZeroClipboard.js ZeroClipboard.setMoviePath( “ZeroClipboard.swf路径” );来指定ZeroClipboard.swf 的地址. demo: <!DOCTYPE html> <html

JavaScript深层克隆对象

今天做题看到了深层克隆对象,并且要求在原型链上编程 于是心血来潮索性来复习一下这个知识点 克隆对象,这名词看着高大上,其实也没什么,便是拷贝一个长的一模一样的对象 也许有初学的小伙伴在想,那还不简单么,so easy var obj1 = {name: 'payen'}; var obj2 = obj1; 这可并不是克隆对象,obj1和obj2根本就是同一个对象, 他俩指向同一个内存地址空间,拿到了同样的一个小房子 这是应为对象是引用值 说到引用值 JavaScript中引用值只有对象 这里注意

javascript 复制与粘贴操作

<script language="javascript"> function readTxt() { alert(window.clipboardData.getData("text")); } function setTxt() { var t=document.getElementById("txt"); t.select(); window.clipboardData.setData('text',t.createTextRa

【javascript】复制到剪贴板功能(支持目前各种浏览器)

本demo支持各种浏览器复制,亲测可用(IE8,IE9,IE10,火狐,谷歌). 本demo中使用了ZeroClipboard(下载地址:https://github.com/zeroclipboard/zeroclipboard). 本demo 必须在服务器环境下,浏览器直接打开无效. 本demo 需要引入3个文件:jquery.min.js.ZeroClipboard.min.js和ZeroClipboard.swf. <!DOCTYPE html> <html> <he

javascript copy 复制到粘贴板的方法

1.如果只是实现一个复制的功能呢有一个比较简单的方案废话不说,直接上代码 (pc 推荐) <script type="text/javascript"> function copyUrl2() { var Url2 = document.getElementById("biao1"); Url2.select(); // 选择对象 document.execCommand("Copy"); // 执行浏览器复制命令 } </sc

Java中的浅层复制和深层复制

浅层复制代码: 1 import java.util.*; 2 3 class Int{ 4 private int i; 5 public Int(int ii){i = ii;} 6 public void increment(){i++;} 7 public String toString(){ 8 return Integer.toString(i); 9 } 10 } 11 12 public class Cloning{ 13 public static void main(Stri

C++深层复制解决指针悬挂

代码: 1 #include <iostream> 2 #include <cstring> 3 4 using namespace std; 5 6 class mystring{ 7 public: 8 mystring(string s){ 9 cout<<"Constructor called."<<endl; 10 ptr = new char[s.length()+1]; 11 strcpy(ptr,s.c_str()); 1