Skip to content

对象的拷贝 #24

Description

@hashdrinker
/**
 * 浅拷贝
 * Object.assign(target, ...sources) 也是浅拷贝
 */
function copy (from, to) {
  // 校验参数
  if (arguments.length > 2) {
    throw new Error('最多2个参数');
  }
  if (typeof from !== 'object' || from === null) {
    throw new Error('第一个参数类型错误');
  }
  if (arguments.length === 2) {
    if (typeof to !== 'object' || to === null) {
      throw new Error('第二个参数类型错误');
    }
    if (Array.isArray(from) !== Array.isArray(to)) {
      throw new Error('参数类型不匹配');
    }
  }
  // 开始拷贝
  const newTo = to || (Array.isArray(from) ? [] : {});
  for (const key in from) {
    if (from.hasOwnProperty(key)) {
      newTo[key] = from[key];
    }
  }
  return newTo;
}

/**
 * 深拷贝
 */
function deepCopy (from, to) {
  // 校验参数
  if (arguments.length > 2) {
    throw new Error('最多2个参数');
  }
  if (typeof from !== 'object' || from === null) {
    throw new Error('第一个参数类型错误');
  }
  if (arguments.length === 2) {
    if (typeof to !== 'object' || to === null) {
      throw new Error('第二个参数类型错误');
    }
    if (Array.isArray(from) !== Array.isArray(to)) {
      throw new Error('参数类型不匹配');
    }
  }
  // 开始拷贝
  const newTo = to || (Array.isArray(from) ? [] : {});
  for (const key in from) {
    if (from.hasOwnProperty(key)) {
      if (typeof from[key] === 'object') {
        newTo[key] = Array.isArray(from[key]) ? [] : {};
        deepCopy(from[key], newTo[key]);
      } else {
        newTo[key] = from[key];
      }
    }
  }
  return newTo;
}

// 测试
const from = {
  a: {
    b: 'b',
  }
}
const to = copy(from);
const deepTo = deepCopy(from);

console.log(to); // { a: { b: 'b' } }
console.log(deepTo); // { a: { b: 'b' } }
from.a.b = 'b2';
console.log(to); // { a: { b: 'b2' } }
console.log(deepTo); // { a: { b: 'b' } }

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions