0
0

[JS] なんとなく分かった気になっているJSをはっきりしておく ~ Object オブジェクト Part 2 ~

Posted at

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はプロパティーの値を更新できるかどうか、enumerablefor..inループ文内で使用できるか、configurableはプロパティーの説明を更新できるかを設定できます。falseの場合はdeleteでの削除もできなくなります。デフォルト値としてwritable、 enumerable、 configurablefalseとなっております。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); // これで内部のオブジェクトも完全に更新を防げる

上記の例で、writablefalseでも値がオブジェクトなら、そのオブジェクトのプロパティーまでは更新できることがわかりました。

ここで、Object.freezeを使えばオブジェクト全体を更新できないように固定できます!
値も更新できず、プロパティーの追加および削除もできず、プロパティーの説明も更新できません!

Object.seal

var sealedObj = Object.seal(obj);
sealedObj.a = 10;
sealedObj.a; // 5 <-- writableがtrueなら10に更新されていた
delete sealedObj.c; // false

sealの場合プロパティーの追加および削除はできず、configurablefalseに変更されます。

代わりにfreezeと違ってプロパティーの値はwritabletrueなら更新できます!

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なため除かれている

こちらはよく目にするメソッドですよね!
オブジェクトでenumerablefalseのプロパティーを除いたプロパティーを全て持ってきて、そのまま配列に変えてくれます!

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';

対象の型を確認する時に使用します!
しかし、配列とnullobjectという型で表示されるため、配列を見分けるためにはArray.isArrayメソッドを使用して、nullを見分けるためには別の処理が必要になってきます。(nullobjectになるのは流石にJavaScript側のミスかなと思いますw)

delete

var obj = {
  a: 'hi',
  b: 'yuchan',
};
obj.b; // yuchan
delete obj.b;
obj.b; // undefined

オブジェクト内のプロパティーを削除できます!
成功すればtrueを失敗したらfalseを返します。

先ほども書きましたが、configurablefalseObject.freezeでオブジェクトが固定されている状態であれば失敗します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0