Object オブジェクトのPart 1に続き、Part 2です!
Object.create(prototype, プロパティー達)
var obj = {}; // Object.create(Object.prototype)と同じ意味となります
var obj2 = Object.create(null, {
a: {
writable: true,
configurable: false,
value: 5,
}
});
obj2.a; // 5
createの意味通り、オブジェクトを生成する方法の一つです!
プロパティー達のところのオプションにはwritable、 configurable、 enumerable、 get、 set、 value
があり、詳しい話は下記のdefineProperties
を見てください!
Object.defineProperties(オブジェクト, プロパティー達)、 Object.defineProperty(オブジェクト, プロパティー, 説明)
var obj = {};
Object.defineProperties(obj, {
a: {
writable: false,
enumerable: true,
value: 5,
},
b: {
get: function() {
return 'yuchan';
},
set: function(value) {
console.log(this.value);
this.a = value;
},
enumerable: false,
configurable: false,
},
});
obj.a; // 5
obj.b; // 'yuchan'
obj.a = 10;
obj.a; // 5 <-- writableがfalseなため更新されてない
for (var key in obj) {
console.log(key);
}; // a undefined <-- bはenumerableがfalseなためlogには出力されない!
obj.b = 15; // 15に更新される代わりsetの内容が実行されるsetのvalueは15となる
obj.a; // 5 <-- this.a = valueにより15に更新されるベキだが、writableがfalseなためそのまま
obj.b; // 'yuchan'
Object.defineProperty(obj, 'b', {
value: 5
}); // Uncaught TypeError: Cannot redefine property <-- configurableがfalseなため再定義できない
オブジェクトのプロパティーを詳しく定義できます!
writable
はプロパティーの値を更新できるかどうか、enumerable
はfor..in
ループ文内で使用できるか、configurable
はプロパティーの説明を更新できるかを設定できます。falseの場合はdelete
での削除もできなくなります。デフォルト値としてwritable、 enumerable、 configurable
はfalse
となっております。value
はプロパティーの値、get
はプロパティーの値を取得する時、set
はプロパティーの値を設定の時を意味します!
writable
はプロパティーの値が更新されることを防ぎますが、値がオブジェクトの場合はそのオブジェクト内のプロパティーが更新されるのは防げません!
これを防ぐには後で紹介するObject.freeze
というメソッドがあります。
Object.defineProperty(obj, 'c', {
value: { x: 3, y: 4 },
writable: false,
enumerable: true,
});
obj.c; // { x: 3, y: 4 }
obj.c = 'yuchan';
obj.c = // { x: 3, y: 4 }
obj.c.x = 5;
obj.c = // { x: 5, y: 4 } <-- writableがfalseでもオブジェクト内のプロパティーは更新できる
Object.getOwnPropertyDescriptor(オブジェクト, プロパティー)
Object.getOwnPropertyDescriptor(obj, 'b'); // {enumerable: false, configurable: false, get: ƒ, set: ƒ}
プロパティーの説明を取得できます!
Object.freeze
var frozenObj = Object.freeze(obj);
frozenObj.a = 10;
frozenObj.a; // 5
delete frozenObj.c; // false
Object.freeze(obj.c); // これで内部のオブジェクトも完全に更新を防げる
上記の例で、writable
がfalse
でも値がオブジェクトなら、そのオブジェクトのプロパティーまでは更新できることがわかりました。
ここで、Object.freeze
を使えばオブジェクト全体を更新できないように固定できます!
値も更新できず、プロパティーの追加および削除もできず、プロパティーの説明も更新できません!
Object.seal
var sealedObj = Object.seal(obj);
sealedObj.a = 10;
sealedObj.a; // 5 <-- writableがtrueなら10に更新されていた
delete sealedObj.c; // false
seal
の場合プロパティーの追加および削除はできず、configurable
がfalse
に変更されます。
代わりにfreeze
と違ってプロパティーの値はwritable
がtrue
なら更新できます!
Object.preventExtensions
var nonExtensible = Object.preventExtensions(obj);
nonExtensible.d = 'new';
nonExtensible.d; // undefined
プロパティーの追加だけ防ぎたい時に使うのがこのObject.preventExtensions
です!
その他のプロパティーの削除や値の更新、オブション設定の更新などは可能です。
Object.keys
Object.keys(obj); // ['a', 'c'] <-- 'b'はenumerableがfalseなため除かれている
こちらはよく目にするメソッドですよね!
オブジェクトでenumerable
がfalse
のプロパティーを除いたプロパティーを全て持ってきて、そのまま配列に変えてくれます!
typeof
var a = 1;
var b = 'yuchan';
var c = true;
var d = {};
var e = [];
var f = function() {};
var g;
var h = null;
typeof a; // 'number'
typeof b; // 'string';
typeof c; // 'boolean';
typeof d; // 'object';
typeof e; // 'object';
typeof f; // 'function';
typeof g; // 'undefined'
typeof h; // 'object';
対象の型を確認する時に使用します!
しかし、配列とnull
もobject
という型で表示されるため、配列を見分けるためにはArray.isArray
メソッドを使用して、nullを見分けるためには別の処理が必要になってきます。(null
もobject
になるのは流石にJavaScript側のミスかなと思いますw)
delete
var obj = {
a: 'hi',
b: 'yuchan',
};
obj.b; // yuchan
delete obj.b;
obj.b; // undefined
オブジェクト内のプロパティーを削除できます!
成功すればtrue
を失敗したらfalse
を返します。
先ほども書きましたが、configurable
がfalse
かObject.freeze
でオブジェクトが固定されている状態であれば失敗します。