Cách sử dụng định dạng JSON trong JavaScript

Javascript căn bản | by Học Javascript

Trong lập trình web hiện đại, JSON (JavaScript Object Notation) là một định dạng dữ liệu cực kỳ phổ biến, được sử dụng rộng rãi để trao đổi dữ liệu giữa client và server. JSON có cú pháp đơn giản, dễ đọc, dễ viết và được hỗ trợ tốt trong JavaScript cũng như nhiều ngôn ngữ lập trình khác.

Với sự phát triển mạnh mẽ của các ứng dụng web và API, việc hiểu và sử dụng JSON một cách hiệu quả là một kỹ năng quan trọng đối với mọi lập trình viên. Trong bài viết này, chúng ta sẽ tìm hiểu về JSON, cách chuyển đổi giữa JSON và JavaScript Object, cũng như cách sử dụng JSON trong thực tế.

JSON trong JavaScript là gì?

JSON (JavaScript Object Notation) là một định dạng dữ liệu có cấu trúc, được thiết kế để lưu trữ và trao đổi dữ liệu giữa các hệ thống. JSON sử dụng một cú pháp đơn giản, dựa trên các cặp key-value tương tự như JavaScript Object nhưng có một số quy tắc chặt chẽ hơn.

JSON thường được dùng để:

  • Truyền tải dữ liệu giữa client (trình duyệt) và server trong các ứng dụng web.
  • Lưu trữ cấu hình, dữ liệu trong file .json.
  • Giao tiếp giữa các hệ thống thông qua API (REST API, GraphQL).

Ví dụ về một dữ liệu JSON:

{
  "name": "Nguyễn Văn A",
  "age": 25,
  "email": "[email protected]",
  "skills": ["JavaScript", "React", "Node.js"]
}

Lý do JSON được sử dụng rộng rãi

JSON trở thành một tiêu chuẩn phổ biến trong lập trình web nhờ những ưu điểm sau:

Dễ đọc, dễ viết

  • Cú pháp đơn giản, không rườm rà như XML.
  • Giống với cách JavaScript định nghĩa object nên rất quen thuộc với lập trình viên.

Nhẹ hơn so với XML

  • JSON có kích thước nhỏ hơn, không cần các thẻ đóng mở như XML.
  • Dữ liệu JSON được truyền tải nhanh hơn, tiết kiệm băng thông.

So sánh JSON và XML:

Đặc điểm JSON XML
Cú pháp đơn giản Không
Dễ đọc và dễ hiểu Không
Dung lượng nhẹ Nhẹ hơn Nặng hơn
Hỗ trợ trong JavaScript Tích hợp sẵn Cần phân tích cú pháp (parsing)

Hỗ trợ tốt trong JavaScript và nhiều ngôn ngữ khác

  • JavaScript có sẵn công cụ xử lý JSON: JSON.parse()JSON.stringify().
  • JSON có thể được sử dụng trong Python, Java, C#, PHP, Ruby, v.v.
  • Là định dạng chuẩn của nhiều dịch vụ API hiện đại như REST API, Firebase, MongoDB.

Cách sử dụng JSON trong JavaScript

JSON là một phần quan trọng trong lập trình JavaScript, đặc biệt khi làm việc với dữ liệu từ API hoặc lưu trữ cấu hình. Dưới đây là cách sử dụng JSON trong JavaScript một cách chi tiết.

Cấu trúc của JSON

JSON có hai kiểu dữ liệu chính

  • Object (đối tượng): Là tập hợp các cặp key-value, được đặt trong dấu {}.
  • Array (mảng): Là danh sách các giá trị, được đặt trong dấu [].

Các kiểu dữ liệu hợp lệ trong JSON

