Objectオブジェクト

編集

Objectオブジェクトは、StringNumberなど他のオブジェクトの雛形として利用される基本的なオブジェクトです。

JavaScriptでは、ほぼすべてのデータ型がObject型を継承しています。

Objectの型

編集

以下のコードで、Objectや他の組み込みオブジェクトの型について確認できます。

console.log(`Objectの型
typeof Object => ${typeof Object}
typeof String => ${typeof String}
typeof Number => ${typeof Number}
typeof Function => ${typeof Function}

Object === Object.prototype.constructor => ${Object === Object.prototype.constructor}
String === String.prototype.constructor => ${String === String.prototype.constructor}
Number === Number.prototype.constructor => ${Number === Number.prototype.constructor}
Function === Function.prototype.constructor => ${Function === Function.prototype.constructor}
`)

実行結果

編集

上記のコードを実行すると、以下の結果が得られます:

Objectの型
typeof Object => function
typeof String => function
typeof Number => function
typeof Function => function

Object === Object.prototype.constructor => true
String === String.prototype.constructor => true
Number === Number.prototype.constructor => true
Function === Function.prototype.constructor => true

解説

編集
  • Objectの型はfunctionです。これは、Objectだけでなく、StringNumber、さらにはFunctionも同様に型がfunctionであることを示しています。
  • このことから、これらは関数であり、それぞれが自身のオブジェクトを生成するためのコンストラクタ(constructor)であることがわかります。

静的プロパティ

編集

Object.length

編集

コンストラクターとしてのパラメーター数。

1
number

Object.name

編集

型名。

"Object"
string

Object.prototype

編集

一般的なオブジェクトは、Object.prototypeからプロパティ(メソッドを含む)を継承しますが、これらのプロパティはシャドウイング(別名オーバーライド)されることがあります。 しかし、Object.create(null)のように意図的に継承されていないオブジェクトを作成したり、Object.setPrototypeOfのように継承されていないオブジェクトを変更することもできます。

静的メソッド

編集

Object の静的メソッドは、オブジェクトの構造や振る舞いを制御し、安全に操作するために必要です。これにより、プロトタイプの管理、プロパティの列挙や保護、動的な性質を持つJavaScriptの一貫性を保ちながら柔軟に対応できます。

また、Object の静的メソッドが使われる大きな理由は名前の衝突を避けるためです。もしプロトタイプにインスタンスメソッドを追加すると、既存のフレームワークやライブラリで同じ名前のメソッドが使われている場合に衝突が発生し、互換性の問題を引き起こします。

例えば、Array.prototype.groupBy をインスタンスメソッドとして追加した場合、古いライブラリが独自に groupBy を定義していると、その動作に影響を与えます。このため、標準的な操作やユーティリティ的な機能は静的メソッドとして定義され、既存のプロトタイプを汚染しないように設計されています。

Object.assign()

編集

1つ以上のソースオブジェクトから、ターゲットオブジェクトにプロパティをコピーします。

構文
Object.assign(target, ...sources)
パラメータ
  • target: プロパティのコピー先となるオブジェクト
  • sources: プロパティのコピー元となる1つ以上のオブジェクト
戻り値
  • 変更されたターゲットオブジェクト
const target = { a: 1 };
const source = { b: 2, c: 3 };
const result = Object.assign(target, source);
console.log(result); // { a: 1, b: 2, c: 3 }

Object.create()

編集

指定されたプロトタイプオブジェクトとプロパティを持つ新しいオブジェクトを生成します。

構文
Object.create(proto[, propertiesObject])
パラメータ
  • proto: 新しいオブジェクトのプロトタイプとなるオブジェクト
  • propertiesObject: 新しいオブジェクトに追加するプロパティを指定するオブジェクト(省略可能)
戻り値
  • 指定されたプロトタイプとプロパティを持つ新しいオブジェクト
const person = {
    sayHello() {
        console.log('Hello!');
    }
};

const john = Object.create(person, {
    name: {
        value: 'John',
        writable: true
    }
});

john.sayHello(); // "Hello!"
console.log(john.name); // "John"

Object.defineProperties()

編集

オブジェクトに複数の新しいプロパティを定義するか、既存のプロパティを変更します。

構文
Object.defineProperties(obj, props)
パラメータ
  • obj: プロパティを定義または修正するオブジェクト
  • props: 新しいプロパティ記述子を含むオブジェクト
戻り値
  • 変更されたオブジェクト
const obj = {};
Object.defineProperties(obj, {
    name: {
        value: 'John',
        writable: true
    },
    age: {
        value: 30,
        writable: false
    }
});

Object.defineProperty()

編集

オブジェクトに新しいプロパティを定義するか、既存のプロパティを変更します。

構文
Object.defineProperty(obj, prop, descriptor)
パラメータ
  • obj: プロパティを定義または修正するオブジェクト
  • prop: 定義または修正するプロパティ名
  • descriptor: プロパティの記述子
戻り値
  • 変更されたオブジェクト
const obj = {};
Object.defineProperty(obj, 'name', {
    value: 'John',
    writable: false,
    enumerable: true,
    configurable: true
});

Object.entries()

編集

オブジェクトの列挙可能なプロパティの [key, value] ペアの配列を返します。

構文
Object.entries(obj)
パラメータ
  • obj: 変換するオブジェクト
戻り値
  • 文字列キーを持つ列挙可能なプロパティの [key, value] ペアの配列
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.entries(obj));
// [['a', 1], ['b', 2], ['c', 3]]

Object.freeze()

編集

オブジェクトを凍結し、プロパティの追加、削除、変更を防ぎます。

構文
Object.freeze(obj)
パラメータ
  • obj: 凍結するオブジェクト
戻り値
  • 凍結されたオブジェクト
const obj = { prop: 42 };
Object.freeze(obj);
obj.prop = 33; // 厳格モードでエラー
console.log(obj.prop); // 42

Object.fromEntries()

編集

[key, value] ペアのリストからオブジェクトを生成します。

構文
Object.fromEntries(iterable)
パラメータ
  • iterable: [key, value] ペアを含むイテラブルオブジェクト
戻り値
  • 新しいオブジェクト
const entries = [['a', 1], ['b', 2], ['c', 3]];
const obj = Object.fromEntries(entries);
console.log(obj); // { a: 1, b: 2, c: 3 }

Object.getOwnPropertyDescriptor()

編集

オブジェクトの指定されたプロパティの記述子を返します。

構文
Object.getOwnPropertyDescriptor(obj, prop)
パラメータ
  • obj: 対象のオブジェクト
  • prop: プロパティ名
戻り値
  • プロパティ記述子オブジェクト
const obj = { name: 'John' };
const descriptor = Object.getOwnPropertyDescriptor(obj, 'name');
console.log(descriptor);
// {
//   value: 'John',
//   writable: true,
//   enumerable: true,
//   configurable: true
// }

Object.getOwnPropertyDescriptors()

編集

オブジェクトのすべての独自プロパティの記述子を返します。

構文
Object.getOwnPropertyDescriptors(obj)
パラメータ
  • obj: 対象のオブジェクト
戻り値
  • すべてのプロパティ記述子を含むオブジェクト
const obj = {
    name: 'John',
    get age() { return 30; }
};
console.log(Object.getOwnPropertyDescriptors(obj));

Object.getOwnPropertyNames()

編集

オブジェクトの独自プロパティ名の配列を返します。

構文
Object.getOwnPropertyNames(obj)
パラメータ
  • obj: 対象のオブジェクト
戻り値
  • プロパティ名の配列
const obj = { a: 1, b: 2 };
Object.defineProperty(obj, 'c', { enumerable: false });
console.log(Object.getOwnPropertyNames(obj));
// ['a', 'b', 'c']

Object.getOwnPropertySymbols()

編集

オブジェクトのすべてのSymbolプロパティを返します。

構文
Object.getOwnPropertySymbols(obj)
パラメータ
  • obj: 対象のオブジェクト
戻り値
  • Symbolプロパティの配列
const sym = Symbol('mySymbol');
const obj = { [sym]: 'value' };
console.log(Object.getOwnPropertySymbols(obj));
// [Symbol(mySymbol)]

Object.getPrototypeOf()

編集

指定されたオブジェクトのプロトタイプを返します。

構文
Object.getPrototypeOf(obj)
パラメータ
  • obj: プロトタイプを取得するオブジェクト
戻り値
  • 指定されたオブジェクトのプロトタイプ
const prototype = { x: 10 };
const obj = Object.create(prototype);
console.log(Object.getPrototypeOf(obj) === prototype); // true

Object.groupBy()

編集

反復可能なオブジェクトの要素をグループ化します。

構文
Object.groupBy(items, callbackFn)
パラメータ
  • items: グループ化する要素を含むイテラブル
  • callbackFn: 各要素のグループを決定するコールバック関数
