精华内容
下载资源
问答
  • 主要介绍了JS对象深度克隆方法,结合实例形式分析了JavaScript深度克隆的实现技巧,需要的朋友可以参考下
  • 题外知识 1. 浅度克隆 基本(原始)数据类型为值传递 引用数据类型:仍为引用传递 2. 深度度克隆 ...// 对象深度克隆 function clone(obj) { var buf; if (obj instanceof Array) { buf = []; let

    题外知识

    1. 浅度克隆

    • 基本(原始)数据类型为值传递
    • 引用数据类型:仍为引用传递

    2. 深度度克隆

    • 所有元素或属性完全克隆
    • 与原引用类型完全独立(后面修改对象属性的时候,原对象不会改变)

    code

    一般就Array,Object。且array是object的一种特殊情况
    摘自:百度结果

    // 对象深度克隆
    function clone(obj) {
        var buf;
        if (obj instanceof Array) {
            buf = [];
            let i = obj.length;
            while (i--) {
                buf[i] = clone(obj[i]);
            }
            return buf;
        } else if (obj instanceof Object) {
            buf = {}
            for (let k in obj) {
                buf[k] = clone(buf[k]);
            }
            return buf;
        } else {
            return obj;
        }
    }
    

    摘自:uview.js的对象深度克隆

    //判断arr是否为一个数组,返回一个bool值
    function isArray (arr) {
        return Object.prototype.toString.call(arr) === '[object Array]';
    }
    // 深度克隆
    function deepClone (obj) {
    	// 对常见的“非”值,直接返回原来值
    	if([null, undefined, NaN, false].includes(obj)) return obj;
        if(typeof obj !== "object" && typeof obj !== 'function') {
    		//原始类型直接返回
            return obj;
        }
        var o = isArray(obj) ? [] : {};
        for(let i in obj) {
            if(obj.hasOwnProperty(i)){
                o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
            }
        }
        return o;
    }
    

    其他

    1.判断对象的类型

    1.code

    // 判断arr是否为一个数组,返回一个bool值
    function isArray (arr) {
        return Object.prototype.toString.call(arr) === '[object Array]';
    }
    // 判断arr是否为一个对象,返回一个bool值
    function isArray (arr) {
        return Object.prototype.toString.call(arr) === '[object Object]';
    }
    

    2.扩展

    在Object.prototype上有一个toString方法,返回的是值类型。也就是说它可以精准地判断输入值的数据类型。

    //原始数据类型 start
    console.log(Object.prototype.toString.call(1))   //[object Number]
    console.log(Object.prototype.toString.call("hello")) //[object String]
    console.log(Object.prototype.toString.call(true)) //[object Boolean]
    console.log(Object.prototype.toString.call(null))  //[object Null]
    let aa;
    console.log(Object.prototype.toString.call(undefined))  //[object Undefined]
    //原始数据类型 end
    
    //引用数据类型 start
    console.log(Object.prototype.toString.call({}))  //[object Object]
    console.log(Object.prototype.toString.call([]))  //[object Array]
    function f1(){
    	var a=1
    }
    console.log(Object.prototype.toString.call(f1))   //[object Function]
    //引用数据类型 end
    
    • 这里利用call,就是改变this指向,让()里面的内容来调用Object.prototype.toString方法;
    let arr1=[]
    console.log(Object.prototype.toString(arr2)) //[object Object]
    console.log(Object.prototype.toString.call(arr2)) //[object Array]
    

    所以call改变this从Object指向了arr1这个对象(数组是对象的一种特殊形式)

    根据原型链的知识(暂未学习)

    既然Object的原型对象上有toString方法,JavaScript中,所有类都是Object的实例对象,因此toString()方法应该也被继承了,那为啥又要调用Object.prototype.toString方法,而不直接使用toString方法,让它自己顺着原型链找到这个.toString方法然后调用呢????
    实际上,所有类在继承Object的时候,改写了toString()方法。
    而只有Object原型上的方法是可以输出数据类型的
    因此我们想判断数据类型时,也只能使用原始方法。继而有了此方法:Object.prototype.toString.call(obj)

    • 那么被改写成什么样了
    var arr=[1,2,3]
    	console.log(Array.prototype.hasOwnProperty('toString'))  //true
    	console.log(Array.hasOwnProperty('toString'))  //false
    	console.log(arr.hasOwnProperty('toString'))    //false
    

    所以只有在Object.prototype上有toString方法

    2.比较typeof与instanceof

    相同点

    JavaScript 中 typeof 和 instanceof 常用来判断一个变量是否为空, 或者是什么类型的。

    不同点

    1. typeof
    • 返回值是一个字符串,用来说明变量的数据类型。
    • typeof 一般只能返回如下6(三个合并成了一个)个结果 number, string, boolean, object ( null, array , object ), undefined, function;
     //原始数据类型 start
      console.log(typeof 1) 
      console.log(typeof ("hello"))
      console.log(typeof (true)) 
      console.log(typeof (null)) 
      console.log(typeof (undefined)) 
      //原始数据类型 end
    
      //引用数据类型 start
      console.log(typeof ({})) 
      console.log(typeof ([]))
      function f1() {
          var a = 1
      }
      console.log(typeof (f1)) 
       //引用数据类型 end
    

    结果
    在这里插入图片描述

    那么问题来了

    Null Array Object 均返回 object,还是无法精确判断他的类型

    2.instanceof
    • 返回值为布尔值
    • instanceof 用于判断一个变量是否属于某个对象的实例(即他是8种数据类型中的哪一种)

    示例

    console.log({} instanceof Object) //true
    
    展开全文
  • 如何深度克隆一个对象 在我们日常工作中经常会遇到需要去克隆一个对象比如多个地方用到的公共的图表基本参数的配置 相信很多人会想到用 Object.assign, JSON.stringify 和 JSON.parse 方法去克隆一个对象,这个可以...

    如何深度克隆一个对象

    在我们日常工作中经常会遇到需要去克隆一个对象比如多个地方用到的公共的图表基本参数的配置

    相信很多人会想到用 Object.assign, JSON.stringifyJSON.parse 方法去克隆一个对象,这个可以明确告诉大家这些都是些不靠谱的浅度克隆。

    我们先来试一下 Object.assign 在控制台执行下列操作

    clipboard.png

    大家有没有发现联动了。关于此方法具体请参考文档
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

    接下来我们看下 JSON.stringifyJSON.parse 克隆对象,同样在控制输入

    clipboard.png

    大家有没有发现什么异常?虽然 JSON.stringify(value[, replacer[, space]]) 可以处理但是太麻烦了,这个方法我就不多说了具体还是参考文档
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

    下面咋们来看一种稍微靠谱的一种方式。在本站搜的前几条中发现的。

    function isArray (arr) {
        return Object.prototype.toString.call(arr) === '[object Array]';  
    }
    // 深度克隆
    function deepClone (obj) {  
        if(typeof obj !== "object" && typeof obj !== 'function') {
            return obj;        //原始类型直接返回
        }
        var o = isArray(obj) ? [] : {}; 
        for(i in obj) {  
            if(obj.hasOwnProperty(i)){ 
                o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i]; 
            } 
        } 
        return o;
    }

    看是靠谱是真是假我们来验证一把 还是在控制台输入

    clipboard.png

    大家发现什么异常的了吗?

    这个没有区分具体的对象,在此问下大家js的对象有哪些呢?相信一般人答不出来4个
    [object Object], [object Array], [object Null], [object RegExp], [object Date], [object HTMLXXElement], [object Map],[object Set],... 等等一系列

    检测类型使用 Object.prototype.toString.call(xxx)typeof

    我们分析下上面对象中哪些是引用类型需要特殊处理呢?相信大家都不陌生了。[object Object][object Array]

    好!详细大家思路有了,咋们用递归来实现一把吧!

    const deepClone = function(obj) {
      // 先检测是不是数组和Object
      // let isMap = Object.prototype.toString.call(obj) === '[object Map];
      // let isSet = Object.prototype.toString.call(obj) === '[object Set];
      // let isArr = Object.prototype.toString.call(obj) === '[object Array]';
      let isArr = Array.isArray(obj);
      let isJson = Object.prototype.toString.call(obj) === '[object Object]';
      if (isArr) {
        // 克隆数组
        let newObj = [];
        for (let i = 0; i < obj.length; i++) {
          newObj[i] = deepClone(obj[i]);
        }
        return newObj;
      } else if (isJson) {
        // 克隆Object
        let newObj = {};
        for (let i in obj) {
          newObj[i] = deepClone(obj[i]);
        }
        return newObj;
      }
      // 不是引用类型直接返回
      return obj;
    };
    
    Object.prototype.deepClone = function() {
      return deepClone(this);
    };
    咋们先不考虑 Map Set Arguments [object XXArrayBuffer] 对象了原理都是一样

    各种情况分析完了才说算是真克隆
    我们在控制台看下

    • 注意先要把方法在控制台输进去,在调试

    clipboard.png

    是不是解决了? 在此并没有结束。 专注的伙伴们相信发现了对象中包含了个 deepClone 方法,具体细节我们在此就不多说了,我们给 Object 添加了个 Object.prototype.deepClone方法导致了每个对象都有了此方法。

    原则上我们不允许在原型链上添加方法的,因为在循环中 for in, Object.entries, Object.values, Object.keys 等方法会出现自定义的方法。

    相信熟悉 Object 文档的伙伴人已经知道解决方案了,

    Object.defineProperty 这个方法给大家带来了福音 具体参考 Object 文档。我们使用一个enumerable (不可枚举)属性就可以解决了。

    在原来基础上添加以下代码即可。

    Object.defineProperty(Object.prototype, 'deepClone', {enumerable: false});

    在看控制台

    clipboard.png

    同样上面方法中也是无法克隆一个不可枚举的属性。

    完整代码如下

    const deepClone = function(obj) {
      // 先检测是不是数组和Object
      // let isArr = Object.prototype.toString.call(obj) === '[object Array]';
      let isArr = Array.isArray(obj);
      let isJson = Object.prototype.toString.call(obj) === '[object Object]';
      if (isArr) {
        // 克隆数组
        let newObj = [];
        for (let i = 0; i < obj.length; i++) {
          newObj[i] = deepClone(obj[i]);
        }
        return newObj;
      } else if (isJson) {
        // 克隆Object
        let newObj = {};
        for (let i in obj) {
          newObj[i] = deepClone(obj[i]);
        }
        return newObj;
      }
      // 不是引用类型直接返回
      return obj;
    };
    
    Object.prototype.deepClone = function() {
      return deepClone(this);
    };
    Object.defineProperty(Object.prototype, 'deepClone', {enumerable: false});
    为了兼容低版本浏览器需要借助 babel-polyfill;

    好了,深度克隆介绍到此。

    展开全文
  • export function deepClone(obj) { ...//obj为list时typeof obj.splice为'function',为对象时typeof obj.splice为'undefined' if (obj && typeof obj === "object") { for (let key in obj) { if (obj[k.
    export function deepClone(obj) {
      let result = typeof obj.splice === "function" ? [] : {};//obj为list时typeof obj.splice为'function',为对象时typeof obj.splice为'undefined'
      if (obj && typeof obj === "object") {
        for (let key in obj) {
          if (obj[key] && typeof obj[key] === "object") {
            result[key] = deepClone(obj[key]);
          } else {
            result[key] = obj[key];
          }
        }
        return result;
      }
      return obj;
    }

     

    展开全文
  • 主要介绍了JS对象深度克隆,结合实例形式分析了JavaScript对象深度克隆的实现方法与相关注意事项,需要的朋友可以参考下
  • C#中如何深度克隆一个对象

    千次阅读 2017-03-16 10:44:14
    C#中如何深度克隆一个对象? ASP.NETAsp.net.Net其他C#代码片段 Share 如何深度克隆一个对象? 普通版: public static object CloneObject( object obj ) { using ( MemoryStream memStream...
    C#中如何深度克隆一个对象? 
     
    

    Share

    如何深度克隆一个对象?

    普通版:

            public static object CloneObject( object obj )
            {
                using ( MemoryStream memStream = new MemoryStream( ) )
                {
                    BinaryFormatter binaryFormatter = new BinaryFormatter( null ,
                         new StreamingContext( StreamingContextStates.Clone ) );
                    binaryFormatter.Serialize( memStream , obj );
                    memStream.Seek( 0 , SeekOrigin.Begin );
                    return binaryFormatter.Deserialize( memStream );
                }
            }
    

    泛型版:

    public  static  T  Clone<T>(T  obj)
    {
            T  ret  =  default(T);
            if  (obj  !=  null)
            {
                    XmlSerializer  cloner  =  new  XmlSerializer(typeof(T));
                    MemoryStream  stream  =  new  MemoryStream();
                    cloner.Serialize(stream,  obj);
                    stream.Seek(0,  SeekOrigin.Begin);
                    ret  =  (T)cloner.Deserialize(stream);
            }
            return  ret;
    }
    展开全文
  • 在ES6中在对象的原型的有一个assign方法,可以实现对象克隆,但克隆是浅克隆,主要表现在对象的第二层如果含有对象,则第二层的对象还是引用原有的对象,有时候并不能达到我们的预期。而比较简单的一种方法实现深...
  • 就是说,在把一个对像赋值给一个变量时,那么这个变量所指向的仍就是原来对 像的地址。那怎么来做呢?答案是“克隆”。 克隆有两种方法:一种是“浅克隆”,一种是“深克隆”(深度克隆)。 浅克隆:基本类型为值...
  • 本篇文章是对JAVA对象深度克隆进行了详细的分析介绍,需要的朋友参考下
  • 深度拷贝指的就是把一个对象中的所有属性或方法,一个个的找到,并且在另一个对象中开辟相应的空间,一个一个的存储到另一个对象中。 题目需求:实现对象深度克隆对象中还有对象或者数组 举个栗子: let obj...
  • JS对象深度克隆实现

    万次阅读 多人点赞 2016-10-07 16:11:42
    本文介绍了JavaScript对象深度克隆的实现,分析了针对原始类型(数值、字符串、布尔值)和对象类型(对象,函数、数组)实现深度克隆的方法,最后给出了一个通用的JS对象深度克隆的方法。
  • 今天整理了下资料,分析下为什么句话可以实现纯数据json对象深度克隆,感兴趣的朋友可以了解下哦
  • Java实现对象深度克隆

    2021-03-07 15:44:56
    实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,代码如下 import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io....
  • js/ts 实现对象深度克隆

    千次阅读 2019-11-23 13:20:57
    自己实现了一个对象深度克隆: 主要缺陷只有一个: 对键值为循环调用的对象无能为力,会堆栈溢出。 作用: 适合常规的纯数据对象深度克隆 function clone(o: any, record = [o]) { switch (Object.type(o)) {...
  • js对象深度克隆

    2020-02-24 10:42:46
    在聊JavaScript(以下简称js)深度克隆之前,我们先来了解一下js中对象的组成。 在js中一切实例皆是对象,具体分为原始类型和合成类型:原始类型对象指的是Undefined、Null、Boolean、Number和String,按值传递。...
  • java的两种深度克隆方法,1cloneTest是用Cloneable接口的clone方法实现(对象必须要实现cloneable接口).2cloneSerialize.java是用对象流写对象到byte数组中,然后从byte数组中取得对象.(对象必须要实现serializble接口)
  • 主要介绍了JavaScript对象深度克隆介绍,本文详细的讲解了什么是对象深度克隆,并给出了示例代码,需要的朋友可以参考下
  • java中实现对象深度克隆

    千次阅读 2018-08-03 10:08:25
    python中有深度拷贝(也可以叫深度克隆)和浅拷贝,同样在java中很多时候需要深度拷贝对象,所谓的深度拷贝对象指的就是对于对象的所用数据及其全部进行copy份,变成两完全不相关的对象,而浅拷贝不拷贝对象所用...
  • 一个前端笔试题:使用JavaScript深度克隆一个对象。可是我发现大多数人都是空白,问他为什么不做,大部分说不懂这题目的意思。 科普一下: js一般有两种不同数据类型的值: 基本类型(包括undefined,Null,...
  • JS对象深度克隆的实现

    千次阅读 2018-08-21 17:39:11
    (1)原始类型包括:Number、String、Boolean、null、undefined(我们需要克隆的主要是前面三) (2)对象类型包括:对象(Object),函数(Function)、数组(Array)。 在克隆过程中对这两类数据类型的处理...
  • 克隆的概念 克隆分为两种:深克隆和浅克隆 深克隆 所有元素或属性完全复制,与原对象完全脱离,也就是说所有对新...–ES6中我们可以通过Object.assign的方式来实现深度克隆。 1.javascript(ES5)中对象的克隆 function
  • 要了解什么是深度克隆对象,首先要知道什么是深拷贝。深拷贝指的是修改克隆出来的对象不会改变原始的对象,基本数据类型的拷贝都是深拷贝。如下代码 var str = 'a'; var str1 = str; str1 = '123'; console.log(str...
  • vue对象深度克隆办法

    千次阅读 2020-10-12 14:43:08
    通过js序列化,将js转换成字符串,然后再将字符串转换成js对象 var olbObj = {a:1}; var str = JSON.stringify(obj); //序列化对象 var newobj = JSON.parse(str); //还原 //相当于 var newObj = JSON.parse(JSON....
  • 一个用于对象深度克隆的同构和可配置javascript函数
  • 简要介绍:js中的对象的赋值,其实是实现了对象的引用,...–ES6中我们可以通过Object.assign的方式来实现深度克隆。1.javascript(ES5)中对象的克隆function deepClone(obj){ var newObj= obj instanceof Array?[]:{};
  • //深度克隆 var obj = { name: "shishuo", age: 20, wife: { name: "xiazixi", age: 20 } } function deepClone(origin,target){ for(var prop in obj){ if(origin.hasOwnProperty(prop
  • var obj = {name:'张三'}; var str; var newObj = {}; str = JSON.stringify(obj), //序列化对象 newObj = JSON.parse(str); //还原 console.log(obj === newObj); //false ...【右上角点赞,谢谢】...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,860
精华内容 6,744
关键字:

如何深度克隆一个对象