Trong JSON, chỉ các kiểu dữ liệu sau đây được hỗ trợ:

  • String – Chuỗi phải được đặt trong dấu "" (không sử dụng ' như trong JavaScript).
  • Number – Hỗ trợ số nguyên và số thực.
  • Booleantrue hoặc false.
  • Null – Giá trị null.
  • Object – Đối tượng JSON.
  • Array – Mảng JSON.

Ví dụ JSON hợp lệ

{
  "name": "John",
  "age": 30,
  "isStudent": false,
  "skills": ["JavaScript", "React", "Node.js"],
  "address": {
    "city": "New York",
    "country": "USA"
  }
}

Chuyển đổi giữa JSON và JavaScript Object

Trong JavaScript, chúng ta cần chuyển đổi giữa Object (đối tượng JavaScript) và chuỗi JSON khi làm việc với dữ liệu từ API hoặc lưu trữ dữ liệu.

Chuyển đổi từ Object sang JSON (Serialization)

Dùng JSON.stringify() để chuyển Object thành chuỗi JSON.

Ví dụ:
const user = { 
  name: "Alice", 
  age: 25, 
  city: "New York" 
};

const jsonString = JSON.stringify(user);
console.log(jsonString); 
// Output: {"name":"Alice","age":25,"city":"New York"}

Lợi ích của JSON.stringify():

  • Giúp chuyển Object thành chuỗi JSON để lưu trữ hoặc gửi đến server.
  • Dữ liệu có thể được lưu vào localStorage, sessionStorage, database hoặc gửi qua API.

Tùy chọn trong JSON.stringify()

JSON.stringify(object, replacer, space)

  • replacer: Hàm hoặc mảng dùng để lọc ra các key cần giữ lại.
  • space: Số khoảng trắng để format JSON dễ đọc hơn.

Ví dụ sử dụng space để format JSON đẹp hơn:

const formattedJSON = JSON.stringify(user, null, 2);
console.log(formattedJSON);
/* Output:
{
  "name": "Alice",
  "age": 25,
  "city": "New York"
}
*/

Chuyển đổi từ JSON sang Object (Deserialization)

Dùng JSON.parse() để chuyển chuỗi JSON thành Object.

Ví dụ:
b) Chuyển đổi từ JSON sang Object (Deserialization)
Dùng JSON.parse() để chuyển chuỗi JSON thành Object.

Ví dụ:

Lưu ý khi dùng JSON.parse():

  • Nếu JSON không hợp lệ (ví dụ: thiếu dấu "), sẽ gây lỗi SyntaxError.
  • Chỉ parse được chuỗi JSON hợp lệ (dữ liệu phải có dạng "{...}" hoặc "[]").

Lỗi thường gặp khi dùng JSON.parse():

const wrongJson = "{name:'Alice', age:25}"; // Lỗi vì thiếu dấu "" quanh key
console.log(JSON.parse(wrongJson)); 
// Uncaught SyntaxError: Unexpected token n in JSON at position 1
Cách sửa:
const correctJson = '{"name":"Alice","age":25}';
console.log(JSON.parse(correctJson)); // {name: "Alice", age: 25}

Làm việc với JSON trong API và AJAX

JSON thường được sử dụng để trao đổi dữ liệu giữa Frontend và Backend thông qua API.

Gửi yêu cầu API và xử lý JSON bằng fetch()

Khi lấy dữ liệu từ API, chúng ta cần chuyển đổi phản hồi (response) từ JSON thành Object bằng response.json().

Ví dụ: Lấy dữ liệu từ API
fetch("https://jsonplaceholder.typicode.com/users/1")
  .then(response => response.json())  // Chuyển đổi JSON thành Object
  .then(data => console.log(data))    // Hiển thị dữ liệu
  .catch(error => console.error("Lỗi:", error));

Giải thích:

  1. fetch() gửi yêu cầu API.
  2. response.json() chuyển đổi phản hồi thành Object.
  3. Dữ liệu JSON đã parse được xử lý trong .then().
  4. catch() xử lý lỗi nếu có.

Output:

{
  "id": 1,
  "name": "Leanne Graham",
  "username": "Bret",
  "email": "[email protected]"
}

Gửi dữ liệu JSON lên Server bằng fetch()

Chúng ta có thể gửi dữ liệu dạng JSON lên server bằng HTTP POST request.

Ví dụ: Gửi dữ liệu JSON
const newUser = {
  name: "Alice",
  email: "[email protected]"
};

fetch("https://jsonplaceholder.typicode.com/users", {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
  },
  body: JSON.stringify(newUser)
})
  .then(response => response.json()) 
  .then(data => console.log("Phản hồi từ server:", data))
  .catch(error => console.error("Lỗi:", error));

