MST

星途 面试题库

面试题:JavaScript 复杂赋值场景下的陷阱分析

假设有一个对象嵌套数组的复杂数据结构 obj = { arr: [[1, 2], { key: 'value' }] },在对其中的部分数据进行赋值操作时可能会遇到哪些陷阱?请详细分析并写出避免陷阱的代码实现。
49.6万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

可能遇到的陷阱

  1. 浅拷贝问题:当直接使用赋值操作符 = 对包含嵌套数组和对象的结构进行赋值时,可能会出现浅拷贝。例如,若想复制 obj.arr 中的子数组 [1, 2],简单的 newArr = obj.arr[0] 只是创建了一个指向原数组的引用,对 newArr 的修改会影响到 obj.arr[0]
  2. 对象引用问题:对于 obj.arr 中的对象 { key: 'value' },同样存在引用问题。如果赋值时没有进行深拷贝,对新对象的修改会反映到原对象上。

避免陷阱的代码实现

  1. 使用 JSON.parse(JSON.stringify()) 进行深拷贝(局限性:不能处理函数、正则等特殊对象)
const obj = { arr: [[1, 2], { key: 'value' }] };
// 深拷贝整个obj
const newObj = JSON.parse(JSON.stringify(obj));
// 修改新对象不会影响原对象
newObj.arr[0][0] = 10;
newObj.arr[1].key = 'newValue';
console.log(obj);
console.log(newObj);
  1. 使用 lodash 库的 cloneDeep 方法
const _ = require('lodash');
const obj = { arr: [[1, 2], { key: 'value' }] };
// 深拷贝整个obj
const newObj = _.cloneDeep(obj);
// 修改新对象不会影响原对象
newObj.arr[0][0] = 10;
newObj.arr[1].key = 'newValue';
console.log(obj);
console.log(newObj);
  1. 手动实现深拷贝函数(较复杂,可处理部分特殊对象)
function deepClone(obj) {
    if (typeof obj!== 'object' || obj === null) {
        return obj;
    }
    let cloneObj;
    if (Array.isArray(obj)) {
        cloneObj = [];
        for (let i = 0; i < obj.length; i++) {
            cloneObj[i] = deepClone(obj[i]);
        }
    } else {
        cloneObj = {};
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                cloneObj[key] = deepClone(obj[key]);
            }
        }
    }
    return cloneObj;
}

const obj = { arr: [[1, 2], { key: 'value' }] };
// 深拷贝整个obj
const newObj = deepClone(obj);
// 修改新对象不会影响原对象
newObj.arr[0][0] = 10;
newObj.arr[1].key = 'newValue';
console.log(obj);
console.log(newObj);