戻り値
  • グループ化されたオブジェクト
const inventory = [
    { name: 'apple', type: 'fruit' },
    { name: 'carrot', type: 'vegetable' }
];
const grouped = Object.groupBy(inventory, item => item.type);
console.log(grouped);
// {
//   fruit: [{ name: 'apple', type: 'fruit' }],
//   vegetable: [{ name: 'carrot', type: 'vegetable' }]
// }

Object.hasOwn()

編集

オブジェクトが指定されたプロパティを独自のプロパティとして持っているかを判定します。

構文
Object.hasOwn(obj, prop)
パラメータ
  • obj: 検査するオブジェクト
  • prop: プロパティ名
戻り値
  • プロパティを持っている場合は true、そうでない場合は false
const obj = { prop: 42 };
console.log(Object.hasOwn(obj, 'prop')); // true
console.log(Object.hasOwn(obj, 'toString')); // false

Object.is()

編集

2つの値が同じ値であるかを判定します。

構文
Object.is(value1, value2)
パラメータ
  • value1: 比較する最初の値
  • value2: 比較する2番目の値
戻り値
  • 2つの値が同じ場合は true、そうでない場合は false
console.log(Object.is(0, -0)); // false
console.log(Object.is(NaN, NaN)); // true
console.log(Object.is({}, {})); // false

Object.isExtensible()

編集

オブジェクトに新しいプロパティを追加できるかどうかを判定します。

構文
Object.isExtensible(obj)
パラメータ
  • obj: 検査するオブジェクト
戻り値
  • オブジェクトが拡張可能な場合は true、そうでない場合は false
const obj = {};
console.log(Object.isExtensible(obj)); // true
Object.freeze(obj);
console.log(Object.isExtensible(obj)); // false

Object.isFrozen()

編集

オブジェクトが凍結されているかどうかを判定します。

構文
Object.isFrozen(obj)
パラメータ
  • obj: 検査するオブジェクト
戻り値
  • オブジェクトが凍結されている場合は true、そうでない場合は false
const obj = { prop: 42 };
console.log(Object.isFrozen(obj)); // false
Object.freeze(obj);
console.log(Object.isFrozen(obj)); // true

Object.isSealed()

編集

オブジェクトがシールされているかどうかを判定します。

構文
Object.isSealed(obj)
パラメータ
  • obj: 検査するオブジェクト
戻り値
  • オブジェクトがシールされている場合は true、そうでない場合は false
const obj = { prop: 42 };
console.log(Object.isSealed(obj)); // false
Object.seal(obj);
console.log(Object.isSealed(obj)); // true

Object.keys()

編集

オブジェクトの列挙可能なプロパティ名の配列を返します。

構文
Object.keys(obj)
パラメータ
  • obj: プロパティを取得するオブジェクト
戻り値
  • 文字列の配列
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.keys(obj)); // ['a', 'b', 'c']

Object.preventExtensions()

編集

オブジェクトに新しいプロパティが追加されるのを防ぎます。

構文
Object.preventExtensions(obj)
パラメータ
  • obj: 拡張を防止するオブジェクト
戻り値
  • 拡張が防止されたオブジェクト
const obj = { prop: 42 };
Object.preventExtensions(obj);
obj.newProp = 123; // 厳格モードでエラー
console.log(obj.newProp); // undefined

Object.seal()

編集

オブジェクトをシールし、プロパティの追加や削除を防ぎます。

構文
Object.seal(obj)
パラメータ
  • obj: シールするオブジェクト
戻り値
  • シールされたオブジェクト
const obj = { prop: 42 };
Object.seal(obj);
obj.newProp = 123; // 厳格モードでエラー
delete obj.prop; // 厳格モードでエラー
obj.prop = 123; // 可能

Object.setPrototypeOf()

編集

オブジェクトのプロトタイプを設定します。

構文
Object.setPrototypeOf(obj, prototype)
パラメータ
  • obj: プロトタイプを変更するオブジェクト
  • prototype: 新しいプロトタイプオブジェクトまたは null
戻り値
  • プロトタイプが変更されたオブジェクト
const obj = { a: 1};
const prototype = { b: 2 };
Object.setPrototypeOf(obj, prototype);
console.log(obj.b); // 2

Object.values()

編集

オブジェクトの列挙可能なプロパティの値の配列を返します。

構文
Object.values(obj)
パラメータ
  • obj: 値を取得するオブジェクト
