概要: このチュートリアルでは、JavaScriptオブジェクトのプロパティと、configurable、enumerable、writable、get、set、valueなどの属性について学習します。
オブジェクトのプロパティ型
JavaScriptは、[[Enumerable]]のように二重の角括弧で囲まれた内部属性を介して、オブジェクトのプロパティの特性を指定します。
オブジェクトには、データプロパティとアクセサプロパティの2種類のプロパティがあります。
1) データプロパティ
データプロパティには、データ値の単一の場所が含まれます。データプロパティには、4つの属性があります。
-
[[Configurable]]– プロパティがdelete演算子を介して再定義または削除できるかどうかを決定します。 -
[[Enumerable]]– プロパティがfor...inループで返されるかどうかを示します。 -
[[Writable]]– プロパティの値を変更できることを指定します。 -
[[Value]]– プロパティの実際の値を格納します。
デフォルトでは、オブジェクトに直接定義されたすべてのプロパティに対して、[[Configurable]]、[[Enumerable]]、および[[Writable]]属性はtrueに設定されます。[[Value]]属性のデフォルト値はundefinedです。
たとえば、次の例では、configurable、enumerable、およびwritable属性がtrueに設定され、それぞれの値が'John'と'Doe'に設定された、firstNameとlastNameの2つのプロパティを持つpersonオブジェクトを作成します。
let person = {
firstName: 'John',
lastName: 'Doe'
};Code language: JavaScript (javascript)プロパティの属性を変更するには、Object.defineProperty()メソッドを使用します。
Object.defineProperty()メソッドは、3つの引数を受け取ります。
- オブジェクト。
- オブジェクトのプロパティ名。
configurable、enumerable、writable、およびvalueの4つのプロパティを持つプロパティ記述子オブジェクト。
Object.defineProperty()メソッドを使用してオブジェクトのプロパティを定義する場合、特に指定がない限り、[[Configurable]]、[[Enumerable]]、および[[Writable]]のデフォルト値はfalseに設定されます。
次の例では、ageプロパティを持つpersonオブジェクトを作成します。
let person = {};
person.age = 25;Code language: JavaScript (javascript)[[Configurable]]属性のデフォルト値はtrueに設定されているため、delete演算子を使用して削除できます。
delete person.age;
console.log(person.age);Code language: CSS (css)出力
undefinedCode language: JavaScript (javascript)次の例では、Object.defineProperty()メソッドを使用して、ssnプロパティをpersonオブジェクトに追加します。
'use strict';
let person = {};
Object.defineProperty(person, 'ssn', {
configurable: false,
value: '012-38-9119'
});
delete person.ssn;Code language: JavaScript (javascript)出力
TypeError: Cannot delete property 'ssn' of #<Object>Code language: PHP (php)この例では、configurable属性がfalseに設定されています。したがって、ssnプロパティを削除するとエラーが発生します。
また、プロパティを非構成可能として定義すると、構成可能に変更することはできません。
Object.defineProperty()メソッドを使用して、writable以外の属性を変更すると、エラーが発生します。例:
'use strict';
let person = {};
Object.defineProperty(person, 'ssn', {
configurable: false,
value: '012-38-9119'
});
Object.defineProperty(person, 'ssn', {
configurable: true
});Code language: JavaScript (javascript)出力
TypeError: Cannot redefine property: ssnCode language: JavaScript (javascript)デフォルトでは、オブジェクトに定義されたすべてのプロパティのenumerable属性はtrueです。これは、次のようにfor...inループを使用して、すべてのオブジェクトプロパティを反復処理できることを意味します。
let person = {};
person.age = 25;
person.ssn = '012-38-9119';
for (let property in person) {
console.log(property);
}Code language: JavaScript (javascript)出力
age
ssn次の例では、enumerable属性をfalseに設定して、ssnプロパティを非列挙可能にします。
let person = {};
person.age = 25;
person.ssn = '012-38-9119';
Object.defineProperty(person, 'ssn', {
enumerable: false
});
for (let prop in person) {
console.log(prop);
}Code language: JavaScript (javascript)出力
age2) アクセサプロパティ
データプロパティと同様に、アクセサプロパティにも[[Configurable]]および[[Enumerable]]属性があります。
ただし、アクセサプロパティには、[[Value]]および[[Writable]]の代わりに[[Get]]および[[Set]]属性があります。
アクセサプロパティからデータを読み取ると、[[Get]]関数が自動的に呼び出されて値を返します。[[Get]]関数のデフォルトの戻り値はundefinedです。
アクセサプロパティに値を代入すると、[[Set]]関数が自動的に呼び出されます。
アクセサプロパティを定義するには、Object.defineProperty()メソッドを使用する必要があります。例:
let person = {
firstName: 'John',
lastName: 'Doe'
}
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);Code language: JavaScript (javascript)出力
'John Doe'Code language: JavaScript (javascript)この例では
- まず、
firstNameとlastNameの2つのプロパティを含むpersonオブジェクトを定義します。 - 次に、アクセサプロパティとして
fullNameプロパティをpersonオブジェクトに追加します。
fullnameアクセサプロパティでは
[[Get]]は、firstName、space、およびlastNameの連結の結果であるフルネームを返します。[[Set]]メソッドは、引数をスペースで分割し、名前の対応する部分のfirstNameプロパティとlastNameプロパティを代入します。- フルネームが正しい形式、つまり、ファーストネーム、スペース、ラストネームでない場合は、エラーをスローします。
複数のプロパティを定義する:Object.defineProperties()
ES5では、Object.defineProperties()メソッドを使用して、単一のステートメントで複数のプロパティを定義できます。例:
var product = {};
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');Code language: JavaScript (javascript)出力
The net price of a Smartphone is 878.90 USDCode language: CSS (css)この例では、productオブジェクトに、name、price、およびtaxの3つのデータプロパティと、1つのアクセサプロパティnetPriceを定義しました。
JavaScriptオブジェクトのプロパティ記述子
Object.getOwnPropertyDescriptor()メソッドを使用すると、プロパティの記述子オブジェクトを取得できます。Object.getOwnPropertyDescriptor()メソッドは、2つの引数を取ります。
- オブジェクト
- オブジェクトのプロパティ
プロパティを記述する記述子オブジェクトを返します。記述子オブジェクトには、configurable、enumerable、writable、およびvalueの4つのプロパティがあります。
次の例では、前の例のproductオブジェクトのnameプロパティの記述子オブジェクトを取得します。
let person = {
firstName: 'John',
lastName: 'Doe'
};
let descriptor = Object.getOwnPropertyDescriptor(person, 'firstName');
console.log(descriptor);Code language: JavaScript (javascript)出力
{ value: 'John',
writable: true,
enumerable: true,
configurable: true }Code language: CSS (css)まとめ
- JavaScriptオブジェクトには、データプロパティとアクセサプロパティの2種類のプロパティがあります。
- JavaScriptは、
[[Configurable]]、[[Enumerable]]、[[Writable]]、および[[Value]]、[[Get]]、[[Set]]などのプロパティの特性を記述するために、[[...]]と表記される内部属性を使用します。 Object.getOwnPropertyDescriptor()メソッドは、オブジェクト内のプロパティのプロパティ記述子を返します。- プロパティは、オブジェクトに直接定義するか、
Object.defineProperty()またはObject.defineProperties()メソッドを使用して間接的に定義できます。これらのメソッドは、プロパティの属性を変更するために使用できます。