fbpx

JavaScript Object Properties Và Những Điều Không Phải Ai Cũng Biết

object trong javascript

Trong bài viết này, mình sẽ giúp bạn có cái nhìn chi tiết hơn về object properties và các attributes của nó như là configurable, enumerable, writable, get, set và value.

Khi đã nắm vững các kiến thức này, mình tin chắc rằng bạn sẽ tự tin hơn khi làm việc với object trong JavaScript.

Cùng tìm hiểu nhé!

1. Các loại object property

JavaScript sử dụng internal attribute (attribute) để mô tả đặc điểm của một property.

Nếu bạn chưa biết object property là gì thì bạn có thể tham khảo bài viết này: https://letdiv.com/object-trong-javascript/

Có hai loại object property: data propertyaccessor property.

1.1 Data property

Data property là property mang một giá trị nào đó. Đây là loại property mà chúng ta hay thường xuyên sử dụng.

Example data property

Một data property bao gồm 4 attributes:

  • configurable – Xác định xem có thể định nghĩa lại hoặc xoá property thông qua toán tử delete hay không.
  • enumerable – Xác định xem property có thể được trả về trong vòng lặp for...in hay không.
  • writable – Chỉ định rằng có thể thay đổi giá trị của property hay không.
  • value – Là giá trị của property.

Mặc định, các attribute configurable, enumerablewritable đều có giá trị là true khi bạn định nghĩa property trực tiếp bên trong object. Giá trị mặc định của attribute valueundefined.

Mình biết là bạn sẽ cảm thấy khó hiểu khi đọc các định nghĩa trên. Đừng lo lắng! Thông qua các ví dụ bên dưới,  bạn sẽ hiểu rõ ngay, vì nó khá là đơn giản.

Sau đây, mình sẽ tạo object person có các property firstNamelastName.

let person = {
    firstName: 'Nguyen',
    lastName: 'Hung'
};

Lúc này, các attribute configurable, enumerablewritable của property firstNamelastName có giá trị mặc định là true.

Để thay đổi attribute của một property, mình sử dụng method Object.defineProperty().

Method Object.defineProperty() có 3 tham số:

  • Object chứa property cần định nghĩa.
  • Tên property.
  • Property descriptor – là object có 4 property configurable, enumerable, writablevalue.

Nếu mình sử dụng method Object.defineProperty() để định nghĩa một property, thì các attribute configurable, enumerablewritable có giá trị mặc định là false.

Đoạn code sau dùng để khởi tạo object person với property age:

let person = {};
person.age = 25;

Bởi vì configurable có giá trị mặc định là true, mình có thể xoá property thông qua toán tử delete:

delete person.age;
console.log(person.age);

Output:

undefined

Ở ví dụ tiếp theo, mình sẽ tạo một object person và định nghĩa property ssn bằng cách sử dụng method Object.defineProperty():

'use strict';

let person = {};
Object.defineProperty(person, 'ssn', {
    configurable: false,
    value: '012-38-9119'
});
delete person.ssn;

Output:

TypeError: Cannot delete property 'ssn' of #<Object>

Qua đoạn code trên, bạn thấy rằng attribute configurable có giá trị là false. Do đó, khi delete property ssn thì chương trình sẽ báo lỗi.

Bên cạnh đó, nếu attribute configurable có giá trị là false, thì property này không thể định nghĩa lại bằng method Object.defineProperty().

'use strict';

let person = {};
Object.defineProperty(person, 'ssn', {
    configurable: false,
    value: '012-38-9119'
});


Object.defineProperty(person, 'ssn', {
    configurable: true
});

Output:

TypeError: Cannot redefine property: ssn

Khi định nghĩa property trực tiếp bên trong object thì enumerable mặc định là true. Điều này có nghĩa là mình có thể sử dụng vòng lặp for...in để duyệt qua property đó. Ví dụ:

let person = {};
person.age = 25;
person.ssn = '012-38-9119';

for (let prop in person) {
    console.log(prop);
}

Output:

age
ssn

Sau đây, mình sẽ chuyển giá trị attribute enumerable của property ssn trở thành false.

let person = {};
person.age = 25;
person.ssn = '012-38-9119';

Object.definedProperty(person, 'ssn', {
    enumerable: false
});
for (let prop in person) {
    console.log(prop);
}

Output:

age

1.2 Accessor property

