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 property và accessor 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.
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ặpfor...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
, enumerable
và writable
đề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 value
là undefined
.
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 firstName
và lastName
.
let person = { firstName: 'Nguyen', lastName: 'Hung' };
Lúc này, các attribute configurable
, enumerable
và writable
của property firstName
và lastName
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
,writable
vàvalue
.
Nếu mình sử dụng method Object.defineProperty()
để định nghĩa một property, thì các attribute configurable
, enumerable
và writable
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ặpfor...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 configurable
và enumerable
.
Nhưng accessor property không có các property value
và writable
, thay vào đó là các property get
và set
.
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 get
là undefined
.
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:firstName
vàlastName
. - 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ốifirstName
vàlastName
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 propertyfirstName
vàlastName
. 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
, price
và tax
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
,writable
vàvalue
. - Accessor property có các attribute:
configurable
,enumerable
,get
vàset
. - 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ặcObject.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é!