js实现深度克隆函数clone()

今天聊一下clone这个前端面试高频问题,由此引出typeof、instanceof、Object.prototype.toString这些javascript Api。js对象之间的赋值,如果直接用"="会发现来两个对象还是同一个对象,改变其中一个另外的一个也会做出对应的改变。

建议先学一下js 数据类型判断   ->   参考https://blog.csdn.net/qq_37548296/article/details/105440198

=======================

  • typeof可以识别出基本数据类型,但是不能识别null,Array,都把它统一归为object类型
  • instanceof不能识别出基本的数据类型 number、boolean、string、undefined、unll、Symbol,但是可以识别出Array、Object、Function,同时对于是使用new声明的类型,它还可以检测出多层继承关系。

说了typeof和instenceof其实就是想说这两个对于深度clone的实现来说不够严谨要不就是多层判断。

=================

接下来我们就用Object.prototype.toString.call()来解答一下面试题

// 我们可以创建一个函数来克隆所有对象:
function clone(obj, o) {
    //Object.prototype.toString.call(obj)返回类似[Object Array] 利用slice来截取我们需要的字符串
    let type = Object.prototype.toString.call(obj).slice(8, -1) //slice方法创建新的数组
    // 如果是Object
    if (type === 'Object') {
      o = {}
      for (let k in obj) {
        o[k] = clone(obj[k]);
      }
      // 如果是对象
    } else if (type === 'Array') { // 直接使用 = 赋值,只是指向相同的引用,如果原数组变化,克隆的数组也会跟着变化
      o = []
      for (let i = 0; i < obj.length; i++) {
        o.push(clone(obj[i]));
      }
    } else {
      // 非引用类型
      o = obj
    }
    return o // 在Javascript里,如果克隆对象是基本类型,我们直接赋值就可以了
             // 把一个值赋给另一个变量时,当那个变量的值改变的时候,另一个值不会受到影响。
  }

  let obj1 = {
    a: [1, 2, 3, 4, 5, 6],
    b: {
      c: 2
    },
    d: 1,
    f: function () {
      return 1
    }
  }
  let obj2 = clone(obj1)
  obj2.f = function () {
    return 2
  }
  obj2.a = 1
  console.log(obj1)
  console.log(obj2)

js实现深度克隆函数clone()_第1张图片

===============================

节点克隆: 

var p = document.getElementsByTagName("p")[0];
var cP = p.cloneNode();//克隆p节点
var cP = p.cloneNode(true);//克隆p节点,深度克隆,克隆节点以及节点下面的子内容。

 

你可能感兴趣的:(JavaScript)