Các kiểu dữ liệu có thể thay đổi và không thể thay đổi trong JavaScript

Khái niệm về tính bất biến không có gì mới vì nó đã có từ rất lâu trong các ngôn ngữ lập trình hướng đối tượng và hàm. Ý tưởng này không phổ biến lắm trong JavaScript, nhưng nó đã dần dần phát triển trong cộng đồng lập trình gần đây. React là người ủng hộ mạnh mẽ việc giữ trạng thái không thay đổi và Facebook đã đóng góp một thư viện có tên là Immutable. js để giúp nguyên nhân này

Trong hướng dẫn này, chúng tôi sẽ trả lời các câu hỏi sau

  1. tính bất biến là gì?
  2. Tại sao và khi nào bạn nên giữ trạng thái của mình không thay đổi?
  3. Các vấn đề liên quan đến đột biến

Các kiểu dữ liệu có thể thay đổi và không thể thay đổi

Một đối tượng có thể thay đổi là một đối tượng có trạng thái có thể được sửa đổi hoặc thay đổi theo thời gian. Mặt khác, một đối tượng bất biến là một đối tượng mà trạng thái của nó không thể thay đổi được sau khi nó được tạo ra. Chà, đó là cách sách giáo khoa định nghĩa các đối tượng có thể thay đổi và không thể thay đổi

Trong JavaScript, chuỗi và số là những kiểu dữ liệu không thể thay đổi. Nếu cảm thấy lạ, đây là một ví dụ để chứng minh tại sao chúng ta gọi chúng là bất biến

Java

 





x



 

1

var x =7;

2

x += 1;




Ví dụ, các số là bất biến vì bạn không thể thay đổi giá trị của nó. Ví dụ: bạn không thể thay đổi giá trị của 7 thành 8 theo nghĩa đen. Điều đó không có ý nghĩa. Thay vào đó, bạn có thể thay đổi giá trị được lưu trong biến x từ 7 thành 8

Các chuỗi cũng không thể thay đổi và điều này là hiển nhiên khi bạn cố gắng thay đổi một ký tự cụ thể trong một chuỗi

Java

 





xxxxxxxxxx

1



 

1

var myString = "I am immutable"

2

myString[2] = 'c'

3

console.log(myString)




Nhưng điều đó không ngăn bạn tạo chuỗi mới

Java

 





xxxxxxxxxx

1



 

1

var myString = "I am immutable.";

2

________số 8_______




Các phương pháp thao tác chuỗi khác như

xxxxxxxxxx
3,
xxxxxxxxxx
4, v.v. cũng trả về một chuỗi mới. Không có thao tác chuỗi nào sửa đổi chuỗi mà chúng hoạt động trong JavaScript

Điều này là do các chuỗi và số là các loại giá trị nguyên thủy được gán theo giá trị chứ không phải theo tham chiếu. Đây là một cuộc thảo luận tốt về bản sao theo giá trị so với. sao chép bằng cách tham khảo cho người mới bắt đầu

Bạn cũng có thể thích. Bạn có thực sự cần dữ liệu bất biến?

Cân nhắc thực tế

Khi tôi đang làm việc trên sản phẩm của mình, Storylens — Một nền tảng viết blog miễn phí, tôi đã sử dụng kết hợp React và Redux. Cả React và Redux đều đánh giá cao việc kiểm tra bình đẳng nông. Điều này đảm bảo rằng DOM chỉ hiển thị lại khi tham chiếu của đối tượng bên dưới đã thay đổi. Vì vậy, khi bạn cập nhật trạng thái hoặc cửa hàng trong React/Redux, bạn sẽ phải tránh thay đổi đối tượng và mảng

Tương tự như vậy, hầu hết các ngăn xếp giao diện người dùng hiện đại ngày nay phụ thuộc rất nhiều vào cấu trúc dữ liệu Bất biến và nếu bạn định sử dụng chúng, tốt hơn là bạn nên làm quen với các khái niệm này. Hãy xem mảng và đối tượng

Mảng và đối tượng có thể thay đổi

