使用js实现复制功能

 更新时间:2022年08月23日 10:38:42   作者:@Junean  
这篇文章主要为大家详细介绍了使用js实现复制功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了使用js实现复制功能的具体代码,供大家参考,具体内容如下

复制

1.遍历复制(for in)

特征:不修改引用关系(原来的属性还在),仅能复制字符属性,Symbol不能复制,不可枚举属性不能复制,原型链不能复制。浅复制

2.JOSN.parse(JSON.stringify(obj)) 转换复制

特征:修改引用关系(相当于创建一个新的对象,不再拥有原来的属性),仅能复制字符属性,Symbol不能复制,不可枚举属性不能复制,原型链不能复制,函数和其他类型不能复制。深复制

3.{…obj}解构赋值复制

特征:修改引用关系,Symbol和函数都能复制,不可枚举属性和原型链都不能复制。浅复制

4.Object.assign()对象复制

特征:不修改引用关系,可以复制属性、方法、Symbol类型,不可枚举属性和原型链都不能复制。浅复制

深复制**

1.使用defineProperty***

function cloneObject(source,target){
    if(source === null||source === undefined) return source;
    if(source===document) return;
    //判断target是不是继承对象的实例,是不是引用类型(null,undefined,Boolean,string,number都不是引用类型)
    if(!Object.prototype.isPrototypeOf(target)){
        //判断源对象是不是dom元素
        if(HTMLElement.prototype.isPrototypeOf(source)){
            //创建dom元素
             target = document.createElement(source.nodeName);
        }else if(source.constructor === RegExp){
            // 任何正则表达式都有source和flags,source是正则内容,flags是正则修饰符
            // 因为这两个属性都是只读属性,不能写入,必须通过构造函数创建时带入
            target = new RegExp(source.source,source.flags);
        }else if(source.constructor === Date){
            // 日期对象在创建的对象中将原有的日期对象放入,可以让当前日期对象变为原有日期对象的值,但是没有引用关系
            targer = new Date(source);
        }else if(source.constructor === Function){
            // 复制函数,通过正则表达式将函数中的参数以及函数体内容提取到数组中,然后通过new Function()创建
            var arr = source.toString().replace(/\n|\r/g,"").trim().match(/\((.*?)\)\s*\{(.*)\}/).slice(1);
            target = new Function(arr[0].trim(),arr[1]);
        }else if(source.constructor === Set){
            // set类型,在处理时,new Set时可以带入数组,因此我们将原有set的列表强转为数组,并且将这个强转后的数组复制给新数组
            target = new Set(cloneObject(Array.from(source.values())));
        }else if(source.constructor === Map){
            target = new Map();
            // 如果是map类型,遍历map中每个元素
            for(var [key,value] of source.entries()){
                // 如果key是引用类型,
                if(Object.prototype.isPrototypeOf(key)){
                     // 如果value引用类型,则将key和value分别做复制,并且将返回的结果放在map中
                    if(Object.prototype.isPrototypeOf(value)){
                        target.set(cloneObject(key),cloneObject(value));
                    }else{
                         //如果value不是引用类型,只将key复制,并且放入map
                        target.set(cloneObject(key),value);
                    }
                }else{
                    // 这是key不是引用类型时
                    if(Object.prototype.isPrototyeOf(value)){
                        target.set(key,cloneObject(value));
                    }else{
                        target.set(key,value);
                    }
                }
            }
        }
        else{
        //除了null和undefined,其他类型都有constructor。任何对象的constructor都是它的类型,利用其constructor创建对象
        //通过对象类型的反射创建新的同类型对象
            target = new source.constructor();
        }
        
    }
    //获取对象的所有字符属性名和Symbol属性名的数组
    var names = Object.getOwnPropertyName(source).concat(Object.getOwnPropertySymbols(source));
    for(var i = 0;i < names.lenght; i++){
        // 如果当前复制的是函数,并且这个函数的属性是prototype,那么这个属性不复制,否则会死循环
        if(source.constructor === Function&&names[i] === "prototype")
            continue;
        // 获取当前属性名的描述对象
        var desc = Object.getOwnPropertyDescriptor(source,names[i]);
        //   这个描述对象的值如果是引用类型
        if(Object.prototype.isPrototypeOf(desc.value)){
             // 根据需要将源对象的描述内容设置给当前目标对象相同属性名的描述内容,及值付为刚才创建相同类型的对象
            Object.defineProperty(target,names[i],{
                enumerable:desc.enumerable,
                configurable:desc.configurable,
                writable:desc.writable,
                value:cloneObject(desc.value)
            });
        }else{
             //如果描述的对象的值不是引用类型,直接将描述对象设置给目标对象的这个属性
            Object.defineProperty(target,names.desc);
        }
    }
    return target;
}


