Biến trong JavaScript: Khám phá Kiểu dữ liệu nguyên thủy và Kiểu dữ liệu tham chiếu

0 0 0

Người đăng: Thái Thịnh

Theo Viblo Asia

Trong JavaScript, biến lưu trữ hai loại dữ liệu cơ bản: kiểu nguyên thủy và kiểu tham chiếu. Hiểu rõ sự khác biệt giữa hai loại này là điều cần thiết để quản lý bộ nhớ và kiểm soát việc chia sẻ, lưu trữ và thay đổi dữ liệu. Bài viết này sẽ đi sâu vào sự khác biệt, cung cấp các ví dụ thực tế và xem xét các phương pháp xử lý hiệu quả cả hai loại.

Kiểu nguyên thủy vs Kiểu tham chiếu

1. Kiểu nguyên thủy

Kiểu dữ liệu đơn giản nhất được gọi là kiểu nguyên thủy. Chúng lưu trữ trực tiếp dữ liệu không thay đổi trong biến. Các kiểu nguyên thủy mà JavaScript hỗ trợ như sau:

  • string: "hello"
  • number: 42
  • boolean: true hoặc false
  • null
  • undefined
  • symbol
  • bigint

Đặc điểm chính:

  • Bất biến: Giá trị của chúng không thể thay đổi trực tiếp.
  • Lưu trữ theo giá trị.

2. Kiểu tham chiếu

Mặt khác, kiểu tham chiếu lưu trữ vị trí bộ nhớ của các đối tượng. Thay vì lưu trữ giá trị thực tế, các biến lưu một tham chiếu đến địa chỉ bộ nhớ. Một số ví dụ bao gồm:

  • object: name: 'Alice'
  • array: [1, 2, 3]
  • function: function() console.log('hello');
  • Date: new Date()

Đặc điểm chính:

  • Có thể thay đổi: Nội dung của chúng có thể được sửa đổi.
  • Lưu trữ theo tham chiếu.

Kiểu nguyên thủy và Kiểu tham chiếu trong thực tế

Sau đây là một ví dụ minh họa:

// Primitive Example
let a = 10;
let b = a;
b = 20;
console.log(a); // Output: 10 // Reference Example
let obj1 = { name: 'Alice' };
let obj2 = obj1;
obj2.name = 'Bob';
console.log(obj1.name); // Output: 'Bob'

Giải thích:

  • Kiểu nguyên thủy: Việc gán a cho b tạo ra một bản sao của giá trị. Thay đổi b không ảnh hưởng đến a vì chúng độc lập.
  • Kiểu tham chiếu: Cả obj1 và obj2 đều trỏ đến cùng một vị trí bộ nhớ. Thay đổi nội dung thông qua obj2 cũng cập nhật obj1.

Hình dung khái niệm

  • Kiểu nguyên thủy: Hãy tưởng tượng mỗi biến như một chiếc hộp riêng chứa một giá trị. Sao chép tạo ra một hộp mới với một giá trị độc lập.
  • Kiểu tham chiếu: Hãy nghĩ về các biến như nhãn dán trỏ đến một thùng chứa chung. Tất cả các nhãn dán tham chiếu đến cùng một thùng chứa đều bị ảnh hưởng bởi những thay đổi được thực hiện đối với nội dung của nó.

Thay đổi (Mutation) vs Gán (Assignment)

Hiểu rõ sự khác biệt giữa thay đổi (mutation) và gán (assignment) là chìa khóa khi làm việc với kiểu tham chiếu.

1. Thay đổi (Mutation): Sửa đổi nội dung của đối tượng hiện có.

let arr = [1, 2, 3];
let arr2 = arr;
arr2.push(4);
console.log(arr); // Output: [1, 2, 3, 4]

2. Gán (Assignment): Thay đổi tham chiếu đến một đối tượng mới.

let arr = [1, 2, 3];
let arr2 = arr;
arr2 = [4, 5, 6];
console.log(arr); // Output: [1, 2, 3]

Sao chép Đối tượng và Mảng

Sao chép Nông (Shallow Copy): Để tạo một bản sao riêng biệt của một đối tượng hoặc mảng, hãy sử dụng toán tử spread (...) hoặc Object.assign().

let original = { name: 'Alice' };
let copy = { ...original };
copy.name = 'Bob';
console.log(original.name); // Output: 'Alice'

Sao chép Sâu (Deep Copy): Đối với các đối tượng lồng nhau, cần sao chép sâu. Một cách tiếp cận phổ biến là sử dụng JSON.parse(JSON.stringify()).

let nested = { person: { name: 'Alice' } };
let deepCopy = JSON.parse(JSON.stringify(nested));
deepCopy.person.name = 'Bob';
console.log(nested.person.name); // Output: 'Alice'

