Các kiểu dữ liệu có thể là một khái niệm khó hiểu. Nhưng với tư cách là lập trình viên, chúng ta sử dụng các kiểu dữ liệu hàng ngày – vì vậy chúng ta nên hiểu chúng.
Câu hỏi đặt ra là máy tính lưu trữ các loại dữ liệu này như thế nào? Nó không thể xử lý mọi loại dữ liệu như nhau.
Trong JavaScript, các loại dữ liệu được chia thành hai loại và máy tính xử lý từng loại khác nhau. Chúng ta có kiểu dữ liệu nguyên thủy và kiểu dữ liệu tham chiếu. Nhưng những cái này là gì? Và tại sao điều quan trọng là phải biết sự khác biệt? Đó là những gì chúng ta sẽ tìm hiểu trong bài viết này.
Các kiểu dữ liệu này khá đơn giản và đôi khi được coi là mức triển khai thấp nhất của ngôn ngữ lập trình. Chúng không phải là đối tượng và không có phương thức.
Ví dụ về các kiểu dữ liệu như vậy là số, chuỗi, booleans, null và không xác định.

Nhưng bạn có thể thắc mắc về các chuỗi, bởi vì chúng có các phương thức. Thực tế là, JavaSvript chuyển đổi các chuỗi nguyên thủy thành các đối tượng chuỗi, để có thể sử dụng các phương thức đối tượng chuỗi.
Khi bạn khai báo một kiểu dữ liệu nguyên thủy trong JavaScript, nó sẽ được lưu trữ trên một ngăn xếp. Ngăn xếp là một cấu trúc dữ liệu đơn giản mà máy tính sử dụng để lưu trữ và truy xuất dữ liệu một cách nhanh chóng.
Kiểu dữ liệu nguyên thủy trên ngăn xếp được xác định bằng tên biến mà bạn đã sử dụng để khai báo trong chương trình của mình. Với mỗi kiểu dữ liệu nguyên thủy mà bạn tạo, dữ liệu sẽ được thêm vào ngăn xếp.
Để thực hiện điều này, giả sử chúng ta khai báo một biến, numOne
và đặt cho nó một giá trị là 50. Chúng ta tiếp tục tạo một biến khác, numTwo
và gán cho nó cùng một giá trị là 50. Vì vậy, cả hai biến đều có cùng một giá trị.
Điều xảy ra trên ngăn xếp là máy tính tạo chỗ cho numOne
và lưu trữ giá trị được gán của nó trên ngăn xếp. Khi nào numTwo
được tạo, máy tính lại tạo phòng và lưu trữ 50 trên ngăn xếp. Không có vấn đề gì khi cả hai biến được gán cùng một giá trị.

Điều gì sẽ xảy ra nếu trong quá trình mã hóa, chúng tôi quyết định cập nhật giá trị của numOne
để nói, 100? Có nghĩa là numTwo
cũng sẽ thay đổi? Câu trả lời là không.
Từ numOne
và numTwo
được lưu trữ khác nhau trên ngăn xếp, việc cập nhật một trong số chúng sẽ không ảnh hưởng đến cái kia. Và chúng ta có thể thử nghiệm điều đó bằng cách thực sự dùng thử trong trình chỉnh sửa mã của mình.
ghi nhật ký numOne
đến bàn điều khiển sẽ xuất 100 và ghi nhật ký numTwo
sẽ xuất ra 50. Vì vậy, trên thực tế, hai biến không có mối quan hệ nào với nhau.
let numOne = 50;
let numTwo = numOne; //numTwo=numOne=50
numOne = 100;
console.log(numOne); //outputs 100
console.log(numTwo); //outputs 50

Bây giờ chúng ta đã thấy việc xử lý các kiểu dữ liệu nguyên thủy dễ dàng như thế nào, hãy xem các kiểu dữ liệu tham chiếu tương tự hoạt động như thế nào.
Các kiểu dữ liệu tham chiếu, không giống như các kiểu dữ liệu nguyên thủy, có bản chất là động. Đó là, chúng không có kích thước cố định.
Hầu hết chúng được coi là đối tượng, và do đó có phương thức. Ví dụ về các kiểu dữ liệu như vậy bao gồm mảng, hàm, tập hợp và tất cả các kiểu đối tượng khác.

Sự khác biệt xuất hiện khi máy tính phải lưu trữ một loại dữ liệu tham chiếu. Khi bạn tạo một biến và gán cho nó một giá trị là kiểu dữ liệu tham chiếu, máy tính không lưu trực tiếp kiểu dữ liệu đó vào biến đó (như trường hợp của kiểu nguyên thủy).
Những gì bạn đã gán cho biến đó là một con trỏ trỏ đến vị trí của kiểu dữ liệu đó trong bộ nhớ. Gây nhầm lẫn? Tôi biết.

Như bạn có thể thấy trong hình trên, hiện tại chúng ta có hai cấu trúc dữ liệu. Một ngăn xếp, và một đống. Giả sử chúng ta đã khai báo một đối tượng chẳng hạn. Bản thân đối tượng được lưu trữ trên một đống và con trỏ của nó được lưu trữ trên một ngăn xếp. Con trỏ được xác định bởi tên biến của đối tượng và trỏ tới đối tượng đó.
Bây giờ, chúng ta có thể tạo một biến, object1
, và gán một đối tượng cho nó. Điều gì sẽ xảy ra nếu như trước đây, chúng ta tạo một biến khác object2
và gán nó cho object1
. Điều đó có nghĩa là một đối tượng khác sẽ được tạo trên heap? Câu trả lời là không.
Vì đối tượng đã tồn tại trên heap, object2
và object1
cả hai sẽ trỏ đến cùng một đối tượng.
Một sự khác biệt khác xuất hiện khi chúng tôi cập nhật object1
. Nếu chúng tôi ghi cả hai biến vào bảng điều khiển, chúng tôi sẽ thấy rằng thay đổi đã ảnh hưởng đến cả hai. Điều này là do chúng đang trỏ đến cùng một đối tượng trên heap – và việc cập nhật một biến tất nhiên sẽ ảnh hưởng đến biến kia.
let object1 = {
name:'Bingeh',
age:18
};
let object2 = object1;
//updating object1,
object1.age = 20;
console.log(object2); //we see that object2 also updates the age attribute

Bây giờ bạn đã biết sự khác biệt giữa kiểu dữ liệu nguyên thủy và kiểu dữ liệu tham chiếu. Điều quan trọng là phải biết những khác biệt này – đặc biệt là khi bạn gặp lỗi như ‘tham chiếu con trỏ null’ – để bạn có thể tìm ra lý do tại sao chúng lại xảy ra.
Điều này đôi khi xảy ra với các nhà phát triển Java, vì vậy tôi hy vọng rằng bài viết này sẽ giúp bạn giải tỏa mọi nghi ngờ.