戻り値
  • 値の配列
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.values(obj)); // [1, 2, 3]

const str = 'hello';
console.log(Object.values(str)); // ['h', 'e', 'l', 'l', 'o']

メソッドの使用例と注意点

編集

オブジェクトのディープクローン

編集
function deepClone(obj) {
    // プリミティブ値の場合はそのまま返す
    if (obj === null || typeof obj !== 'object') return obj;
    
    // 新しいオブジェクトを作成
    const clone = Array.isArray(obj) ? [] : {};
    
    // プロパティをディープコピー
    Object.entries(obj).forEach((<code>[key, value]</code>) => {
        clone[key] = deepClone(value);
    });
    
    return clone;
}

const original = {
    a: 1,
    b: { c: 2 },
    d: [3, 4, { e: 5 }]
};

const cloned = deepClone(original);
console.log(cloned); // originalと同じ構造を持つ新しいオブジェクト

オブジェクトの不変性の実装

編集
const config = {
    apiKey: 'secret123',
    endpoints: {
        users: '/api/users',
        posts: '/api/posts'
    }
};

// オブジェクトを完全に不変にする
const frozenConfig = Object.freeze(config);

// ネストされたオブジェクトも含めて完全に不変にする
function deepFreeze(obj) {
    // プリミティブ値の場合は何もしない
    if (obj === null || typeof obj !== 'object') return obj;
    
    // まず自身のプロパティを凍結
    Object.freeze(obj);
    
    // 再帰的に全てのプロパティを凍結
    Object.values(obj).forEach(deepFreeze);
    
    return obj;
}

const immutableConfig = deepFreeze(config);

プロパティの詳細な制御

編集
const user = {};

// getter/setterを使用したプロパティの定義
Object.defineProperty(user, 'fullName', {
    get() {
        return `${this.firstName} ${this.lastName}`;
    },
    set(value) {
        [this.firstName, this.lastName] = value.split(' ');
    }
});

// 複数のプロパティを一度に定義
Object.defineProperties(user, {
    age: {
        value: 30,
        writable: true,
        enumerable: true
    },
    id: {
        value: 'user123',
        writable: false,
        enumerable: false
    }
});

user.fullName = 'John Doe';
console.log(user.fullName); // "John Doe"

性能に関する注意点

編集
  • Object.freeze()やObject.seal()は、大きなオブジェクトに対して使用すると性能に影響を与える可能性があります。
  • Object.keys()、Object.values()、Object.entries()は、大きなオブジェクトに対して頻繁に呼び出す場合、キャッシュを検討してください。
  • Object.defineProperty()による動的なプロパティの定義は、直接プロパティを設定するよりも若干遅くなる可能性があります。

互換性に関する注意点

編集
  • Object.groupBy()は比較的新しいメソッドで、すべての環境でサポートされているわけではありません。
  • プロキシやリフレクションAPIと組み合わせる場合は、追加の互換性チェックが必要になる場合があります。

インスタンスメソッド

編集

Object.prototype.__defineGetter__()

編集
構文
obj.__defineGetter__(prop, func)

オブジェクトの指定されたプロパティにゲッタ関数を定義します。非推奨とされており、Object.defineProperty()の使用が推奨されます。

Object.prototype.__defineSetter__()

編集
構文
obj.__defineSetter__(prop, func)

オブジェクトの指定されたプロパティにセッタ関数を定義します。非推奨とされており、Object.defineProperty()の使用が推奨されます。

Object.prototype.__lookupGetter__()

編集
構文
obj.__lookupGetter__(prop)

指定されたプロパティに関連付けられたゲッタ関数を取得します。非推奨とされており、新しいコードでは使用を避けるべきです。

Object.prototype.__lookupSetter__()

編集
構文
obj.__lookupSetter__(prop)

指定されたプロパティに関連付けられたセッタ関数を取得します。非推奨とされており、新しいコードでは使用を避けるべきです。

Object.prototype.constructor

編集
構文
obj.constructor

オブジェクトを構築した関数を返します。オブジェクトのプロトタイプチェーンを確認する際に役立ちます。

Object.prototype.hasOwnProperty()

編集
構文
obj.hasOwnProperty(prop)

オブジェクトが指定されたプロパティを直接所有しているかどうかを判定します。

Object.prototype.isPrototypeOf()

編集
構文
obj.isPrototypeOf(object)

