> 文档中心 > 【前端面试宝典】js浅拷贝深拷贝

【前端面试宝典】js浅拷贝深拷贝

写在前面

CSDN话题挑战赛第1期

  • 活动详情地址:CSDN

  • 参赛话题:前端面试宝典

  • 话题描述:欢迎各位加入话题创作得小伙伴,如果我没有猜错得话,我觉得你是应该同我一样是一位前端人。如今前端在IT事业中的占比越来越重,已经成为不可缺少的部分,前端技术也是层出不穷,各种技术类、技术框架也蜂拥而出,前端面试的难度也随之增加,如果我们拥有一套前端面试宝典。如果你是应聘者:你就可以从容的solo面试官,如果你是面试官:你就可以将应聘者拷问到骨子里!
    总之我们大家一起将自己的面试经验以及学习到的知识点汇聚于此,形成一套体系的前端面试宝典。让读者无论是面试还是学习都能够有非常大的收获。就让我们携手共筑前端面试宝典吧!!!

携手共筑前端面试宝典

  • 目录

    题目一

    考点

    答案


题目一

JavaScript深浅拷贝的理解

考点

深浅拷贝的理解

答案

浅拷贝

    // ----------------------------------------------浅拷贝    // 只是把对象的属性和属性值拷贝到另一个对象中    var obj1 = {      a: { a1: { a2: 1 }, a10: { a11: 123, a111: { a1111: 123123 } }      },      b: 123,      c: "123"    }    // 方式1    function shallowClone1(o) {      let obj = {}      for (let i in o) { obj[i] = o[i]      }      return obj    }let shallowObj = shallowClone1(obj1);console.log(shallowObj);    // 方式2    var shallowObj2 = { ...obj1 }console.log(shallowObj2)    // 方式3    var shallowObj3 = Object.assign({}, obj1)    obj1.a.a1 = 999    obj1.b = true;    console.log(obj1);  //第一层的没有被改变,一层以下就被改变了

深拷贝 

// ----------------------------------------------深拷贝    // 简易版      function deepClone(o) {      let obj = {}      for (var i in o) { // if(o.hasOwnProperty(i)){ if (typeof o[i] === "object") {   obj[i] = deepClone(o[i]) } else {   obj[i] = o[i] } // }      }      return obj    }    var myObj = {      a: { a1: { a2: 1 }, a10: { a11: 123, a111: { a1111: 123123 } }      },      b: 123,      c: "123"    }    var deepObj1 = deepClone(myObj)    deepObj1.a.a1 = 999    deepObj1.b = false    console.log(myObj);    // 简易版存在的问题:参数没有做检验,传入的可能是 Array、null、regExp、Date    function deepClone2(o) {      if (Object.prototype.toString.call(o) === "[object Object]") {  //检测是否为对象 let obj = {} for (var i in o) {   if (o.hasOwnProperty(i)) {     if (typeof o[i] === "object") {obj[i] = deepClone(o[i])     } else {obj[i] = o[i]     }   } } return obj      } else { return o      }    }    function isObject(o) {      return Object.prototype.toString.call(o) === "[object Object]" || Object.prototype.toString.call(o) === "[object Array]"    }    // 继续升级,没有考虑到数组,以及ES6中的map、set、weakset、weakmap    function deepClone3(o) {      if (isObject(o)) {//检测是否为对象或者数组 let obj = Array.isArray(o) ? [] : {} for (let i in o) {   if (isObject(o[i])) {     obj[i] = deepClone(o[i])   } else {     obj[i] = o[i]   } } return obj      } else { return o      }    }    // 有可能碰到循环引用问题  var a = {}; a.a = a; clone(a);//会造成一个死循环    // 循环检测    // 继续升级    function deepClone4(o, hash = new map()) {      if (!isObject(o)) return o//检测是否为对象或者数组      if (hash.has(o)) return hash.get(o)      let obj = Array.isArray(o) ? [] : {}      hash.set(o, obj)      for (let i in o) { if (isObject(o[i])) {   obj[i] = deepClone4(o[i], hash) } else {   obj[i] = o[i] }      }      return obj    }    // 递归易出现爆栈问题    //  将递归改为循环,就不会出现爆栈问题了    var a1 = { a: 1, b: 2, c: { c1: 3, c2: { c21: 4, c22: 5 } }, d: 'asd' };    var b1 = { b: { c: { d: 1 } } }    function cloneLoop(x) {      const root = {};      // 栈const loopList = [  //->[]->[{parent:{a:1,b:2},key:c,data:{ c1: 3, c2: { c21: 4, c22: 5 } }}] {   parent: root,   key: undefined,   data: x, }      ];      while (loopList.length) { // 深度优先 const node = loopList.pop(); const parent = node.parent; //{} //{a:1,b:2} const key = node.key; //undefined //c const data = node.data; //{ a: 1, b: 2, c: { c1: 3, c2: { c21: 4, c22: 5 } }, d: 'asd' }  //{ c1: 3, c2: { c21: 4, c22: 5 } }} // 初始化赋值目标,key 为 undefined 则拷贝到父元素,否则拷贝到子元素 let res = parent; //{}->{a:1,b:2,d:'asd'} //{a:1,b:2}->{} if (typeof key !== 'undefined') {   res = parent[key] = {}; } for (let k in data) {   if (data.hasOwnProperty(k)) {     if (typeof data[k] === 'object') {// 下一次循环 loopList.push({  parent: res,  key: k,  data: data[k],})     } else {res[k] = data[k];     }   } }      }      return root    }    function deepClone5(o) {      let result = {}      let loopList = [ {   parent: result,   key: undefined,   data: o }      ]      while (loopList.length) { let node = loopList.pop() let { parent, key, data } = node let anoPar = parent if (typeof key !== 'undefined') {   anoPar = parent[key] = {} } for (let i in data) {   if (typeof data[i] === 'object') {     loopList.push({parent: anoPar,key: i,data: data[i]     })   } else {     anoPar[i] = data[i]   } }      }      return result    }    let cloneA1 = deepClone5(a1)    cloneA1.c.c2.c22 = 5555555    console.log(a1);    console.log(cloneA1);    // ------------------------------------------JSON.stringify()实现深拷贝    function cloneJson(o) {      return JSON.parse(JSON.stringify(o))    }    // let obj = { a: { c: 1 }, b: {} };    // obj.b = obj;    // console.log(JSON.parse(JSON.stringify(obj))) // 报错 // Converting circular structure to JSON

写在最后

CSDN话题挑战赛第1期

  • 活动详情地址:CSDN