Thuộc tính của Object trong Javascript

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

cMột Object là tập hợp của các thuộc tính (properties), được biểu diễn dưới dạng các cặp key-value, giúp lưu trữ và truy xuất thông tin một cách hiệu quả.

Thuộc tính (Properties) đóng vai trò cốt lõi trong Object, giúp định nghĩa các đặc điểm và thông tin của một đối tượng. Mỗi thuộc tính có thể chứa dữ liệu dạng số, chuỗi, boolean, hoặc thậm chí là một hàm (method), giúp Object trở nên linh hoạt và mạnh mẽ hơn trong lập trình.

Khái niệm về thuộc tính trong Object trong JavaScript

Định nghĩa thuộc tính (Property) trong Object

Trong JavaScript, một thuộc tính (property) là một cặp key-value được sử dụng để lưu trữ dữ liệu trong một Object. Key là tên thuộc tính (dạng chuỗi hoặc Symbol), còn value là giá trị của thuộc tính, có thể là bất kỳ kiểu dữ liệu nào như số, chuỗi, mảng, đối tượng hoặc một hàm.

Cấu trúc của một thuộc tính (Key-Value Pair)

Cấu trúc của một thuộc tính trong Object có dạng:

const person = {
  name: "John",      // Thuộc tính với key là "name" và value là chuỗi "John"
  age: 30,           // Thuộc tính với key là "age" và value là số 30
  isStudent: false   // Thuộc tính với key là "isStudent" và value là boolean false
};
  • Key (Tên thuộc tính): Luôn là một chuỗi hoặc Symbol, nếu không phải chuỗi thì JavaScript tự động chuyển đổi thành chuỗi.
  • Value (Giá trị thuộc tính): Có thể là bất kỳ kiểu dữ liệu nào, bao gồm số, chuỗi, boolean, mảng, object hoặc hàm.

Ví dụ với key không phải chuỗi:

const obj = {
  1: "one",       // Key là số, nhưng tự động chuyển thành chuỗi "1"
  true: "yes"     // Key là boolean, nhưng cũng sẽ chuyển thành chuỗi "true"
};

console.log(obj["1"]);   // Output: "one"
console.log(obj[true]);  // Output: "yes"

Phân biệt thuộc tính tĩnh và thuộc tính động

Thuộc tính tĩnh (Static Properties)

  • Được khai báo sẵn trong Object và không thay đổi tên trong quá trình thực thi chương trình.
  • Thường được sử dụng để lưu trữ dữ liệu cố định hoặc dễ dự đoán.

Ví dụ:

const car = {
  brand: "Toyota",
  model: "Camry",
  year: 2023
};

console.log(car.brand); // Output: "Toyota"

Thuộc tính động (Dynamic Properties)

  • Được thêm vào Object sau khi Object đã được khai báo, hoặc thay đổi tên thuộc tính dựa trên biến.
  • Giúp Object linh hoạt hơn trong quá trình lập trình.

Ví dụ thêm thuộc tính động:

const user = {};
user.name = "Alice";   // Thêm thuộc tính động
user.age = 25;

console.log(user); // Output: { name: 'Alice', age: 25 }

Ví dụ sử dụng biến làm key thuộc tính:

const key = "email";
const person = {
  [key]: "[email protected]"  // Key là giá trị của biến key
};

console.log(person.email); // Output: "[email protected]"

Cách khai báo và truy cập thuộc tính trong JavaScript

Khai báo thuộc tính trong Object

Khai báo trực tiếp trong Object Literal {}

Cách phổ biến nhất để khai báo thuộc tính là sử dụng Object Literal. Khi tạo một Object bằng dấu {}, chúng ta có thể khai báo các thuộc tính ngay bên trong nó dưới dạng cặp key: value.

Ví dụ:

const person = {
  name: "Alice",
  age: 25,
  city: "New York"
};
console.log(person); 
// Output: { name: 'Alice', age: 25, city: 'New York' }

Kết quả:

Ưu điểm:

  • Dễ đọc và dễ hiểu.
  • Thích hợp cho Object có dữ liệu cố định ngay từ đầu.

Thêm thuộc tính vào Object sau khi khởi tạo

Chúng ta có thể thêm thuộc tính vào một Object đã tồn tại bằng cách sử dụng toán tử . hoặc [].

