美文网首页
23.js中深拷贝的实现

23.js中深拷贝的实现

作者: jqClub | 来源:发表于2018-04-30 09:03 被阅读0次

1.javaScript的变量类型
(1)基本类型:
5种基本数据类型Undefined、Null、Boolean、Number 和 String,变量是直接按值存放的,存放在栈内存中的简单数据段,可以直接访问。

(2)引用类型:
存放在堆内存中的对象,变量保存的是一个指针,这个指针指向另一个位置。当需要访问引用类型(如对象,数组等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。

2.深拷贝的实现
2.1、Array的slice和concat方法(实际上是浅拷贝)

var array = [1,2,3]; 
var array_concat = array.concat(); 
var array_slice = array.slice(0); 

//缺点:数组中的对象元素(Object,Array等)只是复制了引用
var array = [1, [1,2,3], {name:"array"}]; 
var array_concat = array.concat();

2.2、JSON对象的parse和stringify

var source = { name:"source", child:{ name:"child" } } 
var target = JSON.parse(JSON.stringify(source));
//缺点:对于正则表达式类型、函数类型等无法进行深拷贝(而且会直接丢失相应的值)。并且会抛弃对象的constructor

2.3、简易版本1

var deepCopy = function(obj) {
    if (typeof obj !== 'object') return;
    var newObj = obj instanceof Array ? [] : {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
        }
    }
    return newObj;
}

2.4、简易版本2

function deepClone (obj) {
  if (Array.isArray(obj)) {
    return obj.map(deepClone)
  } else if (obj && typeof obj === 'object') {
    var cloned = {}
    var keys = Object.keys(obj)
    for (var i = 0, l = keys.length; i < l; i++) {
      var key = keys[i]
      cloned[key] = deepClone(obj[key])
    }
    return cloned
  } else {
    return obj
  }
}

2.5、另一种实现

(function ($) {
    'use strict';

    var types = 'Array Object String Date RegExp Function Boolean Number Null Undefined'.split(' ');

    function type () {
       return Object.prototype.toString.call(this).slice(8, -1);
    }

    for (var i = types.length; i--;) {
        $['is' + types[i]] = (function (self) {
            return function (elem) {
               return type.call(elem) === self;
            };
        })(types[i]);
    }

    return $;
})(window.$ || (window.$ = {}));//类型判断

function copy (obj,deep) { 
    if ($.isFunction(obj)) {
        return new Function("return " + obj.toString())();
    } else if (obj === null || (typeof obj !== "object")) { 
        return obj; 
    } else {
        var name, target = $.isArray(obj) ? [] : {}, value; 

        for (name in obj) { 
            value = obj[name]; 

            if (value === obj) {
                continue;
            }

            if (deep) {
                if ($.isArray(value) || $.isObject(value)) {
                    target[name] = copy(value,deep);
                } else if ($.isFunction(value)) {
                    target[name] = new Function("return " + value.toString())();
                } else {
                    target[name] = value;
                } 
            } else {
                target[name] = value;
            } 
        } 
        return target;
    }         
}

2.6、第三方库的实现

jQuery —— $.clone() / $.extend()
Underscore —— _.clone()
lodash —— _.clone() / _.cloneDeep()

参考:
1.JavaScript专题之深浅拷贝
2.javaScript中浅拷贝和深拷贝的实现
3.深入剖析 JavaScript 的深复制

相关文章

  • 23.js中深拷贝的实现

    1.javaScript的变量类型(1)基本类型:5种基本数据类型Undefined、Null、Boolean、N...

  • Javascript中的深拷贝

    JS 中深拷贝的几种实现方法 1、使用递归的方式实现深拷贝 //使用递归的方式实现数组、对象的深拷贝 functi...

  • JS 中深拷贝的几种实现方法

    JS 中深拷贝的几种实现方法 1、使用递归的方式实现深拷贝 方法二 2、通过 JSON 对象实现深拷贝 缺点 (1...

  • iOS基础知识点(网络摘抄)

    1.父类实现深拷贝时,子类如何实现深拷贝。父类没有实现深拷贝时,子类如何实现深拷贝? 深拷贝同浅拷贝的区别:...

  • 深拷贝、浅拷贝

    父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。 深拷贝同浅拷贝的区别:浅拷贝...

  • 面试题整理

    父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。 深拷贝同浅拷贝的区别:浅拷贝...

  • iOS面试基础一

    #父类实现深拷贝时,子类如何实现深度拷贝.父类没有实现深拷贝时,子类如何实现深度拷贝.# <(1)深拷贝同浅拷贝的...

  • 手写深拷贝

    手写深拷贝 深拷贝 深拷贝简单理解就是b是a的一份拷贝,且b中不存在a中对象的引用 深拷贝的实现 1.JSON序列...

  • iOS知识点(一)

    1.1 父类实现深拷贝时,子类如何实现深度拷贝。 父类没有实现深拷贝时,子类如何实现深度拷贝。深拷贝同浅拷贝的区别...

  • 面试 (一) : 基础篇

    父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。• 深拷贝同浅拷贝的区别:浅拷...

网友评论

      本文标题:23.js中深拷贝的实现

      本文链接:https://www.haomeiwen.com/subject/zxlzlftx.html