Truyền theo Giá trị vs truyền theo Tham chiếu

Kiểu Nguyên thủy (Truyền theo Giá trị): Khi truyền kiểu nguyên thủy cho một hàm, một bản sao của giá trị được truyền.

function modifyValue(x) { x = 20;
}
let num = 10;
modifyValue(num);
console.log(num); // Output: 10

Kiểu Tham chiếu (Truyền theo Tham chiếu): Khi truyền kiểu tham chiếu, một tham chiếu đến vị trí bộ nhớ được truyền.

function modifyObject(obj) { obj.name = 'Bob';
}
let person = { name: 'Alice' };
modifyObject(person);
console.log(person.name); // Output: 'Bob'

Kiểu Bao đóng Nguyên thủy (Primitive Wrapper Types)

Mặc dù kiểu nguyên thủy là bất biến, JavaScript tạm thời bao đóng chúng trong các đối tượng để cho phép truy cập vào các phương thức và thuộc tính.

let str = 'hello';
console.log(str.length); // Output: 5

Giải thích: Kiểu chuỗi nguyên thủy 'hello' được tạm thời bao đóng trong một đối tượng String để truy cập thuộc tính length. Kiểu bao đóng bị loại bỏ sau khi thao tác.

Các Best pratice tốt nhất

  • Sử dụng const cho Kiểu Tham chiếu: Khai báo các đối tượng và mảng với const ngăn chặn việc gán lại nhưng cho phép thay đổi nội dung.
 const obj = { name: 'Alice' }; obj.name = 'Bob'; // Allowed obj = { age: 25 }; // Error: Assignment to constant variable.
  • Tránh Thay đổi Không mong muốn: Nếu bạn cần một bản sao độc lập, hãy đảm bảo bạn tạo một bản sao bằng toán tử spread hoặc kỹ thuật sao chép sâu.

  • Biết Khi nào Sử dụng Sao chép Sâu: Đối với các đối tượng nông, toán tử spread là đủ, nhưng các cấu trúc lồng nhau yêu cầu sao chép sâu để tránh các vấn đề về tham chiếu.

  • Tận dụng Tính Bất biến: Sử dụng các thư viện như Immutable.js hoặc áp dụng các kỹ thuật lập trình hàm để giảm thiểu lỗi do thay đổi không mong muốn.

Những cạm bẫy thường gặp

  • Nhầm lẫn giữa Gán và Thay đổi: Hãy lưu ý xem bạn đang sửa đổi một đối tượng hay đang gán lại một tham chiếu.

  • Sửa đổi Tham chiếu Chung: Thay đổi đối tượng được chia sẻ có thể gây ra hậu quả không mong muốn nếu các phần khác của chương trình cũng sử dụng nó.

  • Giả định Tất cả Bản sao đều Độc lập: Hãy nhớ rằng sao chép nông không bảo vệ chống lại những thay đổi trong cấu trúc lồng nhau.

Kết luận

Sự phân biệt giữa kiểu nguyên thủy và kiểu tham chiếu là một trong những khái niệm cốt lõi của JavaScript. Nó ảnh hưởng đến cách bạn truyền dữ liệu cho các hàm, quản lý biến và ngăn chặn các tác dụng phụ không mong muốn trong mã của bạn. Bằng cách nắm vững những khái niệm này và áp dụng các thực tiễn tốt nhất, bạn có thể xây dựng mã JavaScript đáng tin cậy và dễ bảo trì hơn.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 525

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 433

- vừa được xem lúc

Một số phương thức với object trong Javascript

Trong Javascript có hỗ trợ các loại dữ liệu cơ bản là giống với hầu hết những ngôn ngữ lập trình khác. Bài viết này mình sẽ giới thiệu về Object và một số phương thức thường dùng với nó.

0 0 153

- vừa được xem lúc

Tìm hiểu về thư viện axios

Giới thiệu. Axios là gì? Axios là một thư viện HTTP Client dựa trên Promise.

0 0 145

- vừa được xem lúc

Imports và Exports trong JavaScript ES6

. Giới thiệu. ES6 cung cấp cho chúng ta import (nhập), export (xuất) các functions, biến từ module này sang module khác và sử dụng nó trong các file khác.

0 0 110

- vừa được xem lúc

Bài toán đọc số thành chữ (phần 2) - Hoàn chỉnh chương trình dưới 100 dòng code

Tiếp tục bài viết còn dang dở ở phần trước Phân tích bài toán đọc số thành chữ (phần 1) - Phân tích đề và những mảnh ghép đầu tiên. Bạn nào chưa đọc thì có thể xem ở link trên trước nhé.

0 0 245