HomeLập trìnhJavaScriptTính bất biến...

Tính bất biến của JavaScript – Các đối tượng bị đóng băng trong JS được giải thích bằng các ví dụ


Trong JavaScript, chúng tôi sử dụng một Object để lưu trữ nhiều giá trị dưới dạng cấu trúc dữ liệu phức tạp. Bạn tạo một đối tượng với một cặp dấu ngoặc nhọn {}.

Một đối tượng có thể có một hoặc nhiều thuộc tính. Mỗi thuộc tính là một cặp khóa-giá trị được phân tách bằng dấu colon(:). Khóa phải là một loại ký hiệu chuỗi hoặc JavaScript. Giá trị có thể thuộc bất kỳ loại nào, kể cả đối tượng khác.

Với lời giải thích về một đối tượng, hãy tạo một đối tượng để xem nó hoạt động như thế nào:

const user = {
 'name': 'Bob',
 'age': 27   
}

Ở đây chúng ta đã tạo một đối tượng với hai thuộc tính (tên, tuổi) và các giá trị tương ứng của chúng. Chúng tôi đã tạo một biến gọi là user với const từ khóa và chúng tôi đã gán đối tượng cho nó làm giá trị.

Theo mặc định, các đối tượng được mutable. Điều này có nghĩa là sau khi chúng được tạo, bạn có thể thêm thuộc tính mới cho chúng, sửa đổi giá trị của thuộc tính hiện có hoặc xóa thuộc tính.

Trong những năm đầu lập trình, tôi đã tìm thấy các thuật ngữ mutableimmutable rất bối rối. Hãy để tôi thử giải thích nó bằng tiếng Anh đơn giản.

Mutable là thứ bạn có thể thay đổi. Immutable chỉ ngược lại với điều đó. Cho nên, mutability là khả năng thay đổi theo thời gian. Immutability có nghĩa là một cái gì đó không thay đổi theo thời gian.

Có thể có những tình huống mà bạn không muốn một đối tượng thay đổi theo chương trình. Vì vậy, bạn sẽ muốn làm cho nó không thay đổi.

Khi một đối tượng là bất biến, bạn không thể thêm một thuộc tính mới vào nó, sửa đổi nó hoặc xóa một thuộc tính hiện có. Thậm chí không có cách nào để mở rộng nó.

Đây là những gì một Frozen Object mà chúng ta sẽ tìm hiểu, thực hành và hiểu trong bài viết này.

Gần đây, tôi đã thảo luận về các vật thể bị đóng băng trong một chuỗi Twitter. Xin vui lòng có một cái nhìn. Bài viết này sẽ mở rộng về chủ đề với nhiều chi tiết và ví dụ hơn.

Bạn có thể đóng băng (làm cho bất biến) một đối tượng bằng chức năng Object.freeze(obj). Đối tượng được chuyển đến freeze phương pháp sẽ trở thành bất biến. Các freeze() phương thức cũng trả về cùng một đối tượng.

Đọc thêm  Tres forms de factorizar un numero en JavaScript

Hãy tạo một đối tượng gồm các ngôn ngữ được hỗ trợ:

const supportedLanguages = {
  'af': 'Afrikaans',
  'bn': 'Bengali',
  'de': 'German',
  'en': 'English',
  'fr': 'French'
}

Nếu bạn không muốn đối tượng này thay đổi sau khi nó được tạo, chỉ cần sử dụng freeze phương pháp để làm cho nó bất biến.

const frozenSupportedLanguages = Object.freeze(supportedLanguages);

// The supportedLanguages and frozenSupportedLanguages are same

frozenSupportedLanguages === supportedLanguages; // returns true

Bây giờ, hãy thử thay đổi một trong hai đối tượng và xem điều gì sẽ xảy ra:

// Add a new property
supportedLanguages['kn'] = 'Kannada';

// Modify an existing property
supportedLanguages["af"] = 'something else';

// Delete a property
delete supportedLanguages.bn; // returns false

// log the object to the console
console.log(supportedLanguages); // Unchanged => {af: "Afrikaans", bn: "Bengali", en: "English", fr: "French"}

Bạn sẽ gặp lỗi khi thử thay đổi một đối tượng cố định (đối tượng bất biến) trong JavaScript strict môi trường.

À, không hẳn. Các const từ khóa và Object.freeze() không phải là những điều tương tự. Khi bạn gán một đối tượng cho một biến được tạo bằng từ khóa const, bạn không thể gán lại giá trị khác. Tuy nhiên, bạn có thể sửa đổi các đối tượng được gán theo bất kỳ cách nào bạn muốn.

