zoukankan      html  css  js  c++  java
  • JS中的深拷贝与浅拷贝

    首先,先交代下,克隆只针对对象,数组,函数等复杂数据.

    先看,浅拷贝,浅拷贝就是将栈内存中的引用复制一份,赋给一个新变量,本质上两个指向堆内存中的同一个地址,内容也相同,其中一个内容变化了的话,另一个也变化.

    var ljy={
        name:"li jingyi",
        age:23,
        address:{city:"chengdu",
            strict:"pidu"}
    }
    function clone(oldObj){
        if(oldObj==null){return null};
        if(typeof oldObj!=="Object"){
            return oldObj;}
        var newObj =Array.isArray(oldObj)?[]:{};
        for (var key in oldObj){
            newObj[key] = oldObj[key];
        }
        return newObj
    }
    var ljy2 = clone(ljy);
    console.log(ljy===ljy2);//true
    ljy.name='yeeyee';
    console.log(ljy2.name)//yeeyee

    很明显可以看出,改变其中一方的属性的值,另一方也会改变.

    接下来我们看看深拷贝的实现:

    function deepclone(oldObj){
    var newObj = Array.isArray(oldObj)?[]:{};
    for(var key in oldObj){
        if(typeof oldObj[key] !=='object'){
            newObj[key] =oldObj[key]
        }else{
            newObj[key]=deepclone(oldObj[key])
        }
    }
    return newObj;
    }
    
    var ljy={
        name:"li jingyi",
        age:23,
        address:{city:"chengdu",
            strict:"pidu strict"}
    }
    
    var yee =deepclone(ljy);
    console.log(ljy===yee)//false
    yee.sname="Jerry";
    yee.address.strict="Wuhou strict";
    console.log(ljy.name)//还是li jingyi 原对象没变
    console.log(ljy.address.strict)//还是pidu stict原对象没变

    利用了递归的思想来实现深拷贝.首先,用isArray函数来判断是否为数组.之后判断oldObj中的元素通过typeof中所显示的是否为object(typeof下文会详细介绍),是的话实现深拷贝.通过代码就可以看出其与浅拷贝之间的差别.当然,还有更简单的做法,那么请看下面的代码:

    var ljy={
        name:"li jingyi",
        age:23,
        address:{city:"chengdu",
            strict:"pidu strict"}
    }
    
    var yee =JSON.parse(JSON.stringify(ljy));
    console.log(ljy===yee)//false
    yee.sname="Jerry";
    yee.address.strict="Wuhou strict";
    console.log(ljy.name)//还是li jingyi 原对象没变
    console.log(ljy.address.strict)//还是pidu stict原对象没变

    我们可以使用json.parse()方法处理数据,将其转换为Javascript对象.

    var jsontext='{"firstname":"White","lastname":"Tom"}';
    var contact=JSON.parse(jsontext);
    document.write(contact.lastname +','+contact.firstname);
    
    
    //Output:Tom,White

    JSON.stringfy()从一个对象中解析出字符串,而JSON.parse()从一个字符串中解析出JSON对象,这样亦可实现深拷贝.

    前面我们,讲到了typeof,那么接下来,我再总结下:typeof、instanceof以及isArray.

    typeof返回值是一个字符串,用来说明变量的数据类型,返回值分别有:string、boolean、number、function、object以及undefined.typeof在判断null,array,object以及函数实例时,得到的object,这样就会导致在判断这些数据类型的时候,得到的不是真实的数据类型.原来,看过类似的判断array怎么办的方式,那么这里判断array的话,是可以使用instanceof以及isarray方式的.

    instanceof是判断对象是谁的实例,这里的实例就牵扯了对象的继承,它的判断,就是根据原型链进行搜寻,在对象obj1的原型链上,若存在另一个对象obj2的原型属性,那么表达式表达式obj1 instanceof obj2返回值为true否则为false.

    这里再说下上面浅拷贝深拷贝代码中用到的Arrary.isArray函数,用于确定传递的值是否是一个array,而且在检测Array实例时,Array.isArray优于instanceof,因为Array.isArray能检测出iframes.

  • 相关阅读:
    联想IdeaPad品牌出炉 三款笔记本亮相
    [推荐]2008年必不可少的20个网络产品
    微软公开.NET Base Classes源代码
    [共享一下]Head.First.设计模式.中文版
    IT: 蓝牙十岁了
    祝贺“阿来之家”博客正式开通~
    NodeJS安全设计:好吃的草莓味糖果,只给好朋友小红
    NodeJS文件读取:感恩常在抓把糖果,愉悦客人
    NodeJS缓存机制:畅销货,就多囤一点呗
    安装pygame出现is not a supported wheel on this platform解决办法
  • 原文地址:https://www.cnblogs.com/ljylearnsmore/p/14483223.html
Copyright © 2011-2022 走看看