• 前端的多种克隆方式和注意事项


    克隆的意义和常见场景:

    1. 意义: 保证原数据的完整性和独立性
    2. 常见场景: 复制数据, 函数入参, class构造函数等

    浅克隆:

    对象常用的浅克隆

    1. es6扩展运算符...
    2. Object.assign

    数组常用的浅克隆

    1. es6的扩展运算符...
    2. slice=>arr.slice(0)
    3. [].concat

    深度克隆:

    1. 克隆对象的每个层级
    2. 如果属性值是原始数据类型, 拷贝其值, 也就是我们常说的值拷贝
    3. 如果属性值是引用类型, 递归克隆

    深度克隆的方法:

    JSON.stringify+JSON.parse

    eg:JSON.parse(JSON.stringify(对象或数组))

    JSON.stringify+JSON.parse的局限性:

    1. 只能复制普通键的属性, symbol类型的无能为力
    2. 循环引用对象,比如window不能复制
    3. 函数,Date,Reg,Blob等类型不能复制
    4. 性能差

    消息通讯 --BroadcastChannel等等

    1. let chId = 0
    2. function clone(data) {
    3. chId++
    4. let cname = `__clone__${chId}`
    5. let ch1 = new BroadcastChannel(cname)
    6. let ch2 = new BroadcastChannel(cname)
    7. return new Promise((resolve)=> {
    8. ch2.addEventListener('message', ev=>resolve(ev.data), {once: true});
    9. ch1.postMessage(data)
    10. })
    11. }
    12. clone({
    13. a: 'fdfewfjew',
    14. b: 1,
    15. // c: Symbol('gggg')
    16. })
    17. .then(res=> {
    18. console.log(res)
    19. })
    20. .catch(err=> {
    21. console.log(err)
    22. })

    消息通讯:

    1. window.postMessage
    2. BroadcastChannel
    3. Shared Worker
    4. Message Channel

    基于消息通讯的局限:

    1. 循环引用对象不能复制, 如:windows
    2. 函数不能复制
    3. 同步变成异步

    手写深度克隆--递归

    1. function arrLengthMoreThanZero(val) {
    2. return Array.isArray(val) && val.length > 0
    3. }
    4. // 非空对象或者数组length大于0的数组
    5. function isNotNullObjectOrArr (val) {
    6. if(val == null) return false;
    7. const isObject = Object.prototype.toString.call(val) === '[object Object]'
    8. if(isObject && JSON.stringify(val) === '{}') return false;
    9. return Object.prototype.toString.call(val) === '[object Object]' || arrLengthMoreThanZero(val);
    10. }
    11. function deepClone(obj={}) {
    12. if(!isObject(obj)) {
    13. return obj
    14. }
    15. // 初始化返回结果
    16. let result;
    17. // instance of判断是不是数组
    18. if(obj instanceof Array) {
    19. result = []
    20. }
    21. else {
    22. result = {}
    23. }
    24. // for in循环对象和数组都能使用
    25. for(let key in obj) {
    26. // hasOwnProperty=>保证key不是原型的属性
    27. if(obj.hasOwnProperty(key)) {
    28. // 递归
    29. result[key] = deepClone(obj[key])
    30. }
    31. }
    32. return result
    33. }

  • 相关阅读:
    Thinkphp5萤火商城B2C小程序源码
    第三部分—数据结构与算法基础_1. 数据结构理论
    MyBatis调用SqlServer存储过程
    上班都在刷八股文、Alibaba架构师这份“Java面试突击手册”比刷剧还上瘾
    nginx反向代理.NetCore开发的基于WebApi创建的gRPC服务
    使用open3d可视化3d人脸
    【广州华锐互动】智能变电站AR仿真实训系统大大提高培训的效率和质量
    线性代数的本质(八)——内积空间
    时序分析基础(3)——output_delay
    Linux 之七:Linux 防火墙 和进程管理
  • 原文地址:https://blog.csdn.net/qq_42750608/article/details/133362971