Ví dụ thêm thuộc tính động:

const user = {};
user.name = "Bob";  // Thêm thuộc tính name
user.age = 30;      // Thêm thuộc tính age

console.log(user); 
// Output: { name: 'Bob', age: 30 }

Ví dụ thêm thuộc tính bằng biến làm key:

const key = "email";
const person = {};
person[key] = "[email protected]";  // Thêm thuộc tính động

console.log(person.email); 
// Output: "[email protected]"

Ưu điểm:

  • Giúp Object linh hoạt hơn khi làm việc với dữ liệu không cố định.
  • Có thể sử dụng biến để định nghĩa tên thuộc tính một cách linh hoạt.

Truy cập thuộc tính

Dùng dấu chấm (.) - Dot Notation

Cách thông dụng nhất để truy cập thuộc tính là sử dụng dấu ..

Ví dụ:

const car = {
  brand: "Toyota",
  model: "Camry",
  year: 2023
};

console.log(car.brand); // Output: "Toyota"
console.log(car.model); // Output: "Camry"

Lưu ý:

  • Chỉ sử dụng khi tên thuộc tính là một tên hợp lệ (không chứa dấu cách, ký tự đặc biệt, bắt đầu bằng số,...).

Dùng dấu ngoặc vuông ([]) - Bracket Notation

Sử dụng dấu [] giúp truy cập thuộc tính có tên là biến động hoặc chứa ký tự đặc biệt.

Ví dụ:

const person = {
  "full name": "John Doe",
  age: 28
};

console.log(person["full name"]); // Output: "John Doe"
console.log(person["age"]);       // Output: 28
Ví dụ sử dụng biến làm key:
const key = "email";
const user = {
  [key]: "[email protected]"
};

console.log(user["email"]); // Output: "[email protected]"

Khi nào nên dùng dấu [] thay vì .?

  • Khi key có dấu cách hoặc ký tự đặc biệt (ví dụ: "full name").
  • Khi key được xác định dựa trên biến động thay vì một chuỗi cố định.

Cập nhật và xóa thuộc tính

Cập nhật giá trị thuộc tính

Có thể cập nhật giá trị của một thuộc tính bằng cách gán giá trị mới cho nó.

Ví dụ:

const book = {
  title: "JavaScript Basics",
  price: 20
};

// Cập nhật giá trị
book.price = 25;
console.log(book.price); // Output: 25

Nếu thuộc tính chưa tồn tại, JavaScript sẽ tự động thêm mới thuộc tính đó vào Object.

book.author = "John Doe";
console.log(book); 
// Output: { title: 'JavaScript Basics', price: 25, author: 'John Doe' }

Xóa thuộc tính bằng delete object.property

Để xóa một thuộc tính khỏi Object, sử dụng toán tử delete.

Ví dụ:

const user = {
  name: "Alice",
  age: 25,
  email: "[email protected]"
};

// Xóa thuộc tính email
delete user.email;

console.log(user); 
// Output: { name: 'Alice', age: 25 }

Kết quả:

Lưu ý:

  • delete chỉ xóa thuộc tính khỏi Object, nhưng không giải phóng bộ nhớ ngay lập tức.
  • Nếu Object có prototype, delete không ảnh hưởng đến thuộc tính kế thừa từ prototype.
Hành động Cách thực hiện
Khai báo thuộc tính { key: value } hoặc object.key = value hoặc object["key"] = value
Truy cập thuộc tính object.key (dot notation) hoặc object["key"] (bracket notation)
Cập nhật thuộc tính object.key = newValue
Xóa thuộc tính delete object.key

Nắm vững cách khai báo, truy cập, cập nhật và xóa thuộc tính sẽ giúp bạn làm việc hiệu quả hơn với Object trong JavaScript!

Các loại thuộc tính trong Object trong JavaScript

Trong JavaScript, thuộc tính của một Object không chỉ là các cặp key-value, mà còn có những thuộc tính mô tả (property attributes) giúp kiểm soát cách thuộc tính hoạt động. Các thuộc tính này gồm:

  • Thuộc tính có thể liệt kê (Enumerable properties)
  • Thuộc tính có thể ghi (Writable properties)
  • Thuộc tính có thể cấu hình (Configurable properties)