Giải thích:

  • method: "POST" để gửi dữ liệu.
  • headers chứa "Content-Type": "application/json" để báo server biết định dạng dữ liệu.
  • body: JSON.stringify(newUser) chuyển Object thành JSON để gửi đi.
  • response.json() parse phản hồi từ server.

Các lưu ý quan trọng khi sử dụng JSON trong JavaScript

Mặc dù JSON rất hữu ích trong việc trao đổi dữ liệu giữa clientserver, nhưng khi sử dụng nó, chúng ta cần lưu ý một số vấn đề quan trọng để tránh lỗi và xử lý dữ liệu hiệu quả.

JSON không hỗ trợ hàm (function)

Vấn đề

JSON không thể lưu trữ hoặc chuyển đổi function. Nếu một Object chứa function, khi sử dụng JSON.stringify(), function sẽ bị loại bỏ.

Ví dụ minh họa

const obj = {
  name: "Bob",
  greet: function () {
    return "Hello!";
  }
};

console.log(JSON.stringify(obj)); 
// Output: {"name":"Bob"}  (hàm greet đã bị loại bỏ)

Cách xử lý

Nếu bạn cần lưu trữ function trong JSON, hãy sử dụng một cách khác như lưu function dưới dạng chuỗi (string) và khi cần thì chuyển lại thành function.

Cách lưu function dưới dạng string

const obj = {
  name: "Bob",
  greet: "function() { return 'Hello!'; }"
};

const jsonString = JSON.stringify(obj);
console.log(jsonString);
// Output: {"name":"Bob","greet":"function() { return 'Hello!'; }"}

Cách chuyển đổi lại thành function

const parsedObj = JSON.parse(jsonString);
parsedObj.greet = new Function("return 'Hello!';");
console.log(parsedObj.greet()); // Output: Hello!

Lưu ý: Cách này không an toàn nếu dữ liệu JSON đến từ một nguồn không đáng tin cậy, vì có thể tạo ra lỗ hổng bảo mật (vulnerabilities).

Xử lý lỗi khi parse JSON (JSON.parse())

Vấn đề

Nếu chuỗi JSON không hợp lệ, JSON.parse() sẽ gây lỗi và dừng chương trình.

Ví dụ gây lỗi

const invalidJson = "{ name: 'Alice' }";  // Lỗi vì thiếu dấu ngoặc kép quanh key
const data = JSON.parse(invalidJson);  
// Uncaught SyntaxError: Unexpected token n in JSON

Cách xử lý lỗi bằng try...catch

Để tránh chương trình bị dừng đột ngột, chúng ta bọc JSON.parse() trong try...catch để xử lý lỗi một cách an toàn.

const invalidJson = "{ name: 'Alice' }"; // JSON sai cú pháp

try {
  const data = JSON.parse(invalidJson);
  console.log(data);
} catch (error) {
  console.error("Lỗi khi parse JSON:", error.message);
}

Output khi có lỗi:

Lỗi khi parse JSON: Unexpected token n in JSON at position 2

Ưu điểm: Giúp chương trình không bị dừng đột ngột khi gặp lỗi JSON.

JSON.stringify() có thể loại bỏ dữ liệu không thể chuyển đổi

Khi sử dụng JSON.stringify(), một số kiểu dữ liệu không được hỗ trợ sẽ bị loại bỏ.

Các kiểu dữ liệu bị loại bỏ

  • undefined
  • function
  • Symbol

Ví dụ minh họa

const obj = { 
  name: "Eve", 
  age: undefined, 
  greet: () => "Hello", 
  symbolKey: Symbol("id")
};

console.log(JSON.stringify(obj)); 
// Output: {"name":"Eve"}  (Các giá trị `undefined`, function và Symbol đã bị loại bỏ)

Nếu cần lưu trữ undefined, function hoặc Symbol, có thể:

  • Dùng giá trị null thay thế cho undefined.
  • Biến function thành string trước khi lưu.
  • Dùng replacer trong JSON.stringify() để kiểm soát dữ liệu bị loại bỏ.

