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>
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>
Masalah mutasi:
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>
Faedah pendekatan ini:
Alat Kebolehubahan Moden
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>
Kebaikan Immer:
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>
Faedah Immutable.js:
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>
Peraturan ini akan:
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>
Pengubah suai baca sahaja untuk TypeScript:
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!