JavaScript 实现深拷贝

发布于 2021-12-10 12:44:45 字数 2883 浏览 1000 评论 0

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script>
    // 基础数据类型:null, undefined, number, string, boolean, symbol
    // 复合数据类型:object, array, function, date, regexp
    // 扩展:考虑key是否为symbol,考虑结构是否为ES6的新数据结构

    function is(model, value) { return Object.prototype.toString.call(value).slice(8,-1) === model; }
    function isDate(value) { return is('Date', value); }
    function isRegExp(value) { return is('RegExp', value); }
    function isFunction(value) { return is('Function', value); }

    var source = {
      null: null, 
      boolean: 1, 
      undefined: undefined, 
      string: 's',  

      date: new Date(),
      regexp: /\w+/ig,
      func: ()=>{},

      object: {deep:true}, 
      array: [1,2,3],
    };

    function deepCopy(value){
      let type = typeof value;

      // 非复合数据类型,直接返回值
      if(value === null || (type != 'object' && type !=' function')) {
        return value;
      } 
      else if(isDate(value)) {
        const result = new value.constructor(+value)
        return result;
      } 
      else if(isRegExp(value)) {
        const result = new value.constructor(value.source, /\w*$/.exec(value))
        result.lastIndex = value.lastIndex
        return result
      } 
      else if(isFunction(value)) {
        return Object.create(Object.getPrototypeOf(value))
      }

      // update: Object.keys会将symbol直接转化为字符串
      const isArr = Array.isArray(value);
      const props = isArr ? value : Object.keys(value);

      let result = isArr ? new Array(value.length) : new Object();

      props.forEach((prop,index) => {
        if(isArr){
          result[index] = deepCopy(prop)
        } else {
          result[prop] = deepCopy(value[prop]);
        }
      });
      return result;
    }

    var target = deepCopy(source);

    console.log('null compare:' + source.null === target.null);
    console.log('boolean compare:' + source.boolean === target.boolean);
    console.log('undefined compare:' + source.undefined === target.undefined);
    console.log('string compare:' + source.string === target.string);
    console.log('date compare:' + source.date === target.date);
    console.log('regexp compare:' + source.regexp === target.regexp);
    console.log('func compare:' + source.func === target.func);
    console.log('object compare:' + source.object === target.object);
    console.log('array compare:' + source.array === target.array);
    console.log(source);
    console.log(target);

  </script>
</body>
</html>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

本宫微胖

暂无简介

0 文章
0 评论
559 人气
更多

推荐作者

爱人如己

文章 0 评论 0

萧瑟寒风

文章 0 评论 0

云雾

文章 0 评论 0

倒带

文章 0 评论 0

浮世清欢

文章 0 评论 0

撩起发的微风

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文