Một accessor property bao gồm 4 attributes:

  • configurable – Xác định xem có thể định nghĩa lại hoặc xoá property thông qua toán tử delete hay không.
  • enumerable – Xác định xem property có thể được trả về trong vòng lặp for...in hay không.
  • get – Trả về giá trị cho property.
  • set – Thiết lập giá trị cho property.

Tương tự như data property, accessor property cũng có các attribute configurableenumerable.

Nhưng accessor property không có các property valuewritable, thay vào đó là các property getset.

Khi bạn muốn lấy giá trị của accessor property, function get sẽ được gọi tự động và trả về giá trị. Giá trị trả về mặc định của function getundefined.

Nếu bạn gán giá trị cho accessor property, function set sẽ được gọi tự động.

Để định nghĩa một accessor property, bạn phải sử dụng method Object.defineProperty(). Ví dụ:

let person = {
    firstName: 'Nguyen',
    lastName: 'Hung'
};

Object.defineProperty(person, 'fullname', {
    get: function () {
        return this.firstName + ' ' + this.lastName;
    },
    set: function (value) {
        let parts = value.split(' ');
        if (parts.length == 2) {
            this.firstName = parts[0];
            this.lastName = parts[1];
        } else {
            throw 'Invalid name format';
        }
    }
});

console.log(person.fullName);

Output:

'Nguyen Hung'

Ở ví dụ trên:

  • Đầu tiên, mình đã khởi tạo object person với hai property: firstNamelastName.
  • Sau đó, mình thêm accessor property là fullname.
  • Function get trả về kết quả là tên đầy đủ bằng cách nối firstNamelastName lại với nhau.
  • Function set split tham số truyền vào và gán lại giá trị tương ứng cho property firstNamelastName. Nếu tham số truyền vào không đúng format thì chương trình sẽ báo lỗi.

2. Dùng Object.defineProperties để định nghĩa nhiều property

Trong phiên bản ES5, bạn có thể định nghĩa nhiều property cùng một lúc thông qua method Object.defineProperties(). Ví dụ:

Object.defineProperties(product, {
    name: {
        value: 'Smartphone'
    },
    price: {
        value: 799
    },
    tax: {
        value: 0.1
    },
    netPrice: {
        get: function () {
            return this.price * (1 + this.tax);
        }
    }
});

console.log('The net price of a ' + product.name + ' is ' + product.netPrice.toFixed(2) + ' USD');

Output:

The net price of a Smartphone is 878.90 USD

Ở ví dụ trên, mình đã định nghĩa 3 data property name, pricetax và 1 accessor property netPrice cho product object.

3. Property descriptor

Method Object.getOwnPropertyDescriptor() cho phép bạn lấy các thông tin attribute của một property. Giá trị method này trả về được gọi là property descriptor (descriptor).

Method Object.getOwnPropertyDescriptor() bao gồm hai tham số:

  • Object tương ứng.
  • Tên property của object
let person = {
    firstName: 'Nguyen',
    lastName: 'Hung'
}

let descriptor = Object.getOwnPropertyDescriptor(person, 'firstName');
console.log(descriptor);

Output:

{ value: 'Nguyen',
  writable: true,
  enumerable: true,
  configurable: true }

4. Ghi nhớ

  • Object trong JavaScript có hai loại property: data property và accessor property.
  • Data property có các attribute: configurable, enumerable, writablevalue.
  • Accessor property có các attribute: configurable, enumerable, getset.
  • Có thể định nghĩa property trực tiếp trong object hoặc gián tiếp thông qua method Object.defineProperty() hoặc Object.definedProperties(). Những method này cũng có thể được dùng để thay đổi attribute của một property.
  • Method Object.getOwnPropertyDesciptor() dùng để trả về property descriptor của một property.

Tham Gia Cộng Đồng Học Lập Trình Thật Dễ!

Nếu bạn quan tâm đến ngành lập trình, và muốn tìm hiểu những kiến thức bổ ích khác, hãy tham gia ngay cộng đồng Học Lập Trình Thật Dễ nhé!

https://letdiv.com/tham-gia-cong-dong-hoc-lap-trinh-that-de/
Tùng ViO

Tùng ViO

Mình là Tùng ViO, hiện tại đang là Founder và cũng là giảng viên tại LetDiv. Rất hân hạnh được làm quen với bạn!