Mảng và đối tượng không phải là bất biến trong JavaScript vì chúng thực sự có thể thay đổi giá trị của chúng theo thời gian. Hãy xác minh điều này bằng cách chạy các ví dụ mã sau trong bảng điều khiển

Java

 





xxxxxxxxxx

1



 

1

x += 1;
0

2

x += 1;
1

3

x += 1;
2

4

x += 1;
3

5

x += 1;
4

6

x += 1;
5

7

x += 1;
6




Như bạn có thể thấy, x là một đối tượng có thể thay đổi và bất kỳ thay đổi nào trong thuộc tính của x đều được phản ánh trong giá trị của y. Tại sao? . Vì vậy, khi bạn cập nhật giá trị của một thuộc tính của x, bạn đang sửa đổi giá trị cho tất cả các tham chiếu đến đối tượng đó

Chúng ta hãy xem Mảng

Java

 





xxxxxxxxxx

1



 

1

x += 1;
8

2

x += 1;
9




Chắc chắn rằng giá trị của y sẽ chứa cả 'foo' và 'bar'. Nhưng còn x thì sao?

Java

 





xxxxxxxxxx

1



 

1

xxxxxxxxxx
1

2

x += 1;
6




Cả x và y đều là tham chiếu đến cùng một mục và phương thức đẩy sẽ thay đổi mảng ban đầu. Rất nhiều phương thức mảng mà bạn sử dụng hàng ngày là phương thức Mutator. Đây là danh sách các phương thức Array hoạt động trên mảng ban đầu

  • copyWithin
  • lấp đầy
  • nhạc pop
  • đảo ngược
  • sự thay đổi
  • loại
  • mối nối
  • không dịch chuyển

Các phương thức như bản đồ và bộ lọc là bất biến vì chúng tạo một mảng mới mà không làm thay đổi mảng ban đầu. Bạn có thể xác minh điều này bằng cách chạy một ví dụ như thế này

Java

 





xxxxxxxxxx

1



 

1

xxxxxxxxxx
4

2

xxxxxxxxxx
5

3

xxxxxxxxxx
6

4

xxxxxxxxxx
7




Vì vậy, làm cho các đối tượng và mảng trở nên bất biến có nghĩa là gì? . Bất cứ khi nào nội dung của một đối tượng cần được sửa đổi, bạn sẽ không trực tiếp thay đổi đối tượng giá trị ban đầu. Thay vào đó, chúng tôi sẽ coi nó là bất biến và trả về một đối tượng hoàn toàn mới với giá trị được cập nhật

Bất biến trong JavaScript

Bạn có nhiều tùy chọn để thực thi tính bất biến trong JavaScript. Một số tính năng ES6 có thể được sử dụng để nhân bản các giá trị mà không cần sử dụng các tham chiếu ban đầu. Trong phần này, chúng ta sẽ khám phá các kỹ thuật khác nhau để triển khai Tính bất biến trong JavaScript cho Mảng và Đối tượng

Các đối tượng

Để tránh đột biến, tùy chọn có sẵn trong ES5 là đóng băng đối tượng bằng Object. Đông cứng. Đó cũng không phải là một lựa chọn tuyệt vời. Với ES6, bạn có thể ngăn các đối tượng đột biến bằng cách sử dụng phương thức

xxxxxxxxxx
5

Mục tiêu. gán() sao chép các giá trị (của tất cả các thuộc tính riêng có thể đếm được) từ một hoặc nhiều đối tượng nguồn sang đối tượng đích. Nó có chữ ký của Object. gán(mục tiêu, …nguồn)

Hãy xem xét một ví dụ về các đối tượng

Java

 





xxxxxxxxxx

1

10



 

1

xxxxxxxxxx
9

2

var myString = "I am immutable"
0

3

var myString = "I am immutable"
1

4

var myString = "I am immutable"
2

5

var myString = "I am immutable"
3

6

var myString = "I am immutable"
4

7

var myString = "I am immutable"
5

8

var myString = "I am immutable"
6

9

var myString = "I am immutable"
7

10

var myString = "I am immutable"
8




Tham số cho phương thức

