Rumah > hujung hadapan web > tutorial js > Kod Bersih: Ketidakbolehubah JavaScript, konsep teras dan alatan

Kod Bersih: Ketidakbolehubah JavaScript, konsep teras dan alatan

Susan Sarandon
Lepaskan: 2025-01-17 20:33:15
asal
526 orang telah melayarinya

Clean Code: JavaScript immutability, core concepts and tools

Apakah mutasi?

Mutasi merujuk kepada mengubah suai secara langsung nilai sedia ada. Dalam JavaScript, objek dan tatasusunan boleh ditukar (dimutasi) secara lalai:

<code class="language-javascript">// 变异示例
const user = { name: 'Alice' };
user.name = 'Bob';           // 变异对象属性

const numbers = [1, 2, 3];
numbers.push(4);             // 变异数组
numbers[0] = 0;              // 变异数组元素</code>
Salin selepas log masuk

Mutasi ini boleh mencipta pepijat yang sukar ditemui, terutamanya dalam aplikasi besar.

Mengapa mutasi harus dielakkan?

Mari kita lihat contoh mudah:

<code class="language-javascript">// 使用变异的代码
const cart = {
  items: [],
  total: 0
};

function addProduct(cart, product) {
  cart.items.push(product);
  cart.total += product.price;
}

// 使用示例
const myCart = cart;
addProduct(myCart, { id: 1, name: "Laptop", price: 999 });
// 直接更改 myCart
console.log(cart === myCart); // true,两个变量指向同一个对象</code>
Salin selepas log masuk

Masalah mutasi:

  1. Rujukan dikongsi: Bahagian kod yang berbeza boleh menukar objek yang sama tanpa mengetahui bahagian lain.
  2. Kesan sampingan: Perubahan akan menjejaskan fungsi lain yang menggunakan objek yang sama.
  3. Sukar untuk nyahpepijat: Tidak dapat mengesan bahagian kod yang telah menukar objek.
  4. Ujian kompleks: Mutasi menjadikan ujian unit lebih sukar untuk ditulis.

Penyelesaian: Pengaturcaraan Ketidakbolehubah

Kaedah kebolehubahan mencipta salinan baharu objek untuk setiap perubahan:

<code class="language-javascript">// 不变性代码
function addProduct(cart, product) {
  // 创建一个新对象,而不更改原始对象
  return {
    items: [...cart.items, product],
    total: cart.total + product.price
  };
}

// 使用示例
const initialCart = { items: [], total: 0 };
const newCart = addProduct(initialCart, { id: 1, name: "Laptop", price: 999 });

console.log(initialCart); // { items: [], total: 0 }
console.log(newCart);     // { items: [{...}], total: 999 }
console.log(initialCart === newCart); // false,它们是不同的对象</code>
Salin selepas log masuk

Faedah pendekatan ini:

  1. Kebolehramalan: setiap fungsi mengembalikan keadaan baharu, tiada kesan sampingan tersembunyi.
  2. Penjejakan Perubahan: Setiap perubahan mencipta objek baharu yang boleh dijejaki.
  3. Mudah untuk diuji: Fungsi adalah fungsi tulen dan lebih mudah untuk diuji.
  4. Penyahpepijatan yang lebih baik: boleh membandingkan status sebelum dan selepas perubahan.

Alat Kebolehubahan Moden

Immer: Gaya penulisan ringkas

Immer membolehkan anda menulis kod yang kelihatan seperti kod JavaScript biasa, tetapi menghasilkan hasil yang tidak berubah:

<code class="language-javascript">import produce from 'immer';

const initialCart = {
  items: [],
  total: 0,
  customer: {
    name: 'Alice',
    preferences: {
      notifications: true
    }
  }
};

// 不使用 Immer(冗长的方法)
const updatedCart = {
  ...initialCart,
  items: [...initialCart.items, { id: 1, name: "Laptop", price: 999 }],
  total: initialCart.total + 999,
  customer: {
    ...initialCart.customer,
    preferences: {
      ...initialCart.customer.preferences,
      notifications: false
    }
  }
};