Hãy hiểu sự khác biệt với một ví dụ. Lần này, chúng ta sẽ làm như vậy supportedLanguages đối tượng nhưng sẽ không đóng băng nó.

const supportedLanguages = {
  'af': 'Afrikaans',
  'bn': 'Bengali',
  'de': 'German',
  'en': 'English',
  'fr': 'French'
}

Bây giờ bạn có thể sửa đổi nó như thế này:

// Add a new property
supportedLanguages['kn'] = 'Kannada';

// Modify an existing property
supportedLanguages["af"] = 'something else';

// Delete a property
delete supportedLanguages.bn; // returns true

// log the object to the console
console.log(supportedLanguages);

Bây giờ supportedLanguages đối tượng được thay đổi như sau:

hình ảnh-78

Vì vậy, thay đổi này được cho phép. Nhưng nếu bạn cố gán một đối tượng mới cho supportedLanguages Biến đổi:

supportedLanguages = {'id': 'Indonesian'};

Bạn sẽ nhận được lỗi này:

hình ảnh-79

Tôi hy vọng sự khác biệt đã rõ ràng – đó cũng là một câu hỏi phỏng vấn thường gặp.

Một lần nữa, chúng ta cần các đối tượng đóng băng khi chúng ta cần tính bất biến. Trong lập trình hướng đối tượng, thường có các API mà chúng ta không thể mở rộng hoặc sửa đổi bên ngoài ngữ cảnh hiện tại.

bạn có nhớ final từ khóa trong Java? Hoặc làm thế nào trong ngôn ngữ lập trình Kotlin, danh sách là bất biến theo mặc định? Cố gắng thay đổi chúng trong thời gian chạy sẽ gây ra lỗi. Tính bất biến là một khái niệm cần thiết để sử dụng trong lập trình chức năng.

Tính bất biến cũng thường quan trọng trong ngôn ngữ lập trình JavaScript. Bạn có thể muốn một đối tượng cấu hình là bất biến, một bộ ngôn ngữ được hỗ trợ cố định cho các ứng dụng của bạn hoặc bất kỳ thứ gì khác mà bạn không muốn thay đổi trong thời gian chạy.

Đọc thêm  JavaScript viết hoa chữ cái đầu tiên – Cách viết hoa chữ cái đầu tiên trong một từ bằng JS

Trong JavaScript, Arrays là những đối tượng dưới mui xe. Vì vậy, bạn cũng có thể áp dụng Object.freeze()vào mảng để làm cho chúng không thay đổi.

Hãy lấy một loạt các giác quan của con người:

const senses = ['touch', 'sight', 'hearing', 'smell', 'taste'];

Bây giờ chúng ta có thể làm cho nó trở nên bất biến như thế này:

Object.freeze(senses);

Bây giờ, hãy thử đẩy một phần tử vào mảng đó. Điều đó là không thể.

senses.push('walking');

Đầu ra sẽ là lỗi sau:

hinh-80

Cố gắng xóa một phần tử khỏi mảng:

senses.pop();

Bạn sẽ gặp lỗi này:

hinh-81

Vui lòng nhận thấy lỗi trong cả hai trường hợp. Nó nói rõ ràng, thuộc tính thêm và xóa không được phép vì đối tượng cơ bản không thể mở rộng.

Một thuộc tính đối tượng JavaScript có thể có một đối tượng khác làm giá trị của nó. Nó có thể đi đến một mức độ sâu hơn xuống.

Khi chúng ta đóng băng một đối tượng, nó là một shallow Đông cứng. Điều này có nghĩa là chỉ các thuộc tính cấp cao nhất bị đóng băng. Nếu bất kỳ giá trị nào của thuộc tính là một đối tượng khác, thì đối tượng bên trong đó sẽ không bị đóng băng. Bạn vẫn có thể thay đổi nó.

Hãy hiểu điều này với ví dụ về một đối tượng cấu hình:

const config = {
  'db': 'postgresql',
  'host': 'acme-ind.com',
  'password': 'fake-password',
  'port': 512,
  'admin': {
    'name': 'Tapas',
    'rights': ['create', 'update', 'delete']
  }
}

Đối tượng cấu hình có các thuộc tính như db, máy chủ, mật khẩu và cổng với các giá trị kiểu chuỗi đơn giản. Tuy nhiên, thuộc tính quản trị viên có một đối tượng làm giá trị. Bây giờ, hãy đóng băng đối tượng cấu hình.

Object.freeze(config);

Bây giờ, hãy thử thay đổi tên db.