指定されたオブジェクトが、自身のプロトタイプチェーンに含まれているかどうかを判定します。

Object.prototype.propertyIsEnumerable()

編集
構文
obj.propertyIsEnumerable(prop)

オブジェクトの指定されたプロパティが列挙可能かどうかを判定します。

Object.prototype.toLocaleString()

編集
構文
obj.toLocaleString()

オブジェクトをロケールに依存した文字列表現に変換します。通常はtoString()メソッドを呼び出しますが、ロケール固有の動作を実装することも可能です。

Object.prototype.toString()

編集
構文
obj.toString()

オブジェクトを文字列表現に変換します。通常は[object Type]の形式で返されます。 toString()メソッドは、オブジェクトを表す文字列を返します[1]。 すべてのオブジェクトは toString() メソッドを持っています。このメソッドは、オブジェクトがテキスト値として表現される場合や、文字列が期待される方法でオブジェクトが参照される場合に、自動的に呼び出されます。デフォルトでは、toString()メソッドは、Objectの子孫であるすべてのオブジェクトに継承されます。カスタム・オブジェクトでこのメソッドがオーバーライドされていない場合、toString() は "[object type]" を返し、type はオブジェクト・タイプです。以下のコードで説明します。

Object.prototype.valueOf()

編集

オブジェクトのプリミティブ値を返します。

構文
obj.valueOf()
戻り値
  • オブジェクトのプリミティブ値
const num = new Number(123);
console.log(num.valueOf()); // 123

const str = new String("hello");
console.log(str.valueOf()); // "hello"

Object.prototype.toLocaleString()

編集

基本的にtoStringと全く同じ動作を行う。 このメソッドは、ArrayやNumber、Date型のオブジェクトがtoLocaleStringを持っているのに対し、他のオブジェクトはこれを持っていないため、他の型でtoLocaleStringが呼び出される場合でもエラー出してプログラムの実行が止まらないための雛形として用意されています。 他のデータ型でtoLocaleStringを使うべき問題にあたった場合にそれぞれのデータ型でメソッドを定義してやればよい。

Object.prototype.hasOwnProperty(V)

編集

オブジェクトが引数で渡したプロパティを自前で持っているかをチェックする。持っていない場合、および他のクラスから継承している場合はfalseを返す。

for~in文は通常、オブジェクトにプロパティやメソッドを追加したときにその違いが出る。 例えば次の様なオブジェクトを作成したとする。

Object.prototype.getBMI = function(){ return this[体重] / this[身長] ** 2 }
const girl ={
  身長: 158,
  体重: 49
};
for (const p in girl)
  console.log(p, ' : ', girl[p]); 
/*
 身長  :  158
 体重  :  49
 getBMI  :  ƒ (){ return this[体重] / this[身長] ** 2 }
 */

この様にすると結果として、「身長」、「体重」の他に「getBMI」のメソッドの中身も表示されてしまう。 それを禁止するために、親オブジェクトから取得したデータを無視するため次の様に記述する。

for (const p in girl)
  if (girl.hasOwnProperty(p))
    console.log(p, ' : ', girl[p]);

ちなみに、親オブジェクトも含めてそのプロパティを持っているかどうかを調べるにはin演算子を使用する。

if (p in girl) { /* ... */ }

Object.prototype.valueOf()

編集

データの値をそのまま返す。 このメソッドは他のオブジェクトでそれぞれオーバーライドされるのを期待されて存在しています。 そのため、単体としてそれほどの意味は無い。 プリミティブ型のラッパーオブジェクトから元のプリミティブを得る時に使われる。

Object.prototype.isPrototypeOf(V)

編集

引数で与えたオブジェクトが、自分の子孫ノードであるかどうかをチェックする。

function Foo(){}
function Bar(){}
function Baz(){}
Bar.prototype = new Foo();
Baz.prototype = new Bar();
console.log(Foo.prototype.isPrototypeOf(new Bar()));  // true
console.log(Foo.prototype.isPrototypeOf(new Baz()));  // true

Object.prototype.propertyIsEnumerable(V)

編集

引数で指定したプロパティがオブジェクト自身のプロパティかつ、for~in文で列挙可能なものであるのかをチェックする。 プロパティでなければfalseを、列挙可能ならtrueを、不可能ならfalseを返す。

下位階層のページ

編集

脚註

編集
  1. ^ Object.prototype.toString() - JavaScript // MDN” (2021年9月13日). 2021年11月23日閲覧。

外部リンク

編集