Thuộc tính có thể liệt kê (Enumerable Properties)

Đặc điểm của thuộc tính có thể liệt kê

  • Thuộc tính có thể liệt kê là những thuộc tính có thể xuất hiện khi duyệt qua Object bằng for...in hoặc Object.keys().
  • Mặc định, các thuộc tính được tạo bằng Object Literal {} hoặc new Object() đều là enumerable (enumerable: true).

Kiểm tra một thuộc tính có thể liệt kê hay không

Sử dụng propertyIsEnumerable()
Phương thức propertyIsEnumerable(property) giúp kiểm tra một thuộc tính có thể liệt kê hay không.

const person = {
  name: "Alice",
  age: 25
};

console.log(person.propertyIsEnumerable("name")); // Output: true
console.log(person.propertyIsEnumerable("age"));  // Output: true

Sử dụng Object.propertyDescriptor()

const person = {
  name: "Alice",
  age: 25
};

const descriptor = Object.getOwnPropertyDescriptor(person, "name");
console.log(descriptor.enumerable); // Output: true

Thuộc tính có thể ghi (Writable Properties)

Quyền ghi vào thuộc tính (writable: true/false)

  • Thuộc tính có thể ghi (writable: true) nghĩa là có thể thay đổi giá trị của nó.
  • Nếu một thuộc tính có writable: false, bạn không thể cập nhật giá trị của nó.

Ví dụ: Thuộc tính writable

const user = {};
Object.defineProperty(user, "role", {
  value: "admin",
  writable: false // Không cho phép thay đổi giá trị
});

console.log(user.role); // Output: "admin"
user.role = "editor"; // Không thay đổi được do writable: false
console.log(user.role); // Output: "admin"

Lưu ý: Khi một thuộc tính có writable: false, việc gán giá trị mới sẽ không gây lỗi trong chế độ bình thường, nhưng sẽ tạo lỗi nếu chạy ở chế độ "use strict".

"use strict";
const obj = {};
Object.defineProperty(obj, "name", {
  value: "Alice",
  writable: false
});

obj.name = "Bob"; // Lỗi: Cannot assign to read-only property 'name'

Thuộc tính có thể cấu hình (Configurable Properties)

Ý nghĩa của configurable: true/false

  • Nếu configurable: true, bạn có thể xóa hoặc thay đổi mô tả của thuộc tính.
  • Nếu configurable: false, thuộc tính không thể bị xóa và không thể thay đổi một số thuộc tính mô tả (như writableenumerable).

Ví dụ: Thuộc tính configurable

const user = {};
Object.defineProperty(user, "id", {
  value: 1001,
  configurable: false // Không cho phép xóa hoặc thay đổi mô tả thuộc tính
});

console.log(user.id); // Output: 1001

delete user.id; // Không xóa được
console.log(user.id); // Output: 1001

Khi configurable: false, chúng ta không thể xóa thuộc tính hoặc thay đổi mô tả của nó.

Object.defineProperty(user, "id", {
  value: 2002
}); 
// Lỗi: Cannot redefine property: id

Loại thuộc tính Mô tả Giá trị mặc định
Enumerable Quyết định thuộc tính có xuất hiện khi duyệt Object hay không (for...in, Object.keys()). true
Writable Quyết định có thể thay đổi giá trị của thuộc tính hay không. true
Configurable Quyết định có thể xóa hoặc thay đổi mô tả của thuộc tính hay không. true

Để kiểm soát các thuộc tính trong Object, chúng ta có thể sử dụng Object.defineProperty() hoặc Object.getOwnPropertyDescriptor(). Điều này giúp bảo vệ dữ liệu trong Object khi lập trình.

Việc hiểu rõ các thuộc tính này giúp bạn quản lý Object tốt hơn, tránh lỗi không mong muốn và bảo vệ dữ liệu quan trọng!

Object.defineProperty()Object.defineProperties() trong JavaScript

JavaScript cho phép chúng ta kiểm soát chi tiết các thuộc tính của đối tượng bằng cách sử dụng hai phương thức quan trọng:

  • Object.defineProperty(object, property, descriptor): Dùng để định nghĩa hoặc thay đổi một thuộc tính với quyền kiểm soát cụ thể (writable, enumerable, configurable).
  • Object.defineProperties(object, descriptors): Dùng để định nghĩa nhiều thuộc tính cùng lúc với các quyền kiểm soát chi tiết.