config.db = 'redis';

Nó không được phép vì đối tượng bị đóng băng. Tuy nhiên, bạn có thể làm điều này:

config.admin.name="atapas";

Ở đây chúng tôi đã thay đổi thuộc tính của đối tượng lồng nhau. Vì đối tượng đóng băng có bản chất nông, nó sẽ không ngăn chúng ta thay đổi đối tượng lồng nhau. Vì vậy, nếu bạn đăng nhập đối tượng trong bảng điều khiển, đây là những gì bạn sẽ nhận được:

hinh-82

Nhưng làm cách nào để đóng băng sâu một đối tượng nếu bạn cần hoặc muốn? Bạn có thể muốn đóng băng tất cả các thuộc tính của đối tượng ở mức sâu nhất có thể đúng không? Chúng ta có thể làm điều đó bằng cách sử dụng đệ quy.

Đọc thêm  Các khái niệm JavaScript bạn nên biết trước khi học React

Trong lập trình, đệ quy là một phương pháp sử dụng một thủ tục, hàm hoặc thuật toán để gọi chính nó. Kiểm tra bài viết này để hiểu sâu hơn.

Vì vậy, chúng ta có thể lặp qua mọi thuộc tính và áp dụng đệ quy phương thức đóng băng cho mọi thứ. Nó sẽ đảm bảo rằng các đối tượng lồng nhau cũng bị đóng băng.

Để làm điều đó, bạn có thể viết một hàm đơn giản như sau:

const deepFreeze = obj => {
  Object.keys(obj).forEach(prop => {
    if (typeof obj[prop] === 'object') deepFreeze(obj[prop]);
  });
  return Object.freeze(obj);
};

deepFreeze(config);

Với Object.freeze, chúng tôi đạt được tính bất biến hoàn toàn. Nhưng có hai phương pháp khác cung cấp tính bất biến của đối tượng, chỉ một phần.

  • Object.seal – Chúng ta không thể thêm thuộc tính mới hoặc xóa thuộc tính hiện có của một đối tượng được niêm phong bằng phương thức này. Nhưng chúng ta vẫn có thể cập nhật giá trị của các thuộc tính hiện có.
  • Object.preventExtensions – Phương pháp này ngăn việc tạo thuộc tính mới. Nhưng bạn có thể cập nhật và xóa các thuộc tính hiện có.

Đây là một bảng để so sánh chúng:

Tạo ra Đọc Cập nhật Xóa bỏ
Đông cứng ✔️
niêm phong ✔️ ✔️
ngăn chặnTiện ích mở rộng ✔️ ✔️ ✔️

Không có cách đơn giản nào để giải phóng một đối tượng bị đóng băng trong JavaScript.

Bạn có thể mô phỏng quá trình giải phóng bằng cách tạo một bản sao của đối tượng duy trì nguyên mẫu.

Đây là gói NPM thực hiện tương tự với bản sao nông.

Để tóm tắt,

  • Chúng ta có thể đóng băng một đối tượng để làm cho nó trở nên bất biến.
  • Bạn sử dụng phương pháp Object.freeze để đóng băng một đối tượng.
  • Bạn không thể tạo thuộc tính mới, sửa đổi hoặc xóa thuộc tính hiện có hoặc mở rộng đối tượng khi áp dụng đóng băng.
  • Khai báo một biến với const từ khóa có giá trị đối tượng không giống như đóng băng đối tượng.
  • Bạn có thể đóng băng một mảng bằng cách sử dụng cùng một freeze phương pháp.
  • Phương pháp đóng băng thực hiện đóng băng nông. Sử dụng đệ quy để đóng băng sâu.
  • Các seal()preventExtentions() các phương pháp cung cấp tính bất biến một phần.
  • Unfreezing không được hỗ trợ trong ngôn ngữ (chưa).

Đó là tất cả cho bây giờ. Tôi hy vọng bạn đã tìm thấy bài viết này sâu sắc và nó giúp bạn hiểu rõ hơn về tính bất biến của đối tượng.

Kết nối nào. Bạn sẽ thấy tôi hoạt động trên Twitter (@tapasadhikary). Hãy theo dõi. Tôi cũng đã bắt đầu chia sẻ kiến ​​thức bằng kênh YouTube của mình nên bạn cũng có thể xem qua.

Bạn cũng có thể thích những bài viết này:





Zik.vn – Biên dịch & Biên soạn Lại

spot_img

Create a website from scratch

Just drag and drop elements in a page to get started with Newspaper Theme.

Buy Now ⟶

Bài viết liên quang

DMCA.com Protection Status