サーチ…
構文
- オブジェクト= {}
- object = new Object()
- object = Object.create(プロトタイプ[、propertiesObject])
- object.key = value
- オブジェクト["key"] = value
- オブジェクト[Symbol()] = value
- オブジェクト= {key1:value1、 "key2":value2、 'key3':value3}
- object = {conciseMethod(){...}}
- object = {[computed()+ "key"]:value}
- Object.defineProperty(obj、propertyName、propertyDescriptor)
- property_desc = Object.getOwnPropertyDescriptor(obj、propertyName)
- Object.freeze(obj)
- Object.seal(obj)
パラメーター
プロパティ | 説明 |
---|---|
value | プロパティに割り当てる値。 |
writable | プロパティの値を変更できるかどうか。 |
enumerable | プロパティがループ内for in 列挙されるかどうか。 |
configurable | プロパティ記述子を再定義することが可能かどうか。 |
get | 呼び出される関数は、プロパティの値を返します。 |
set | プロパティに値が代入されたときに呼び出される関数。 |
備考
オブジェクトは、キーと値のペアまたはプロパティの集合です。キーはString
またはSymbol
です。値はプリミティブ(数値、文字列、シンボル)または他のオブジェクトへの参照です。
JavaScriptでは、オブジェクト(関数、配列など)や不変のオブジェクト(数値、文字列、ブール値)として動作するプリミティブがかなりの量の値となります。それらのプロパティまたはprototype
のプロパティは、dot( obj.prop
)またはブラケット( obj['prop']
)表記法を使用してアクセスできます。特筆すべき例外は、 undefined
の特別な値とnull
です。
オブジェクトは、値ではなく、JavaScriptで参照されます。これは、関数への引数としてコピーまたは渡されたとき、 "コピー"とオリジナルは同じオブジェクトへの参照であり、一方のプロパティの変更は他方の同じプロパティを変更することを意味します。これは、不変で値によって渡されるプリミティブには当てはまりません。
Object.keys
Object.keys(obj)
は、指定されたオブジェクトのキーの配列を返します。
var obj = {
a: "hello",
b: "this is",
c: "javascript!"
};
var keys = Object.keys(obj);
console.log(keys); // ["a", "b", "c"]
浅いクローニング
ES6のObject.assign()
関数を使用すると、すべての列挙可能なプロパティを既存のObject
インスタンスから新しいインスタンスにコピーできます。
const existing = { a: 1, b: 2, c: 3 };
const clone = Object.assign({}, existing);
これには、 String
プロパティに加えてSymbol
プロパティも含まれます。
現在ステージ3の提案であるオブジェクトの休憩/散布の破壊は、Objectインスタンスの浅いクローンを作成するさらに簡単な方法を提供します。
const existing = { a: 1, b: 2, c: 3 };
const { ...clone } = existing;
古いバージョンのJavaScriptをサポートする必要がある場合、Objectを複製する最も互換性のある方法は、手動でプロパティを反復し、 .hasOwnProperty()
を使用して継承されたものをフィルタリングすることです。
var existing = { a: 1, b: 2, c: 3 };
var clone = {};
for (var prop in existing) {
if (existing.hasOwnProperty(prop)) {
clone[prop] = existing[prop];
}
}
Object.defineProperty
これにより、プロパティ記述子を使用して既存のオブジェクトにプロパティを定義することができます。
var obj = { };
Object.defineProperty(obj, 'foo', { value: 'foo' });
console.log(obj.foo);
コンソール出力
foo
Object.defineProperty
は、次のオプションを使用してObject.defineProperty
ことができます。
Object.defineProperty(obj, 'nameOfTheProperty', {
value: valueOfTheProperty,
writable: true, // if false, the property is read-only
configurable : true, // true means the property can be changed later
enumerable : true // true means property can be enumerated such as in a for..in loop
});
Object.defineProperties
使用すると、一度に複数のプロパティを定義できます。
var obj = {};
Object.defineProperties(obj, {
property1: {
value: true,
writable: true
},
property2: {
value: 'Hello',
writable: false
}
});
読み取り専用プロパティ
プロパティ記述子を使用すると、プロパティを読み込み専用にすることができ、値を変更しようとすると自動的に失敗し、値は変更されず、エラーもスローされません。
プロパティ記述子のwritable
プロパティは、そのプロパティを変更できるかどうかを示します。
var a = { };
Object.defineProperty(a, 'foo', { value: 'original', writable: false });
a.foo = 'new';
console.log(a.foo);
コンソール出力
元の
非列挙型プロパティ
私たちはfor (... in ...)
ループfor (... in ...)
プロパティが表示されるのfor (... in ...)
避けることができます
プロパティデスクリプタのenumerable
プロパティは、そのプロパティがオブジェクトのプロパティをループしている間に列挙されるかどうかを示します。
var obj = { };
Object.defineProperty(obj, "foo", { value: 'show', enumerable: true });
Object.defineProperty(obj, "bar", { value: 'hide', enumerable: false });
for (var prop in obj) {
console.log(obj[prop]);
}
コンソール出力
ショー
ロックプロパティの説明
プロパティの記述子はロックすることができ、変更はできません。プロパティを通常どおりに使用して値を割り当てたり取得したりすることは可能ですが、再定義しようとすると例外がスローされます。
プロパティ記述子のconfigurable
プロパティは、記述子のそれ以上の変更を禁止するために使用されます。
var obj = {};
// Define 'foo' as read only and lock it
Object.defineProperty(obj, "foo", {
value: "original value",
writable: false,
configurable: false
});
Object.defineProperty(obj, "foo", {writable: true});
このエラーはスローされます:
TypeError:プロパティを再定義できません:foo
また、プロパティはまだ読み取り専用です。
obj.foo = "new value";
console.log(foo);
コンソール出力
元の値
アクセッサのプロパティ(getおよびset)
プロパティを2つの関数の組み合わせとして扱います。一つは値を取得する関数、もう一つは値を設定する関数です。
プロパティ記述子のget
プロパティは、プロパティから値を取得するために呼び出される関数です。
set
プロパティは関数でもあり、プロパティに値が代入されたときに呼び出され、新しい値が引数として渡されます。
get
またはset
したディスクリプタにvalue
またはwritable
を割り当てることはできません
var person = { name: "John", surname: "Doe"};
Object.defineProperty(person, 'fullName', {
get: function () {
return this.name + " " + this.surname;
},
set: function (value) {
[this.name, this.surname] = value.split(" ");
}
});
console.log(person.fullName); // -> "John Doe"
person.surname = "Hill";
console.log(person.fullName); // -> "John Hill"
person.fullName = "Mary Jones";
console.log(person.name) // -> "Mary"
特殊文字または予約語を含むプロパティ
オブジェクトのプロパティ表記法は通常myObject.property
として記述されますが 、これは主に文字、数字、アンダースコア( _
)のJavaScript変数名に通常含まれる文字のみを許可します 。
スペース、☺、ユーザー提供のコンテンツなどの特殊文字が必要な場合は、 []
ブラケット記法を使用します。
myObject['special property ☺'] = 'it works!'
console.log(myObject['special property ☺'])
すべての桁のプロパティ:
特殊文字に加えて、すべての桁のプロパティ名にはカッコ表記が必要です。ただし、この場合、プロパティは文字列として記述する必要はありません。
myObject[123] = 'hi!' // number 123 is automatically converted to a string
console.log(myObject['123']) // notice how using string 123 produced the same result
console.log(myObject['12' + '3']) // string concatenation
console.log(myObject[120 + 3]) // arithmetic, still resulting in 123 and producing the same result
console.log(myObject[123.0]) // this works too because 123.0 evaluates to 123
console.log(myObject['123.0']) // this does NOT work, because '123' != '123.0'
ただし、8進表記法として解釈されるため、先行ゼロは推奨されません。 (TODO、8進数、16進数、指数表記を記述した例を生成してリンクする必要があります)
参照:[配列はオブジェクトです]例。
動的/可変プロパティ名
場合によっては、プロパティ名を変数に格納する必要があります。この例では、どの単語を検索する必要があるかをユーザーに尋ね、 dictionary
名前を付けたオブジェクトの結果を提供します。
var dictionary = {
lettuce: 'a veggie',
banana: 'a fruit',
tomato: 'it depends on who you ask',
apple: 'a fruit',
Apple: 'Steve Jobs rocks!' // properties are case-sensitive
}
var word = prompt('What word would you like to look up today?')
var definition = dictionary[word]
alert(word + '\n\n' + definition)
word
名前の変数を調べるには、 []
ブラケット記法をどのように使っているかに注意してください。もし私たちが伝統的なものを使うならば.
表記法では、文字通り値をとるため、
console.log(dictionary.word) // doesn't work because word is taken literally and dictionary has no field named `word`
console.log(dictionary.apple) // it works! because apple is taken literally
console.log(dictionary[word]) // it works! because word is a variable, and the user perfectly typed in one of the words from our dictionary when prompted
console.log(dictionary[apple]) // error! apple is not defined (as a variable)
変数のword
を文字列'apple'
置き換えることによって、 []
表記でリテラル値を書くこともできます。 [特殊文字または予約語付きプロパティ]の例を参照してください。
ブラケット構文を使用して動的プロパティを設定することもできます。
var property="test";
var obj={
[property]=1;
};
console.log(obj.test);//1
それは以下と同じです:
var property="test";
var obj={};
obj[property]=1;
配列はオブジェクトです
免責条項:配列のようなオブジェクトの作成はお勧めしません。しかし、特にDOMを使って作業しているときに、その動作を理解することは役に立ちます。これは、多くのDOM
document
関数から返されたDOMオブジェクトに対して通常の配列操作が機能しない理由を説明します。 (すなわち、querySelectorAll
、form.elements
)
次のオブジェクトを作成したとします。このオブジェクトには、Arrayで表示されると予想されるいくつかのプロパティがあります。
var anObject = {
foo: 'bar',
length: 'interesting',
'0': 'zero!',
'1': 'one!'
};
次に、配列を作成します。
var anArray = ['zero.', 'one.'];
さて、オブジェクトと配列の両方を同じ方法で検査する方法に注目してください。
console.log(anArray[0], anObject[0]); // outputs: zero. zero!
console.log(anArray[1], anObject[1]); // outputs: one. one!
console.log(anArray.length, anObject.length); // outputs: 2 interesting
console.log(anArray.foo, anObject.foo); // outputs: undefined bar
anArray
は実際にはanObject
ように実際にはオブジェクトなanObject
、 anArray
カスタムanObject
プロパティを追加することもできanArray
免責条項:カスタムプロパティを持つ配列は、通常は混乱させる可能性があるのでお勧めできませんが、配列の最適化された機能が必要な高度な場合に便利です。 (つまり、jQueryオブジェクト)
anArray.foo = 'it works!';
console.log(anArray.foo);
anObject
をlength
さを加えて配列のようなオブジェクトにすることさえできます。
anObject.length = 2;
次に、Cスタイルのfor
ループを使用して、あたかもそれが配列であるかのようにanObject
を反復処理することができます。 配列の反復を参照してください。
anObject
は配列のようなオブジェクトだけであることに注意してください。 (Listとしても知られています)本当の配列ではありません。 push
やforEach
(あるいはArray.prototype
便利な関数)のような関数は、配列のようなオブジェクトではデフォルトでは機能しないため、これは重要です。
DOM document
関数の多くは、上で作成した配列のようなanObject
似たList(つまりquerySelectorAll
、 form.elements
)をanObject
ます。 「 配列に似たオブジェクトから配列への変換 」を参照してください。
console.log(typeof anArray == 'object', typeof anObject == 'object'); // outputs: true true
console.log(anArray instanceof Object, anObject instanceof Object); // outputs: true true
console.log(anArray instanceof Array, anObject instanceof Array); // outputs: true false
console.log(Array.isArray(anArray), Array.isArray(anObject)); // outputs: true false
Object.freeze
Object.freeze
は、新しいプロパティの追加、既存のプロパティの削除、および既存のプロパティの列挙可能性、構成可能性、および書き込み可能性の変更を防止することによって、オブジェクトを不変にします。また、既存のプロパティの値が変更されないようにします。ただし、再帰的には機能しません。つまり、子オブジェクトは自動的にフリーズされず、変更される可能性があります。
コードが厳密なモードで実行されていない限り、フリーズ後の操作は暗黙的に失敗します。コードがstrictモードの場合、 TypeError
がスローされます。
var obj = {
foo: 'foo',
bar: [1, 2, 3],
baz: {
foo: 'nested-foo'
}
};
Object.freeze(obj);
// Cannot add new properties
obj.newProperty = true;
// Cannot modify existing values or their descriptors
obj.foo = 'not foo';
Object.defineProperty(obj, 'foo', {
writable: true
});
// Cannot delete existing properties
delete obj.foo;
// Nested objects are not frozen
obj.bar.push(4);
obj.baz.foo = 'new foo';
Object.seal
Object.seal
は、オブジェクトのプロパティの追加または削除を防ぎます。オブジェクトが密封されると、そのプロパティ記述子を別のタイプに変換することはできません。 Object.freeze
とは異なり、プロパティの編集が可能です。
密封されたオブジェクトに対してこの操作を実行しようとすると、自動的に失敗します
var obj = { foo: 'foo', bar: function () { return 'bar'; } };
Object.seal(obj)
obj.newFoo = 'newFoo';
obj.bar = function () { return 'foo' };
obj.newFoo; // undefined
obj.bar(); // 'foo'
// Can't make foo an accessor property
Object.defineProperty(obj, 'foo', {
get: function () { return 'newFoo'; }
}); // TypeError
// But you can make it read only
Object.defineProperty(obj, 'foo', {
writable: false
}); // TypeError
obj.foo = 'newFoo';
obj.foo; // 'foo';
strictモードでは、これらの操作によってTypeError
がスローされます
(function () {
'use strict';
var obj = { foo: 'foo' };
Object.seal(obj);
obj.newFoo = 'newFoo'; // TypeError
}());
反復可能なオブジェクトの作成
var myIterableObject = {};
// An Iterable object must define a method located at the Symbol.iterator key:
myIterableObject[Symbol.iterator] = function () {
// The iterator should return an Iterator object
return {
// The Iterator object must implement a method, next()
next: function () {
// next must itself return an IteratorResult object
if (!this.iterated) {
this.iterated = true;
// The IteratorResult object has two properties
return {
// whether the iteration is complete, and
done: false,
// the value of the current iteration
value: 'One'
};
}
return {
// When iteration is complete, just the done property is needed
done: true
};
},
iterated: false
};
};
for (var c of myIterableObject) {
console.log(c);
}
コンソール出力
1
オブジェクトの休憩/スプレッド(...)
オブジェクトの広がりは、 Object.assign({}, obj1, ..., objn);
構文上の砂糖ですObject.assign({}, obj1, ..., objn);
それは...
演算子で行われ...
:
let obj = { a: 1 };
let obj2 = { ...obj, b: 2, c: 3 };
console.log(obj2); // { a: 1, b: 2, c: 3 };
Object.assign
として、深いマージではなく浅いマージを行います。
let obj3 = { ...obj, b: { c: 2 } };
console.log(obj3); // { a: 1, b: { c: 2 } };
注 : この仕様は現在ステージ3にあります
記述子と名前付きプロパティ
プロパティはオブジェクトのメンバーです。それぞれの名前付きプロパティは、(name、descriptor)のペアです。名前は、アクセスを許可する文字列です(ドット表記object.propertyName
または角括弧表記object['propertyName']
)。記述子は、アクセスされたときのプロパティ(プロパティに何が起こるか、それにアクセスして返される値は何か)を定義するフィールドのレコードです。全体として、プロパティは名前をビヘイビアに関連付けます(ビヘイビアをブラックボックスと考えることができます)。
名前付きプロパティには2つのタイプがあります。
- データプロパティ :プロパティの名前は値に関連付けられます。
- アクセサプロパティ :プロパティの名前は、1つまたは2つのアクセサ関数に関連付けられています。
デモンストレーション:
obj.propertyName1 = 5; //translates behind the scenes into
//either assigning 5 to the value field* if it is a data property
//or calling the set function with the parameter 5 if accessor property
//*actually whether an assignment would take place in the case of a data property
//also depends on the presence and value of the writable field - on that later on
プロパティの型は、その記述子のフィールドによって決定され、プロパティは両方の型のどちらでもありません。
データ記述子 -
- 必須フィールド:
value
またはwritable
または両方 - オプションフィールド:
configurable
、enumerable
サンプル:
{
value: 10,
writable: true;
}
アクセサ記述子 -
- 必須フィールド:
get
またはset
またはその両方 - オプションフィールド:
configurable
、enumerable
サンプル:
{
get: function () {
return 10;
},
enumerable: true
}
フィールドとそのデフォルトの意味
configurable
、 enumerable
、およびwritable
: - これらのキーはすべてデフォルトで
false
です。 - このプロパティ記述子の型が変更され、そのプロパティが対応するオブジェクトから削除される可能性が
true
場合に限りtrue
configurable
です。 -
enumerable
は、対応するオブジェクトのプロパティの列挙中にこのプロパティが表示される場合にのみtrue
です。 -
writable
は、プロパティに関連付けられた値を代入演算子で変更できる場合にのみtrue
です。
get
してset
:
- これらのキーのデフォルトは
undefined
です。 -
get
は、プロパティのゲッターとして機能する関数です。ゲッターがない場合は、undefined
です。関数の戻り値は、プロパティの値として使用されます。 -
set
はプロパティのセッターとして機能する関数です。セッターがない場合はundefined
です。この関数は、プロパティに代入される新しい値を引数として受け取るだけです。
value
:
- このキーのデフォルトは
undefined
です。 - プロパティに関連付けられた値。任意の有効なJavaScript値(数値、オブジェクト、関数など)を指定できます。
例:
var obj = {propertyName1: 1}; //the pair is actually ('propertyName1', {value:1,
// writable:true,
// enumerable:true,
// configurable:true})
Object.defineProperty(obj, 'propertyName2', {get: function() {
console.log('this will be logged ' +
'every time propertyName2 is accessed to get its value');
},
set: function() {
console.log('and this will be logged ' +
'every time propertyName2\'s value is tried to be set')
//will be treated like it has enumerable:false, configurable:false
}});
//propertyName1 is the name of obj's data property
//and propertyName2 is the name of its accessor property
obj.propertyName1 = 3;
console.log(obj.propertyName1); //3
obj.propertyName2 = 3; //and this will be logged every time propertyName2's value is tried to be set
console.log(obj.propertyName2); //this will be logged every time propertyName2 is accessed to get its value
Object.getOwnPropertyDescriptor
オブジェクト内の特定のプロパティの説明を取得します。
var sampleObject = {
hello: 'world'
};
Object.getOwnPropertyDescriptor(sampleObject, 'hello');
// Object {value: "world", writable: true, enumerable: true, configurable: true}
オブジェクトのクローニング
オブジェクトの完全なコピー(オブジェクトのプロパティとそれらのプロパティ内の値など)が必要な場合は、 ディープクローンと呼ばれます。
オブジェクトをJSONにシリアライズすることができれば、 JSON.parse
とJSON.stringify
組み合わせて、 JSON.parse
深いクローンを作成できます。
var existing = { a: 1, b: { c: 2 } };
var copy = JSON.parse(JSON.stringify(existing));
existing.b.c = 3; // copy.b.c will not change
JSON.stringify
はDate
オブジェクトをISO形式の文字列表現に変換しますが、 JSON.parse
はその文字列をDate
変換しません。
深いクローンを作成するためのJavaScriptには、組み込み関数はありません。また、多くの理由ですべてのオブジェクトに深いクローンを作成することは一般的に不可能です。例えば、
- オブジェクトは、検出できない非列挙型および隠れたプロパティを持つことができます。
- オブジェクトgetterとsetterはコピーできません。
- オブジェクトは循環構造を持つことができます。
- 関数のプロパティは、隠されたスコープの状態に依存する可能性があります。
プリミティブな値、日付、配列、または他の「素敵な」オブジェクトのみを含むプロパティを持つ素敵なオブジェクトがあると仮定すると、以下の関数をディープクローンの作成に使用できます。この関数は、循環構造を持つオブジェクトを検出し、そのような場合にエラーをスローする再帰関数です。
function deepClone(obj) {
function clone(obj, traversedObjects) {
var copy;
// primitive types
if(obj === null || typeof obj !== "object") {
return obj;
}
// detect cycles
for(var i = 0; i < traversedObjects.length; i++) {
if(traversedObjects[i] === obj) {
throw new Error("Cannot clone circular object.");
}
}
// dates
if(obj instanceof Date) {
copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
// arrays
if(obj instanceof Array) {
copy = [];
for(var i = 0; i < obj.length; i++) {
copy.push(clone(obj[i], traversedObjects.concat(obj)));
}
return copy;
}
// simple objects
if(obj instanceof Object) {
copy = {};
for(var key in obj) {
if(obj.hasOwnProperty(key)) {
copy[key] = clone(obj[key], traversedObjects.concat(obj));
}
}
return copy;
}
throw new Error("Not a cloneable object.");
}
return clone(obj, []);
}
Object.assign
Object.assign()メソッドは、すべての列挙可能なプロパティの値を1つ以上のソースオブジェクトからターゲットオブジェクトにコピーするために使用されます。ターゲットオブジェクトを返します。
これを使用して、既存のオブジェクトに値を割り当てます。
var user = {
firstName: "John"
};
Object.assign(user, {lastName: "Doe", age:39});
console.log(user); // Logs: {firstName: "John", lastName: "Doe", age: 39}
または、オブジェクトの浅いコピーを作成するには:
var obj = Object.assign({}, user);
console.log(obj); // Logs: {firstName: "John", lastName: "Doe", age: 39}
または、複数のオブジェクトの多くのプロパティを1つにマージします。
var obj1 = {
a: 1
};
var obj2 = {
b: 2
};
var obj3 = {
c: 3
};
var obj = Object.assign(obj1, obj2, obj3);
console.log(obj); // Logs: { a: 1, b: 2, c: 3 }
console.log(obj1); // Logs: { a: 1, b: 2, c: 3 }, target object itself is changed
プリミティブはラップされ、nullとundefinedは無視されます。
var var_1 = 'abc';
var var_2 = true;
var var_3 = 10;
var var_4 = Symbol('foo');
var obj = Object.assign({}, var_1, null, var_2, undefined, var_3, var_4);
console.log(obj); // Logs: { "0": "a", "1": "b", "2": "c" }
文字列ラッパーだけが独自の列挙可能なプロパティを持つことができます
レデューサーとして使う:(配列をオブジェクトにマージする)
return users.reduce((result, user) => Object.assign({}, {[user.id]: user})
オブジェクトのプロパティの反復
このループでは、オブジェクトに属する各プロパティにアクセスできます
for (var property in object) {
// always check if an object has a property
if (object.hasOwnProperty(property)) {
// do stuff
}
}
オブジェクトには、オブジェクトの基本クラスから継承されたプロパティがある可能性があるため、 hasOwnProperty
の追加チェックを含める必要があります。このチェックを行わないと、エラーが発生する可能性があります。
オブジェクトのすべてのプロパティを含むArrayを返すObject.keys
関数を使用して、 Array.map
またはArray.forEach
関数でこの配列をループすることもできます。
var obj = { 0: 'a', 1: 'b', 2: 'c' };
Object.keys(obj).map(function(key) {
console.log(key);
});
// outputs: 0, 1, 2
オブジェクトからのプロパティの取得
プロパティの特性:
オブジェクトから取得できるプロパティには、次のような特性があります。
- 列挙可能
- 非計数
- 自分の
Object.defineProperty(ies)を使用してプロパティを作成する際に、 「own」以外の特性を設定できます。オブジェクトのプロトタイプレベル( __proto__
)にない直接的なレベルで利用できるプロパティは、 独自のプロパティと呼ばれます。
また、 Object.defindProperty(ies)
を使用せずにオブジェクトに追加されるプロパティには、その列挙可能な特性がありません。つまり、それは真実とみなされます。
列挙可能性の目的:
列挙可能な特性をプロパティに設定する主な目的は、異なるプログラム的な方法を使用して、オブジェクトからオブジェクトを取得する際に特定のプロパティの可用性を実現することです。これらの異なる方法については、以下で詳しく説明します。
プロパティを取得する方法:
オブジェクトからのプロパティは、次の方法で取得できますが、
for..in
ループこのループは、オブジェクトから列挙可能なプロパティを取得する際に非常に便利です。さらに、このループは、列挙可能な独自のプロパティを取得するだけでなく、プロトタイプチェーンを探索してプロトタイプがnullになるまで同じ検索を行います。
//Ex 1 : Simple data var x = { a : 10 , b : 3} , props = []; for(prop in x){ props.push(prop); } console.log(props); //["a","b"] //Ex 2 : Data with enumerable properties in prototype chain var x = { a : 10 , __proto__ : { b : 10 }} , props = []; for(prop in x){ props.push(prop); } console.log(props); //["a","b"] //Ex 3 : Data with non enumerable properties var x = { a : 10 } , props = []; Object.defineProperty(x, "b", {value : 5, enumerable : false}); for(prop in x){ props.push(prop); } console.log(props); //["a"]
この関数は、EcmaScript 5の一部として公開されました。オブジェクトから列挙可能な独自のプロパティを取得するために使用されます。リリース前には、
for..in
ループとObject.prototype.hasOwnProperty()
関数を組み合わせて、オブジェクトからオブジェクトのプロパティを取得するのに使用されていました。//Ex 1 : Simple data var x = { a : 10 , b : 3} , props; props = Object.keys(x); console.log(props); //["a","b"] //Ex 2 : Data with enumerable properties in prototype chain var x = { a : 10 , __proto__ : { b : 10 }} , props; props = Object.keys(x); console.log(props); //["a"] //Ex 3 : Data with non enumerable properties var x = { a : 10 } , props; Object.defineProperty(x, "b", {value : 5, enumerable : false}); props = Object.keys(x); console.log(props); //["a"]
この関数は、オブジェクトから列挙可能なプロパティと列挙可能でないプロパティの両方を取得します。また、EcmaScript 5の一部としてリリースされました。
//Ex 1 : Simple data var x = { a : 10 , b : 3} , props; props = Object.getOwnPropertyNames(x); console.log(props); //["a","b"] //Ex 2 : Data with enumerable properties in prototype chain var x = { a : 10 , __proto__ : { b : 10 }} , props; props = Object.getOwnPropertyNames(x); console.log(props); //["a"] //Ex 3 : Data with non enumerable properties var x = { a : 10 } , props; Object.defineProperty(x, "b", {value : 5, enumerable : false}); props = Object.getOwnPropertyNames(x); console.log(props); //["a", "b"]
その他:
オブジェクトからすべての(独自の、列挙可能な、列挙可能でない、すべてのプロトタイプレベルの)プロパティを取得する手法を以下に示します。
function getAllProperties(obj, props = []){
return obj == null ? props :
getAllProperties(Object.getPrototypeOf(obj),
props.concat(Object.getOwnPropertyNames(obj)));
}
var x = {a:10, __proto__ : { b : 5, c : 15 }};
//adding a non enumerable property to first level prototype
Object.defineProperty(x.__proto__, "d", {value : 20, enumerable : false});
console.log(getAllProperties(x)); ["a", "b", "c", "d", "...other default core props..."]
これはEcmaScript 5をサポートするブラウザでサポートされます。
オブジェクトの値を配列に変換する
このオブジェクトが与えられた場合:
var obj = {
a: "hello",
b: "this is",
c: "javascript!",
};
次のようにして、値を配列に変換できます。
var array = Object.keys(obj)
.map(function(key) {
return obj[key];
});
console.log(array); // ["hello", "this is", "javascript!"]
オブジェクトエントリの反復処理 - Object.entries()
提案されたObject.entries()
メソッドは、指定されたオブジェクトのキーと値のペアの配列を返します。 Array.prototype.entries()
ようなイテレータは返されませんが、 Object.entries()
によって返された配列は無関係に反復することができます。
const obj = {
one: 1,
two: 2,
three: 3
};
Object.entries(obj);
結果:
[
["one", 1],
["two", 2],
["three", 3]
]
これは、オブジェクトのキー/値のペアを反復する便利な方法です。
for(const [key, value] of Object.entries(obj)) {
console.log(key); // "one", "two" and "three"
console.log(value); // 1, 2 and 3
}