Cách thay thế undefined bằng null

const obj = { name: "Eve", age: undefined || null };
console.log(JSON.stringify(obj)); 
// Output: {"name":"Eve","age":null}

Cách lưu function dưới dạng string

const obj = { 
  name: "Eve", 
  greet: "function() { return 'Hello!'; }" 
};

console.log(JSON.stringify(obj)); 
// Output: {"name":"Eve","greet":"function() { return 'Hello!'; }"}
Sử dụng replacer trong JSON.stringify()
const obj = { 
  name: "Eve", 
  age: undefined, 
  greet: () => "Hello", 
  symbolKey: Symbol("id")
};

// replacer function: Chỉ giữ lại key có kiểu dữ liệu hợp lệ
const jsonString = JSON.stringify(obj, (key, value) => {
  if (typeof value === "undefined" || typeof value === "function" || typeof value === "symbol") {
    return null;
  }
  return value;
});

console.log(jsonString); 
// Output: {"name":"Eve"}
Vấn đề Nguyên nhân Cách xử lý
JSON không hỗ trợ function Khi sử dụng JSON.stringify(), function sẽ bị loại bỏ Lưu function dưới dạng string và chuyển đổi lại khi cần
Lỗi khi parse JSON (JSON.parse()) JSON không hợp lệ (thiếu dấu "", sai dấu ,,...) Sử dụng try...catch để xử lý lỗi
JSON.stringify() loại bỏ undefined, function, Symbol` Vì JSON chỉ hỗ trợ String, Number, Boolean, Object, Array Sử dụng null thay cho undefined, lưu function dưới dạng string hoặc sử dụng replacer

Khi sử dụng JSON trong JavaScript, cần cẩn thận với các kiểu dữ liệu bị mất và sử dụng các kỹ thuật xử lý lỗi để tránh chương trình bị dừng đột ngột.

Ứng dụng thực tế của JSON trong JavaScript

JSON là một định dạng dữ liệu phổ biến, có rất nhiều ứng dụng thực tế trong lập trình JavaScript. Dưới đây là một số trường hợp sử dụng phổ biến của JSON trong việc lưu trữ dữ liệu, trao đổi thông tin giữa clientserver, quản lý cấu hình hệ thống, và làm việc với cơ sở dữ liệu NoSQL.

Lưu trữ dữ liệu cục bộ bằng LocalStorage và SessionStorage

JSON được sử dụng để lưu trữ dữ liệu trên trình duyệt thông qua LocalStorage và SessionStorage.

  • LocalStorage: Dữ liệu không bị xóa khi tải lại trang hoặc đóng trình duyệt.
  • SessionStorage: Dữ liệu chỉ tồn tại trong một phiên (session), khi đóng trình duyệt, dữ liệu sẽ bị mất.

Ví dụ minh họa

Lưu dữ liệu vào LocalStorage

const user = { name: "Charlie", age: 28 };

// Chuyển đổi object thành JSON và lưu vào LocalStorage
localStorage.setItem("user", JSON.stringify(user));

// Lấy dữ liệu từ LocalStorage và chuyển thành object
const storedUser = JSON.parse(localStorage.getItem("user"));

console.log(storedUser); 
// Output: { name: "Charlie", age: 28 }

Lưu dữ liệu vào SessionStorage

const sessionData = { token: "abc123", expiresIn: 3600 };

// Lưu vào SessionStorage
sessionStorage.setItem("session", JSON.stringify(sessionData));

// Lấy dữ liệu từ SessionStorage
const storedSession = JSON.parse(sessionStorage.getItem("session"));

console.log(storedSession); 
// Output: { token: "abc123", expiresIn: 3600 }

Dữ liệu có thể lưu trên trình duyệt mà không cần server.
Giúp giảm số lần gọi API, cải thiện hiệu suất.
Dễ dàng truy xuất khi cần thiết.

Truyền dữ liệu giữa Frontend và Backend qua API

JSON là định dạng mặc định trong hầu hết các API hiện đại để truyền dữ liệu giữa client (frontend)server (backend).

Ví dụ: Gửi request bằng Fetch API

fetch("https://jsonplaceholder.typicode.com/users", {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    name: "Alice",
    email: "[email protected]"
  })
})
  .then(response => response.json()) // Chuyển đổi JSON response thành Object
  .then(data => console.log("Response từ server:", data))
  .catch(error => console.error("Lỗi:", error));

Ưu điểm:
Dễ dàng gửi và nhận dữ liệu từ server.
Giúp đồng bộ hóa dữ liệu giữa client và backend.
Hỗ trợ hầu hết các ngôn ngữ lập trình như Node.js, Python, PHP, Java,...

Định dạng dữ liệu trong các file cấu hình (config.json)

JSON thường được sử dụng để lưu cấu hình hệ thống trong các file .json, giúp dễ dàng thay đổi mà không cần chỉnh sửa code.

Ví dụ: File config.json trong một ứng dụng Node.js

{
  "appName": "MyApp",
  "version": "1.0.0",
  "database": {
    "host": "localhost",
    "port": 3306,
    "username": "admin",
    "password": "123456"
  }
}
Cách đọc file config.json trong JavaScript
fetch("./config.json")
  .then(response => response.json()) // Chuyển đổi JSON thành Object
  .then(config => console.log("Cấu hình:", config))
  .catch(error => console.error("Lỗi khi đọc file:", error));

Dễ dàng chỉnh sửa cấu hình mà không cần thay đổi mã nguồn.
Tách biệt dữ liệu cấu hình khỏi logic ứng dụng.
Hỗ trợ tốt trong các hệ thống lớn (ví dụ: package.json trong Node.js).

Làm việc với Firebase và các dịch vụ lưu trữ dữ liệu NoSQL

Các cơ sở dữ liệu NoSQL như MongoDB, Firebase Firestore sử dụng JSON để lưu trữ và truy vấn dữ liệu.

Ví dụ: Lưu và truy xuất dữ liệu từ Firebase Firestore

import { initializeApp } from "firebase/app";
import { getFirestore, doc, setDoc, getDoc } from "firebase/firestore"; 

// Cấu hình Firebase
const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "your-project.firebaseapp.com",
  projectId: "your-project-id",
  storageBucket: "your-project.appspot.com",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID"
};

// Khởi tạo Firebase
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

// Lưu dữ liệu JSON vào Firestore
const saveUser = async () => {
  await setDoc(doc(db, "users", "user1"), {
    name: "David",
    age: 25,
    email: "[email protected]"
  });
  console.log("Dữ liệu đã được lưu");
};

// Lấy dữ liệu JSON từ Firestore
const getUser = async () => {
  const docSnap = await getDoc(doc(db, "users", "user1"));
  if (docSnap.exists()) {
    console.log("Dữ liệu người dùng:", docSnap.data());
  } else {
    console.log("Không tìm thấy dữ liệu");
  }
};

// Gọi hàm lưu và lấy dữ liệu
saveUser();
getUser();

Dữ liệu JSON được lưu trữ trực tiếp trong Firestore, MongoDB.
Truy xuất dữ liệu nhanh chóng, không cần schema cố định như SQL.
Linh hoạt, phù hợp với các ứng dụng web và mobile.

Kết bài

JSON (JavaScript Object Notation) là một định dạng dữ liệu quan trọng và không thể thiếu trong lập trình JavaScript. Với cú pháp đơn giản, dễ đọc, dễ ghi và khả năng tương thích cao, JSON được sử dụng rộng rãi trong lưu trữ dữ liệu, truyền tải thông tin giữa client và server, cấu hình hệ thống, và tích hợp với các cơ sở dữ liệu NoSQL như Firebase, MongoDB.

Việc hiểu và sử dụng JSON thành thạo giúp lập trình viên tối ưu hóa hiệu suất, đơn giản hóa việc quản lý dữ liệu, và xây dựng các ứng dụng web linh hoạt, mạnh mẽ hơn. Khi làm việc với JSON, cần lưu ý đến các lỗi phổ biến như mất dữ liệu khi stringify, lỗi parse JSON không hợp lệ, và các giới hạn khi sử dụng trong JavaScript để đảm bảo hiệu quả tối đa.

Bài viết liên quan