一、使用 JSON.parseJSON.stringify

    1. JSON.parse(JSON.stringify(obj))

    缺点:

    • 循环引用会报错。
    • 性能较差。
    • 会忽略 undefined,Date,RegExp,Error 等特殊对象。

    二、使用递归

    实现:

    1. function isObj(obj) {
    2. return typeof obj === 'object'
    3. }
    4. function deepClone(obj, hash = new WeakMap()) {
    5. if (!isObj(obj) || obj === null || obj === undefined) return obj
    6. let cloneObj
    7. const Constructor = obj.constructor
    8. switch (Constructor) {
    9. case RegExp:
    10. cloneObj = new Constructor(obj)
    11. break
    12. case Date:
    13. cloneObj = new Constructor(obj.getTime())
    14. break
    15. case Array:
    16. cloneObj = []
    17. break
    18. default:
    19. if (hash.has(obj)) return hash.get(obj)
    20. cloneObj = new Constructor()
    21. hash.set(obj, cloneObj)
    22. }
    23. for (let key in obj) {
    24. if (typeof obj[key] == 'function') {
    25. cloneObj[key] = obj[key].bind(cloneObj)
    26. } else {
    27. cloneObj[key] = isObj(obj[key]) ? deepClone(obj[key], hash) : obj[key]
    28. }
    29. }
    30. return cloneObj
    31. }

    参考实现:https://github.com/wengjq/Blog/issues/3

    1. (function ($) {
    2. 'use strict';
    3. var types = 'Array Object String Date RegExp Function Boolean Number Null Undefined'.split(' ');
    4. function type () {
    5. return Object.prototype.toString.call(this).slice(8, -1);
    6. }
    7. for (var i = types.length; i--;) {
    8. $['is' + types[i]] = (function (self) {
    9. return function (elem) {
    10. return type.call(elem) === self;
    11. };
    12. })(types[i]);
    13. }
    14. return $;
    15. })(window.$ || (window.$ = {}));//类型判断
    16. function copy (obj,deep) {
    17. if ($.isFunction(obj)) {
    18. return new Function("return " + obj.toString())();
    19. } else if (obj === null || (typeof obj !== "object")) {
    20. return obj;
    21. } else {
    22. var name, target = $.isArray(obj) ? [] : {}, value;
    23. for (name in obj) {
    24. value = obj[name];
    25. if (value === obj) {
    26. continue;
    27. }
    28. if (deep) {
    29. if ($.isArray(value) || $.isObject(value)) {
    30. target[name] = copy(value,deep);
    31. } else if ($.isFunction(value)) {
    32. target[name] = new Function("return " + value.toString())();
    33. } else {
    34. target[name] = value;
    35. }
    36. } else {
    37. target[name] = value;
    38. }
    39. }
    40. return target;
    41. } 
    42. }