📜  浅克隆 (1)

📅  最后修改于: 2023-12-03 15:40:44.898000             🧑  作者: Mango

浅克隆 (Shallow Clone)

简介

浅克隆是指在对象或者数组被克隆时,只会创建一个新的对象或数组并复制其引用,而不是递归地复制所有子对象或子数组。浅克隆可以有效地节省内存,但可能会导致副作用。

例如,当你克隆一个包含其他对象的对象时,并对原对象或新对象进行修改时,另一个对象也会被修改,因为它们共享同一引用。

用途
1. 节省内存

使用浅克隆可以避免不必要的复制并节约内存,尤其是处理大型对象和数组时更为有效。

const obj = {
  name: "Tom",
  age: 18,
  hobbies: ["reading", "music"],
  scores: { math: 90, english: 85 }
};

// 浅克隆
const clonedObj = Object.assign({}, obj);

// 修改原对象属性
obj.name = "Jerry";

console.log(obj.name); // "Jerry"
console.log(clonedObj.name); // "Tom"

// 修改原对象数组属性
obj.hobbies.push("swimming");

console.log(obj.hobbies); // ["reading", "music", "swimming"]
console.log(clonedObj.hobbies); // ["reading", "music", "swimming"]

// 修改原对象子对象属性
obj.scores.math = 95;

console.log(obj.scores.math); // 95
console.log(clonedObj.scores.math); // 95
2. 处理可变数据

使用浅克隆可以更方便地处理具有可变性的数据,例如 Redux 中的状态管理。

const initialState = {
  todos: [
    { id: 1, text: "task 1", completed: false },
    { id: 2, text: "task 2", completed: true }
  ],
  visibilityFilter: "SHOW_ALL"
};

function reducer(state = initialState, action) {
  switch (action.type) {
    case "ADD_TODO":
      return {
        ...state,
        todos: [
          ...state.todos,
          { id: action.id, text: action.text, completed: false }
        ]
      };
    case "TOGGLE_TODO":
      return {
        ...state,
        todos: state.todos.map(todo =>
          todo.id === action.id ? { ...todo, completed: !todo.completed } : todo
        )
      };
    case "SET_VISIBILITY_FILTER":
      return {
        ...state,
        visibilityFilter: action.filter
      };
    default:
      return state;
  }
}

在上面的代码中,我们使用了浅克隆技术来创建新的状态对象。在每个 Reducer 中,我们都返回了一个新对象,而不是修改原始状态对象。这使得 React 组件可以检测到状态的更改,并且可以避免在处理状态更改时出现错误。

常见问题
1. 如何实现浅克隆?

JavaScript 中可以使用以下方法实现浅克隆:

  • Object.assign() 方法
  • Spread Operator(展开运算符)
  • Array.slice() 方法
// Object.assign() 方法
const clonedObj = Object.assign({}, obj);

// Spread Operator
const clonedObj = { ...obj };

// Array.slice() 方法
const clonedArr = arr.slice();
2. 如何实现深克隆?

如果需要完全复制对象或数组,并递归地复制所有子对象或子数组,则需要实现深克隆。通常可以使用 JSON 解析/序列化或第三方库来实现深克隆。

// JSON 解析/序列化
const clonedObj = JSON.parse(JSON.stringify(obj));

// Lodash 库
const _ = require("lodash");
const clonedObj = _.cloneDeep(obj);
总结

浅克隆是一种有效的内存节省技术,可以用于处理可变数据和状态管理。但是在复杂的情况下可能会出现副作用,因此需要注意。在需要完全复制对象或数组并递归地复制所有子对象或子数组时,建议使用深克隆技术。