プロパティの種類は2種類ある。
- データプロパティ・・・必ず値が格納される
- アクセッサプロパティ・・・値をもたない。そのかわり、getter,setterと呼ばれる関数を設定し、値の格納、取り出しを行う。
下記の場合、_name
がデータプロパティ。get name(), set name()
がアクセッサプロパティ。
js
//データプロパティ
const obj = {
name:'Tom',
show:function(){
console.log(name);
}
}
//アクセッサプロパティ
var obj2 = {
_name:'Tom',
get name(){
console.log('_nameを読み込みます');
return this._name;
},
set name(value){
console.log('_nameに'+value+'を書き込みます');
this._name = value;
}
};
//データプロパティ_nameにアクセス
console.log(obj2._name); //Tom
//getterにアクセス (値の取り出し)
obj2.name;
//'_nameを読み込みます。'
//'Tom'
//setterにアクセス(値の格納)
obj2.name = 'John';
//'_nameに'John'を書き込みます'
//'John'
obj2.name;
//'_nameを読み込みます。'
//'John'
プロパティアクセス
- プロパティへの、追加、変更、削除は以下の通り
- delete演算子を使う時、返り値は真偽値。削除成功ならばtrueが返る。
js
const obj = {
name:'Tom',
show:function(){
console.log(name);
}
}
//プロパティアクセス
obj.name; //'Tom' アクセス
obj.age = '18'; //追加
obj.name = 'John'; //変更
delete obj.name; //true 削除
delete演算子は、プロトタイプ継承したプロパティを削除できない。しかし演算結果はtrueが返る
js
function MyClass(x, y) {
this.x = x;
this.y = y;
}
MyClass.prototype.show = function() {
console.log(this.x, this.y);
}
const obj = new MyClass(2, 5);
delete obj.show //true
obj.show();
//2 5
//showメソッドは削除されず実行される
プロパティの存在チェック
方法 | 用途 |
---|---|
hasOwnProperty | プロトタイプ継承を除いた、プロパティの存在チェック。 |
Object.keys() | プロトタイプ継承を除いた、プロパティの存在チェック。 |
in 演算子 | プロトタイプ継承も含む、プロパティの存在チェック。 |
for(let keys in obj) | プロトタイプ継承も含む、プロパティの存在チェック。 |
js
obj.hasOwnProperty('x');
//true xプロパティが存在
const keys = Object.keys(obj);
console.log(keys);
//["x", "y"]
'show' in obj;
//true
for(let keys in obj) {
console.log(keys);
}
//"x" "y" "show"
プロパティの属性
属性名 | 意味 |
---|---|
writable | プロパティ値を書き換え可能 |
enumerable | for in文で列挙可能 |
configurable | 属性を変更可能。プロパティの削除可能 |
get | プロパティ値のゲッター関数を指定可能 |
set | プロパティ値のセッター関数を指定可能 |
Object.getOwnPropertyDescriptor(obj, prop);で取得可能
配列のlengthプロパティは、配列のインスタンスオブジェクトのプロパティに属している。(in 演算子でtrue)。そのため、forin文で回せば、配列自身のプロパティとして列挙されるはずである。しかし、現れない。それはenumerable属性がfalseのため。
js
const obj = {
name:'Tom',
show:function(){
console.log(name);
}
}
//プロパティの属性チェック
const prop = Object.getOwnPropertyDescriptor(obj, 'show');
console.log(prop);
//configurable:true
//enumerable:true
//value:ƒ ()
//writable:true
//__proto__:Object
//配列のlengthプロパティチェック
const arr = [0, 1, 3];
//in演算子でtrue
length in arr;
//true
//forin文で列挙されない
for(let keys in arr){
console.log(keys);
} //0 1 2
//プロパティの属性チェック
const arrProp = Object.getOwnPropertyDescriptor(arr, 'prop');
//configurable:false,
//enumerable:false,
//value:3,
//writable:true
不変オブジェクト
変数にはミュータブルな型とイミュータブルな型がある。
- イミュータブルな型とは変更不可なもの。基本型はイミュータブル。数値や文字列など。
- ミュータブルな型とは変更可なもの。ArrayオブジェクトやDateオブジェクトなどは変更可な型。
イミュータブルな型
これらは値が変更しているわけではなく、[num + 3]で新しく4という値を生成し、numに代入しているだけである。strも同じ。
js
var num = 1;
num = num + 3; // numの値は4
var str = "Hello"
str = str + " World" // (1)"Hello World"
ミュータブル型
array[0]の値が書き換え可能。
js
const array = [1, 3, 4];
array[0] = 5; // [5, 3, 4]
イミュータブルなオブジェクトをサポートする関数
上記のようなarrayオブジェクトを書き換え不可能にする関数がある。
メソッド名 | プロパティ追加 | プロパティ削除 | プロパティ変更 | 確認メソッド |
---|---|---|---|---|
preventExtensions | ☓ | ○ | ○ | Object.isExtensible |
Seal | ☓ | ☓ | ○ | Object.isSealed |
Freeze | ☓ | ☓ | ☓ | Object.isFrozen |
js
const array = [1, 3, 4];
//プロパティの追加だけを不可能にする
Object.preventExtensions(array);
array[1] = 20;
delete array[0];
array[3] = 10;
console.log(array);
//[undefined, 20, 4]