// 使用 Immer(简单的方法)
const updatedCartImmer = produce(initialCart, draft => {
  draft.items.push({ id: 1, name: "Laptop", price: 999 });
  draft.total += 999;
  draft.customer.preferences.notifications = false;
});</code>
Salin selepas log masuk

Kebaikan Immer:

  • Sintaks biasa: Tulis kod seperti biasa.
  • Tiada API baharu untuk dipelajari: gunakan objek dan tatasusunan JavaScript biasa.
  • Pantas: Salin bahagian yang ditukar sahaja.
  • Pengesanan perubahan automatik: Jejaki perubahan dan buat rujukan baharu hanya apabila diperlukan.
  • Berfungsi dengan baik dengan TypeScript: semua jenis maklumat disimpan.

Immutable.js: struktur data yang cekap

Immutable.js menyediakan struktur data yang direka bentuk untuk kebolehubah:

<code class="language-javascript">import { Map, List } from 'immutable';

// 创建不变的数据结构
const cartState = Map({
  items: List([]),
  total: 0
});

// 添加一个项目
const newCart = cartState
  .updateIn(
    ['items'],
    items => items.push(Map({
      id: 1,
      name: "Laptop",
      price: 999
    }))
  )
  .update('total', total => total + 999);

// Immutable.js 方法始终返回新实例
console.log(cartState.getIn(['items']).size); // 0
console.log(newCart.getIn(['items']).size);   // 1

// 轻松比较
console.log(cartState.equals(newCart)); // false

// 转换回常规 JavaScript
const cartJS = newCart.toJS();</code>
Salin selepas log masuk

Faedah Immutable.js:

  • Menggunakan struktur data tidak berubah adalah pantas.
  • API Kaya untuk bekerja dengan data.
  • Perkongsian data yang cekap memori.
  • Gunakan equals() untuk memudahkan semakan kesaksamaan.
  • Elakkan perubahan yang tidak disengajakan.

Konfigurasi ESLint yang tidak berubah

ESLint boleh membantu menguatkuasakan amalan pengekodan tidak berubah melalui peraturan tertentu:

<code class="language-javascript">// .eslintrc.js
module.exports = {
  plugins: ['functional'],
  rules: {
    'functional/immutable-data': 'error',
    'functional/no-let': 'error',
    'functional/prefer-readonly-type': 'error'
  }
};</code>
Salin selepas log masuk

Peraturan ini akan:

  • Halang mutasi data langsung.
  • Galakkan penggunaan const dan bukannya let.
  • Adalah disyorkan untuk menggunakan jenis baca sahaja dalam TypeScript.

Skrip Jenis dan kebolehubahan

TypeScript membantu menguatkuasakan kebolehubahan melalui sistem jenisnya:

<code class="language-typescript">// 购物车的不变类型
type Product = {
  readonly id: number;
  readonly name: string;
  readonly price: number;
};

type Cart = {
  readonly items: ReadonlyArray<Product>;
  readonly total: number;
};

// TypeScript 防止变异
const cart: Cart = {
  items: [],
  total: 0
};

// 编译错误:items 是只读的
cart.items.push({ id: 1, name: "Laptop", price: 999 });

// 函数必须创建一个新的购物车
function addProduct(cart: Cart, product: Product): Cart {
  return {
    items: [...cart.items, product],
    total: cart.total + product.price
  };
}

// TypeScript 确保原始对象不会更改
const newCart = addProduct(cart, { id: 1, name: "Laptop", price: 999 });</code>
Salin selepas log masuk

Pengubah suai baca sahaja untuk TypeScript:

  • baca sahaja: Halang perubahan atribut.
  • ReadonlyArray: Halang perubahan tatasusunan.
  • Baca sahaja: Menjadikan semua sifat baca sahaja.

Jenis ini disemak pada masa penyusunan, membantu mengesan ralat lebih awal.

Kesimpulan

Ketidakbolehubahan menjadikan kod anda lebih mudah diramal dan diselenggara. Walaupun memerlukan sedikit masa untuk membiasakan diri, kelebihan dalam kebolehpercayaan dan kebolehselenggaraan adalah berbaloi.

Atas ialah kandungan terperinci Kod Bersih: Ketidakbolehubah JavaScript, konsep teras dan alatan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan