オブジェクトについて
グローバルオブジェクト
- JavaScriptエンジンが初期状態で生成するオブジェクト
- ↓確認方法(どれも同じ)
console.log(globalThis);
window
self
frames
- グローバルオブジェクトは下記の要素が混ざって用意されている
- node.jsの用意しているオブジェクト
定義方法
- キーについて(文字列で管理されている)
- 予約語も使える
- 数字も文字列もできる
- 式もできる
- 上記のキーのアクセスはブラケット記法でしかアクセスできない
const interests = 'hoge';
const person = {
age: 37,
name: ['yusuke','hashizume'],
gender: 'male',
interests: {
sports: 'golf',
music: 'guiter',
},
getFullName: function() {
console.log(this.name[0] + this.name[1]);
},
const: 'const', // 予約後
3: 3, // 数字
'hoge fuga': 'hoge', //文字列
[interests]: ['fuga','foo'], // 式
};
アクセス(ドット記法)
console.log(person.name); //['yusuke','hashizume']
console.log(person.name[0]); //'yusuke'
console.log(person.interests.sports); //'golf'
アクセス(ブラケット記法)
console.log(person['name']); //['yusuke', 'hashizume]
どう使い分ける
キーに変数を使いたいときはブラケット
const ageKey = 'age';
person[ageKey] = 12;
オブジェクトのキー情報の取得方法
- for in
const coffee = {
name: 'Cafe Latte',
color: 'black',
size: 350,
isHot: true,
};
for(const key in coffee){
console.log(key); // name, color, size, isHot
}
- Object.keys
const keys = Object.keys(coffee);
console.log(keys); // name, color, size, isHot
オブジェクトのバリュー情報の取得方法
- for of
for(const value of coffee){
console.log(value); // 'Cafe Latte', 'black', 350, true
}
- Object.values
const values = Object.values(coffee);
console.log(values); // 'Cafe Latte', 'black', 350, true;
キー・バリューの配列で取得
- Object.entries
const ary = Object.entries(coffee);
console.log(ary); // ['name','Cafe Latte'],['color','black'],['size',350],['isHot',true]
オブジェクト情報を取り出した時の順番
- キーが正の整数を昇順で表示
- それ以外のキーは定義された順
const person = {
age: 37,
name: ['yusuke','hashizume'],
gender: 'male',
interests: {
sports: 'golf',
music: 'guiter',
},
getFullName: function() {
console.log(this.name[0] + this.name[1]);
},
const: 'const', // 予約後
3: 3, // 数字
1.2: 1.2,
2: 2,
};
Object.keys(person); // [2,3,age,name,gender,interests,getFullName,const,1.2]
Object.values(person); // 上記の順番と同じ
オブジェクトの省略記法
const name = 'Espresso';
const size = 350;
// 本来
const coffee = {
name: name,
size: size,
}
// こうやって省略できる
const coffee = {
name,
size,
}
オブジェクトのコピーについて
const num = {val:2}
const newNum = num;
newNum.val = 4;
console.log(num) // {val:4}
console.log(newNum) // {val:4}
↑値そのものをコピーではなく値の参照をコピーしているので元の値が変わってしまう。
↓これも同じこと
const num = {val:2}
const double = (num) => {
num.val = num.val*2;
return num;
}
const newNum = double(num);
console.log(num) // {val:4}
console.log(newNum) //{val:4}
スプレッド構文を使ってオブジェクトをコピーする
const num = {val:2};
const newNum = {...num};
newNum.val = 4;
console.log(num) // {val:2};
console.log(newNum) // {val:4}
// numとnewNumは別物!
追加もできるよ
const coffee = {
name: 'Cafe Latte',
size: 350,
}
const coffee2 = {
...coffee,
isHot: true,
}
あくまでもシャローコピーである
- 多階層のコピーには対応していない
const coffee = {
name: 'Cafe Latte',
size: 350,
nutritions: {
calories: 5,
}
};
const coffee2 = {...coffee};
coffee2.nutritions.calories = 180;
console.log(coffee.nutritions.calories); // 180 =>影響受けちゃった!
オブジェクトの結合
- Object.assign(a,b,[c,d,…])
- 第一引数のオブジェクトに他を結合
- 同一キーがあれば後に結合された方が優先される
- スプレッド構文との違い
- スプレッド構文はオブジェクトを展開して新しいオブジェクトを作る
- Object.assignは既存のオブジェクトを元にどんどん結合する
const obj1 = {a:1};
const obj2 = {b:2};
Object.assign(obj1,obj2);
console.log(obj1); // {a:1, b:2}
分割代入
const book = {
title: 'js',
price: 19.0,
}
// 通常
const title = book.title;
const price = book.price;
// 分割代入
const {title, price} = book;
特殊な動き
- 別名を付けられる
- 多階層にもアクセスできる
- 代入していない余り全てを受け取れる
const book = {
title: 'js',
price: 19.0,
author: {
firstName: 'yusuke',
lastName: 'hashizume',
},
publisher: 'hoge inc',
open: '9/5',
}
const {
title: bookTitle, // 別名
price,
author:{ // 多階層
firstName,
lastName,
},
...other // 余り
} = book;
console.log(bookTitle); // js
console.log(firstName); // yusuke
console.log(other); // {publisher:'hoge inc', open: '9/5'}
オブジェクトの中から特定のプロパティの有無を探す
- 上記bookオブジェクトから検索
console.log('title' in book); // true
console.log('hello' in book); // false
オプショナルチェーン
挙動
- ?.の前の式の値がnullかundefinedならその後は評価せずにすぐにundefinedを返す
user.address // userがnullやundefinedならエラーになる
user?.address // エラーにならずundefinedを返す(未定義ならエラー)
ポイント
- 存在しない式ならエラーになる(あくまでもnullかundefined)
- メソッドにも使える
- 関数オブジェクトにも使える
- ブラケット記法にも使える
- delete演算子にも使える
hoge.address // hogeが未定義ならエラー
user?.getAddress(); // メソッドにも使える
getUser?.(); // 関数オブジェクトにも使える
user?.['address']; // ブラケット記法にも使える
delete user?.address; // userがnullかundefiedなら何も起こらずにtrueが返る