Hi FE !
Ai
git
前端面试题
前端小tip
  • vite
  • webpack
npm
  • vue2
  • vue3
react
GitHub
Ai
git
前端面试题
前端小tip
  • vite
  • webpack
npm
  • vue2
  • vue3
react
GitHub
  • s011-手写深拷贝★★

s011-手写深拷贝★★

深拷贝方法

1.JSON.stringify() 和 JSON.parse()

3.手写简易版deepClone

function deepClone(obj) {
	let newObj = obj.intanceof(Array) ? [] : {}
		for(let item in obj) {
			let template = typeof(obj[item]) == 'Object' ? deepClone(obj[item]) : obj[item]
			newObj.item = template
		}
	return newObj;
}

版本2

function deepClone(obj = {}) {
  if(typeof obj !== 'object' || obj == null) {
    return obj
  }
  let result = obj.intanceof(Array) ? [] : {}
  for(let key in obj) {
    //保证key 不是原型上的属性
    if(obj.hasOwnProperty(key)) {
      result[key] = deepClone(obj[key])
    }
  }
  return result;
}

项目中用的


// 深度克隆
export function deepClone(obj) {
  let isArr = Array.isArray(obj);
  let isJson = Object.prototype.toString.call(obj) === "[object Object]";
  if (isArr) {
    let newObj = [];
    for (let i = 0; i < obj.length; i++) {
      newObj[i] = deepClone(obj[i]);
    }
    return newObj;
  } else if (isJson) {
    let newObj = {};
    for (let i in obj) {
      newObj[i] = deepClone(obj[i]);
    }
    return newObj;
  }
  return obj;
}
function structuralClone(obj) {
  return new Notification('', {data: obj, silent: true}).data;
}

const obj = /* ... */;
const clone = structuralClone(obj);

深拷贝(考虑到复制 Symbol 类型)

function isObject(val) {
  return typeof val === "object" && val !== null;
}

function deepClone(obj, hash = new WeakMap()) {
  if (!isObject(obj)) return obj;
  if (hash.has(obj)) {
    return hash.get(obj);
  }
  let target = Array.isArray(obj) ? [] : {};
  hash.set(obj, target);
  Reflect.ownKeys(obj).forEach((item) => {
    if (isObject(obj[item])) {
      target[item] = deepClone(obj[item], hash);
    } else {
      target[item] = obj[item];
    }
  });

  return target;
}

深拷贝 structuredClone()

JavaScript 内置了一个 structuredClone() 的方法, 此方法提供了一种简单有效的方法来深度克隆对象, 且适用于大多数现代浏览器和 Node.js v17 以上

// 将原始对象传递给该函数, 它将返回一个具有不同引用和对象属性引用的深层副本

const obj = { name: 'Mike', friends: [{ name: 'Sam' }] };
const clonedObj = structuredClone(obj);

console.log(obj === clonedObj); // false
console.log(obj.friends === clonedObj.friends); // false

与众所周知的 JSON.parse(JSON.stringify())” 不同, structuredClone() 允许您克隆循环引用,这是目前在 JavaScript 中使用深拷贝最简单的方法。

兼容多种对象的神拷贝

function deepClone (target, hash = new WeakMap()) { // 额外开辟一个存储空间WeakMap来存储当前对象
  if (target === null) return target // 如果是 null 就不进行拷贝操作
  if (target instanceof Date) return new Date(target) // 处理日期
  if (target instanceof RegExp) return new RegExp(target) // 处理正则
  if (target instanceof HTMLElement) return target // 处理 DOM元素

  if (typeof target !== 'object') return target // 处理原始类型和函数 不需要深拷贝,直接返回

  // 是引用类型的话就要进行深拷贝
  if (hash.get(target)) return hash.get(target) // 当需要拷贝当前对象时,先去存储空间中找,如果有的话直接返回
  const cloneTarget = new target.constructor() // 创建一个新的克隆对象或克隆数组
  hash.set(target, cloneTarget) // 如果存储空间中没有就存进 hash 里

  Reflect.ownKeys(target).forEach(key => { // 引入 Reflect.ownKeys,处理 Symbol 作为键名的情况
    cloneTarget[key] = deepClone(target[key], hash) // 递归拷贝每一层
  })
  return cloneTarget // 返回克隆的对象
}

Edit this page
最近更新: 2025/6/27 02:24
Contributors: qdleader
qdleader
本站总访问量 129823次 | 本站访客数 12人