zoukankan      html  css  js  c++  java
  • Js 对象拷贝

    Js 对象拷贝

    对象的引用在js里面实在的太常见了。如果不注意这个问题,则往往会犯一些小白一样的错误。比如:

    var pa = {
      name: 'huasheng',
      age: '20',
      address: {
        province: 'zzz',
        city: 'aaa'
      }
    };
    
    function test(param){
      var addr = param.address;
      addr.city = "bbb";
    }
    
    test(obj);
    
    console.log(obj.address.city); // bbb
    // 这里函数test里面的 addr = param.address 其实就产生了一个引用
    // 本来以为的是把param的address重新赋给一个变量 addr,然后修改 addr 里面的值,不去影响param
    // 但是实验结果发现,addr 和 param.address 两个其实是一个东西。

    关于Js变量引用的问题,其实就是数据类型的问题。在Js里面,有两种数据类型:基础类型和引用类型

    其中,Number, Boolean, String都是基础类型,引用类型包括:Object, Array, Function

    大家也可以参考一下这篇文章:http://www.cnblogs.com/diva/

    既然发现了问题,那当然要来解决问题。(下面主要针对的是Object和Array两种引用类型,在实际应用中,引用里面需要变化Function的需求不多,最多要求调用一下。)

    其实,解决办法说白了,就是重新拷贝一份新的数据,如果是基础类型的,直接赋值就OK, 引用类型的需要拷贝一份出来。这里的拷贝都要求能够深层拷贝对象。

    方案1:递归法

    function deepCopy(result, source) {
      for (var key in source) {
        var copy = source[key];
        if (source === copy) continue;//如window.window === window,会陷入死循环,需要处理一下
        if (is(copy, "Object")) {
          result[key] = arguments.callee(result[key] || {}, copy);
        } else if (is(copy, "Array")) {
          result[key] = arguments.callee(result[key] || [], copy);
        } else {
          result[key] = copy;
        }
      }
        
      return result;
      
      function is(obj, type) {
        var toString = Object.prototype.toString;
        return (type === "Null" && obj === null) ||
          (type === "Undefined" && obj === undefined ) ||
          toString.call(obj).slice(8, -1) === type;
      }
    
    }
    callee 的用法可以参见:JS 中的call,apply,bind 和 caller, callee

    方案2:JSON序列化法

    先把对象转成JSON格式的字符串,再将该字符串解析成新的对象。该方法可以一次性解决深层拷贝问题。简单易行。

    var pa = {
      name: 'huasheng',
      age: '20',
      address: {
        province: 'zzz',
        city: 'aaa'
      }
    };
    
    var b = JSON.parse(JSON.stringify(pa));
    console.log(b);
    b.address.city = 'bbb';
    console.log(b.address.city);    // bbb
    console.log(pa.address.city);   // aaa
    -----------------------------一花开五叶 结果自然成-------------------------------------------------
  • 相关阅读:
    VUEX
    使用element框架 增加router路由
    VUE目录
    elementUI 创建
    VUE组件(父子组件)
    VUE操作DOM获取HTML、删除HTML、插入HTML
    VUE网络交互axios(网络请求库)
    VUE 或者JS 常用数据类型及方法:字符串、数组、对象
    VUE实际案例--计数器(商城数量加减)
    VUE学习 --数据类型、el挂点、指令等
  • 原文地址:https://www.cnblogs.com/zyc-undefined/p/3311084.html
Copyright © 2011-2022 走看看