xxxxxxxxxx
6 là đối tượng đích và bạn có thể chuyển nhiều hơn một đối tượng làm nguồn. Phương thức hợp nhất tất cả các nguồn từ phải sang trái theo thứ tự đó và trả về đối tượng đích. Bạn có thể sử dụng phương pháp để hợp nhất các đối tượng và sao chép chúng một cách nông cạn

Với cú pháp khá dài dòng của nó, Object. gán có thể làm cho mã của bạn khó đọc. Có một cú pháp thay thế được gọi là toán tử trải rộng đối tượng sử dụng ba dấu chấm để sao chép nông một đối tượng. Toán tử trải rộng cho phép bạn sử dụng để sao chép vô số thuộc tính từ nhiều nguồn bằng cách sử dụng một cách ngắn gọn. Đây là cách bạn sao chép các đối tượng bằng cách sử dụng toán tử trải rộng

Java

 





xxxxxxxxxx

1

10



 

1

xxxxxxxxxx
9

2

var myString = "I am immutable"
0

3

var myString = "I am immutable"
1

4

var myString = "I am immutable"
2

5

myString[2] = 'c'
4

6

myString[2] = 'c'
5

7

var myString = "I am immutable"
4

8

var myString = "I am immutable"
2

9

var myString = "I am immutable"
6

10

var myString = "I am immutable"
8




Xóa thuộc tính đối tượng

Có nhiều cách để bạn loại bỏ một thuộc tính mà không làm thay đổi đối tượng. Sở thích cá nhân của tôi là sử dụng cú pháp phá hủy đối tượng

Cú pháp gán phá hủy là một biểu thức JavaScript cho phép giải nén các giá trị từ mảng hoặc thuộc tính từ các đối tượng thành các biến riêng biệt

Đây là một ví dụ

Java

 





xxxxxxxxxx

1



 

1

console.log(myString)
1

2

console.log(myString)
2

3

console.log(myString)
3

4

console.log(myString)
4

5

x += 1;
2




Nếu bạn đã biết tên của thuộc tính cần xóa, bạn có thể thử điều này. ’

Java

 





xxxxxxxxxx

1



 

1

console.log(myString)
7

2

console.log(myString)
8

3

console.log(myString)
9




Nếu tên của thuộc tính cần xóa là động, bạn có thể thực hiện việc này

Java

 





xxxxxxxxxx

1



 

1

xxxxxxxxxx
1

2

xxxxxxxxxx
2

3

console.log(myString)
8

4

xxxxxxxxxx
4




Mảng

Như đã đề cập trước đó, hầu hết các phương thức mảng đều có thể thay đổi. Nhưng bạn có thể sử dụng cú pháp toán tử trải rộng trên mảng để thêm và xóa các mục khỏi một mảng. Hãy xem một ví dụ

Java

 





xxxxxxxxxx

1



 

1

xxxxxxxxxx
6

2

xxxxxxxxxx
7

3

xxxxxxxxxx
8




Tốt, điều đó thật dễ dàng. Chúng tôi giữ nguyên mảng cũ và tạo một mảng mới. Còn xóa thì sao?

Phương thức

xxxxxxxxxx
7 xóa phần tử khỏi mảng ban đầu. Vì vậy, thay vào đó, bạn có thể sử dụng
xxxxxxxxxx
8 để trả về một mảng mới

Tính bất biến trong Mảng đối tượng và Đối tượng lồng nhau

Các hàm mảng như. bản đồ là bất biến khi bạn ánh xạ một mảng giá trị. Tuy nhiên, chúng không phải là bất biến khi bạn đang làm việc với một mảng các đối tượng. Hãy mở rộng ví dụ về trái cây mà chúng ta đã tạo trước đó

Java

 





xxxxxxxxxx

1

21



 

1

var myString = "I am immutable.";
0

2

var myString = "I am immutable.";
1

3

var myString = "I am immutable.";
2

4

var myString = "I am immutable.";
3

5

var myString = "I am immutable.";
4

6

var myString = "I am immutable.";
1

7

var myString = "I am immutable.";
6

8

var myString = "I am immutable.";
7

9

var myString = "I am immutable.";
8

10

var myString = "I am immutable.";
9

11

var newString = myString.slice(0,7);
0

12

var newString = myString.slice(0,7);
1

13