//原型.isPrototypeOf(对象)。对象里面是不是拥有xx的原型
//反射:通过对象

2.使用JSON对象实现深复制

使用**JSON.parse(str)**可以将字符串转换成对象;

使用**JSON.stringify(obj)**将对象转换成对象形式的字符串,其中无法转换对象中的方法,可以考虑先将对象中的方法使用toString()转为字符串,然后再转换使用JSON.stringify(obj);

*使用**JSON.parse(str)**可以将字符串转换成对象

var obj={
    a:1,
    b:3,    //ab复制不会随其中一个的变化而变化
    c:{        //c复制会随其中一个的变化而变化,因为c属于对象的地址引用关系
        d:10,
        e:20
    }
};
var o1 = JSON.parse(JSON.stringify(obj)); //将obj复制给o1

3.使用递归实现深复制

结构仅限于对象。如果存在数组、正则、日期对象、dom对象则不能使用。

var obj = {
a:1,
b:2,
c:{
        a:1,
  b:2,
  c:{
            a:1,
      b:2,
      }
}
}
//函数定义参数时,注意必要参数写在前面,非必要参数写在后面
function cloneObj(source,target){
    if(target === undefined) target = {};
for(var prop in source){
  //如果
        if(typeof source[prop] === "object" && source[prop] != null){
      target[prop] = {};
      cloneObj(source[prop],target[prop]);
  }else{
            target[prop] = source[prop];
  }
}
return target;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • JavaScript 开发工具webstrom使用指南

    JavaScript 开发工具webstrom使用指南

    本文给大家推荐了一款非常热门的javascript开发工具webstrom,着重介绍了webstrom的特色功能、设置技巧、使用心得以及快捷键汇总,非常的全面。
    2014-12-12
  • js代码实现轮播图

    js代码实现轮播图

    这篇文章主要为大家详细介绍了js代码实现轮播图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • 基于JS快速实现导航下拉菜单动画效果附源码下载

    基于JS快速实现导航下拉菜单动画效果附源码下载

    这是一个带变形动画特效的下拉导航菜单特效。该导航菜单在菜单项之间切换时,下拉菜单会快速的根据菜单内容的大小来动态变形,显示合适的下拉菜单大小,效果非常棒,对导航下拉菜单效果感兴趣的朋友一起通过本文学习吧
    2016-10-10
  • CSS(js)限制页面显示的文本字符长度

    CSS(js)限制页面显示的文本字符长度

    限制页面显示的字符长度,一直被众多网友倾睬,本人也是一fans利用闲暇时间搜集整理了一些实用技巧,需要了解的朋友可以参考下
    2012-12-12
  • Mint-UI时间组件起始时间问题及时间插件使用

    Mint-UI时间组件起始时间问题及时间插件使用

    这篇文章主要介绍了Mint-UI时间组件起始时间问题的解决方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-08-08
  • JavaScript生成二维数组的多种方法小结

    JavaScript生成二维数组的多种方法小结

    我经常在面试中问候:你能用 JavaScript 生成一个二维数组吗?这个问题看似简单,实际上却能揭示出面试者对 JavaScript 的熟练程度,天,就让我们一起来探索这个问题背后的答案,揭开生成二维数组的多种秘密,需要的朋友可以参考下
    2024-04-04
  • 详解JavaScript运算符中==和===的区别

    详解JavaScript运算符中==和===的区别

    在JavaScript中==运算符和===运算符是经常遇到的,那么二者有哪些区别呢,本文就来和大家进行简单的讨论,感兴趣的小伙伴可以跟随小编一起学习学习
    2023-05-05
  • 真见识了-全代码编写的图片

    真见识了-全代码编写的图片

    真见识了-全代码编写的图片...
    2007-08-08
  • 微信小程序实现底部弹出框

    微信小程序实现底部弹出框

    这篇文章主要为大家详细介绍了微信小程序实现底部弹出框,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • 按钮JS复制文本框和表格的代码

    按钮JS复制文本框和表格的代码

    有时候我们需要复制一个框的内容或者整个表格,一般的操作很可能造成一些不方便,一是操作步骤较为复制,一是复制表格的时候容易复制不完整或者格式出错。
    2011-04-04

最新评论