Object.defineProperty()Tạo thuộc tính với kiểm soát chi tiết

Cú pháp:

Object.defineProperty(object, propertyName, descriptor);
  • object: Đối tượng cần thêm hoặc sửa đổi thuộc tính.
  • propertyName: Tên thuộc tính cần thêm hoặc chỉnh sửa.
  • descriptor: Một đối tượng chứa các thuộc tính mô tả (value, writable, enumerable, configurable).

Ví dụ cơ bản:

const user = {};  

// Định nghĩa thuộc tính 'name' với các thuộc tính mô tả cụ thể
Object.defineProperty(user, "name", {  
  value: "Alice",
  writable: false, // Không thể thay đổi giá trị
  enumerable: true, // Hiển thị khi duyệt
  configurable: false // Không thể xóa hoặc thay đổi cấu hình
});

console.log(user.name); // Output: Alice

user.name = "Bob"; // Không thể gán lại do writable: false
console.log(user.name); // Output: Alice

delete user.name; // Không thể xóa do configurable: false
console.log(user.name); // Output: Alice

Trong ví dụ trên:

  • writable: false: Ngăn không cho thay đổi giá trị.
  • enumerable: true: Cho phép thuộc tính xuất hiện khi duyệt qua Object.
  • configurable: false: Không thể xóa hoặc thay đổi mô tả thuộc tính.

Ví dụ về writable, enumerable, configurable

writable: false – Không thể thay đổi giá trị

const person = {};

Object.defineProperty(person, "age", {
  value: 30,
  writable: false // Không cho phép thay đổi giá trị
});

person.age = 40; // Không có tác dụng
console.log(person.age); // Output: 30

enumerable: false – Không thể duyệt qua for...in hoặc Object.keys()

const user = {
  username: "john_doe"
};

Object.defineProperty(user, "password", {
  value: "123456",
  enumerable: false // Ẩn khỏi vòng lặp
});

console.log(Object.keys(user)); // Output: ["username"]

configurable: false – Không thể xóa hoặc thay đổi mô tả thuộc tính

const car = {
  brand: "Toyota"
};

Object.defineProperty(car, "brand", {
  configurable: false // Không thể xóa hoặc thay đổi descriptor
});

delete car.brand; // Không thể xóa
console.log(car.brand); // Output: "Toyota"

Object.defineProperty(car, "brand", {
  enumerable: false // Lỗi: Cannot redefine property
});

Object.defineProperties() – khai báo nhiều thuộc tính cùng lúc

Nếu muốn tạo nhiều thuộc tính với mô tả chi tiết, chúng ta có thể sử dụng Object.defineProperties().

Cú pháp:

Object.defineProperties(object, {
  property1: { descriptor1 },
  property2: { descriptor2 },
  ...
});

Ví dụ:

const product = {};

Object.defineProperties(product, {
  name: {
    value: "Laptop",
    writable: false, // Không thể thay đổi
    enumerable: true
  },
  price: {
    value: 1500,
    writable: true, // Có thể thay đổi
    enumerable: true
  },
  stock: {
    value: 10,
    writable: true,
    enumerable: false // Không hiển thị khi duyệt
  }
});

console.log(product.name); // Output: Laptop
product.price = 1400;
console.log(product.price); // Output: 1400

console.log(Object.keys(product)); // Output: ["name", "price"]

Kết quả:

Duyệt qua các thuộc tính của Object trong JavaScript

Trong JavaScript, chúng ta có nhiều cách để duyệt qua các thuộc tính của một đối tượng (Object). Dưới đây là các phương pháp phổ biến để lấy danh sách thuộc tính, giá trị và kiểm tra sự tồn tại của thuộc tính.

Duyệt qua thuộc tính bằng vòng lặp

Sử dụng vòng lặp for...in để lặp qua các thuộc tính

Vòng lặp for...in được sử dụng để duyệt qua tất cả các thuộc tính có thể liệt kê (enumerable properties) của một đối tượng.

Cú pháp:

for (let key in object) {
  // Thực hiện hành động với từng key
}

Ví dụ:

const user = {
  name: "Alice",
  age: 25,
  city: "Hanoi"
};

for (let key in user) {
  console.log(`${key}: ${user[key]}`);
}

Output:

name: Alice
age: 25
city: Hanoi

Ưu điểm: Duyệt qua tất cả các thuộc tính có thể liệt kê.
Nhược điểm: Cũng duyệt qua các thuộc tính kế thừa từ prototype.

for (let key in user) {
  if (user.hasOwnProperty(key)) { // Chỉ lấy thuộc tính của chính đối tượng
    console.log(`${key}: ${user[key]}`);
  }
}

Lấy danh sách các thuộc tính và giá trị của Object trong JavaScript

Object.keys() – Lấy danh sách các key

Phương thức Object.keys(object) trả về một mảng chứa tất cả các key (thuộc tính) có thể liệt kê của đối tượng.

const user = {
  name: "Alice",
  age: 25,
  city: "Hanoi"
};

console.log(Object.keys(user)); 

Output:

["name", "age", "city"]

Ưu điểm: Trả về mảng chứa các thuộc tính, có thể dùng với .forEach() hoặc map().
Nhược điểm: Chỉ lấy các thuộc tính có thể liệt kê, không lấy thuộc tính symbol.

Object.values() – Lấy danh sách các value

Phương thức Object.values(object) trả về một mảng chứa tất cả các giá trị của thuộc tính có thể liệt kê.

console.log(Object.values(user)); 

Output:

["Alice", 25, "Hanoi"]

Ứng dụng: Có thể dùng để xử lý hoặc hiển thị danh sách giá trị một cách dễ dàng.

Object.entries() – Lấy danh sách key-value dưới dạng mảng

Phương thức Object.entries(object) trả về một mảng chứa các cặp [key, value], giúp dễ dàng duyệt qua từng thuộc tính và giá trị.

Ví dụ:

console.log(Object.entries(user));

Output:

[
  ["name", "Alice"],
  ["age", 25],
  ["city", "Hanoi"]
]

Duyệt qua Object.entries() bằng forEach():

Object.entries(user).forEach(([key, value]) => {
  console.log(`${key}: ${value}`);
});

Output:

name: Alice
age: 25
city: Hanoi

Ứng dụng: Hữu ích khi cần thao tác với cả key và value.

Kiểm tra sự tồn tại của thuộc tính trong JavaScript

Sử dụng in operator

Toán tử in giúp kiểm tra xem một thuộc tính có tồn tại trong đối tượng hay không.

console.log("name" in user); // Output: true
console.log("salary" in user); // Output: false

Lưu ý: in cũng kiểm tra các thuộc tính kế thừa từ prototype.

Sử dụng hasOwnProperty()

Phương thức hasOwnProperty(property) kiểm tra một thuộc tính có phải của đối tượng hay không (không tính các thuộc tính kế thừa).

console.log(user.hasOwnProperty("name")); // Output: true
console.log(user.hasOwnProperty("salary")); // Output: false

Ưu điểm: Không kiểm tra thuộc tính kế thừa như in.

Kết bài

Thuộc tính (Properties) là một phần quan trọng của Object trong JavaScript, giúp lưu trữ và quản lý dữ liệu một cách linh hoạt. Việc hiểu rõ cách khai báo, truy cập, cập nhật, xóa thuộc tính cũng như các phương pháp kiểm soát quyền hạn (writable, enumerable, configurable) sẽ giúp lập trình viên làm việc với Object hiệu quả hơn.

Ngoài ra, khi thao tác với thuộc tính Object, chúng ta cần lưu ý các lỗi thường gặp như truy cập thuộc tính không tồn tại, sử dụng sai phương thức kiểm tra thuộc tính, hoặc nhầm lẫn giữa thuộc tính riêng và thuộc tính kế thừa. Sử dụng các kỹ thuật như optional chaining (?.), hasOwnProperty(), in operator sẽ giúp giảm thiểu lỗi và cải thiện độ ổn định của ứng dụng.

Việc nắm vững các khái niệm về thuộc tính của Object không chỉ giúp code trở nên dễ đọc, dễ bảo trì mà còn tối ưu hiệu suất khi làm việc với dữ liệu trong JavaScript.

Bài viết liên quan

  • 2