var newString = myString.slice(0,7);
2

14

var newString = myString.slice(0,7);
3

15

var newString = myString.slice(0,7);
4

16

var newString = myString.slice(0,7);
5

17

var newString = myString.slice(0,7);
6

18

var newString = myString.slice(0,7);
7

19

var newString = myString.slice(0,7);
8

20

var newString = myString.slice(0,7);
9

21

xxxxxxxxxx
0




Java

 





xxxxxxxxxx

1



 

1

xxxxxxxxxx
2




Tại sao dữ liệu của mảng ban đầu cũng bị thay đổi? . Bất kỳ sửa đổi nào bạn thực hiện đối với một đối tượng trong mảng nhân bản sẽ sửa đổi đối tượng ban đầu thông qua tham chiếu

Tại sao tính bất biến lại quan trọng?

Nếu bạn đang tích cực sử dụng các thư viện giao diện người dùng như React, Vue hoặc thư viện quản lý trạng thái như Redux, bạn có thể đã gặp các cảnh báo nói rằng bạn không nên thay đổi trạng thái. Giữ trạng thái không thay đổi có thể giúp bạn về hiệu suất, khả năng dự đoán và theo dõi đột biến tốt hơn

khả năng dự đoán

Đối với bất kỳ ứng dụng cỡ trung bình nào, sẽ có trạng thái  —  rất nhiều ứng dụng — và các hành động không đồng bộ cập nhật trạng thái đó. Trạng thái của ứng dụng sẽ khác đáng kể so với trạng thái ban đầu sau khi người dùng cuối bắt đầu sử dụng ứng dụng. Đột biến ẩn các thay đổi dẫn đến tác dụng phụ, do đó gây khó khăn cho việc gỡ lỗi và tìm lỗi. Bằng cách giữ cho các cấu trúc của bạn không thay đổi, bạn sẽ có thể dự đoán những gì đang ở trạng thái tại bất kỳ thời điểm nào và bạn có thể yên tâm rằng sẽ không có bất kỳ tác dụng phụ khó chịu nào

Theo dõi đột biến

Với các thực thể bất biến, bạn có thể thấy những thay đổi xảy ra với các đối tượng này dưới dạng một chuỗi sự kiện. Điều này là do các biến có tham chiếu mới dễ theo dõi hơn so với các biến hiện có. Điều này đặc biệt có thể giúp bạn gỡ lỗi mã của bạn và xây dựng các ứng dụng đồng thời tốt hơn. Có các trình gỡ lỗi sự kiện giúp bạn phát lại các sự kiện DOM bằng các lần phát lại video hoạt động hoàn toàn dựa trên theo dõi đột biến

Tóm lược

Vì vậy, trong bài viết này, chúng tôi đã đề cập đến những điều cơ bản về đột biến và lý do tại sao từ bất biến lại phổ biến trong thế giới JavaScript gần đây. Nếu bạn có bất kỳ câu hỏi nào, hãy cho tôi biết trong phần bình luận

Loại dữ liệu nào là bất biến trong JavaScript?

Trong JavaScript Chuỗi và số là các kiểu dữ liệu không thể thay đổi.

Sự khác biệt giữa các loại dữ liệu có thể thay đổi và không thay đổi là gì?

Tóm tắt sự khác biệt, đối tượng có thể thay đổi có thể thay đổi trạng thái hoặc nội dung của chúng và đối tượng không thể thay đổi không thể thay đổi trạng thái hoặc nội dung của chúng . Đối tượng bất biến. Đây là các loại dựng sẵn như int, float, bool, string, unicode, tuple. Nói một cách đơn giản, một đối tượng bất biến không thể thay đổi sau khi nó được tạo.

Các loại bất biến và có thể thay đổi là gì?

Ví dụ về dữ liệu có thể thay đổi và bất biến là gì?

Danh sách, Bộ và Từ điển trong Python là ví dụ về một số loại dữ liệu có thể thay đổi trong Python. Kiểu dữ liệu không thể thay đổi là những loại có giá trị không thể sửa đổi sau khi chúng được tạo . Ví dụ về các kiểu dữ liệu bất biến là int, str, bool, float, tuple, v.v.