LoginSignup
2
0

More than 1 year has passed since last update.

【JavaScript】オブジェクト② 〜

Last updated at Posted at 2021-10-07

概要

...【JavaScript】オブジェクト①の続きです。

JavaScriptを学習、理解を深めるため「JavaScript Primer 迷わないための入門書」を読み、
理解した内容等を記載していく。

【JavaScript】JavaScript入門一覧」に他の記事をまとめています。

この記事で理解できること

  • オブジェクトのプロパティの追加方法

プロパティの追加

  • オブジェクトは、プロパティの追加などオブジェクト作成後も値を変更できる。
  • オブジェクトに指定したプロパティが存在しない場合、自動的にプロパティが作成される。
  • ドット記法ブラケット記法のどちらでも追加可能。
  • 追加時にプロパティ名(キー)を変数変数の命名規則には適合しない文字列Symbolを指定する際は、ブラケット記法を使用する。
// 空のオブジェクト「obj」を作成
const obj = {};

// nameプロパティをドット記法で追加して値を代入
obj.name = "Taro";             // 自動的にnameプロパティが作成される

// 変数「key」に変数の命名規則には適合しないプロパティ名「e-mail」を代入
const key = "e-mail";
obj[key] = "sample@mail.com";  // 変数「key」に代入したe-mailプロパティが作成、および指定した値が設定される

// Symbolのプロパティを追加
obj[Symbol("hobby")] = "baseball";

console.log(obj); // => {name: 'Taro', e-mail: 'sample@mail.com', Symbol(hobby): 'baseball'}

【Tips】Computed property names

  • ブラケット記法を用いたプロパティの定義は、オブジェクトリテラル{ }内でも可能。
  • その際、プロパティ名は「Computed property names」と呼ばれる。
  • 「Computed property names」はES2015から導入された記法
object.js
// 変数「key」に変数の命名規則には適合しないプロパティ名「e-mail」を代入
const key = "e-mail";

// 空のオブジェクト「obj」を作成
const obj = {
    [key]: "sample@mail.com"  //  =>  変数「key」が評価されプロパティ名「e-mail」の設定、および値が設定される
};

// 変数「key」をブラケット記法で指定
console.log(obj[key]);        // => sample@mail.com

注意点

  • 冒頭で記載した通り、JavaScriptのオブジェクトはオブジェクト作成後にプロパティを変更可能という特性を持つ。
  • オブジェクトの作成時以外でプロパティを追加すると、オブジェクトがどんなプロパティを持っているか不明確になりやすい。
  • できる限りオブジェクト作成後に新しいプロパティは追加せず、オブジェクトの作成時のオブジェクトリテラルの中でプロパティを定義することが推奨されている。

プロパティの削除

  • オブジェクトのプロパティを削除する場合は、delete演算子を使用する。
  • ドット記法の場合delete オブジェクト.プロパティ名;で削除可能。
  • ブラケット記法の場合delete オブジェクト[プロパティ名];で削除可能。
object.js
// 3つのプロパティを持つ、オブジェクト「obj」を作成
const obj = {
    "name": "Taro",
    "age": 24,
    "e_mail": "main@mail.com",
};

// オブジェクト「obj」からプロパティ「age」を削除
delete obj.age;

// オブジェクト「obj」からプロパティ「e_mail」を削除
delete obj["e_mail"];

console.log(obj);  // => {name: 'Taro'}

プロパティの存在を確認する

JavaScriptでは、存在しないプロパティにアクセスした場合、例外ではなくundefinedを返す。
あるオブジェクトがあるプロパティを持っているかを確認する方法として、次の3つがある。

  • undefinedとの比較
  • in演算子
  • hasOwnPropertyメソッド

undefinedとの比較

  • 存在しないプロパティにアクセスした場合undefinedが返されるため、プロパティにアクセスすると存在を確認できる。
  • しかし、プロパティの値がundefinedだった場合、区別が難しくなる。
  • そのため、プロパティが存在するかの判定にはin演算子hasOwnPropertyメソッドを使用する。
object.js
// オブジェクト「obj」を作成
const obj = {
    "name": "Taro",
    "age": undefined
};

// 事前に確認してみる
console.log(obj.name);  // => Taro
console.log(obj.age);   // => undefined(値がundefined)
console.log(obj.not);   // => undefined(存在しないプロパティを指定した場合の挙動)

// オブジェクト「obj」にプロパティ「name」が存在するか確認
if (obj.name !== undefined) {
    // undefinedじゃなければconsole.logが実行される
    console.log("undefinedではない");  // => undefinedではない
}

// オブジェクト「obj」にプロパティ「age」が存在するか確認
if (obj.age !== undefined) {
    // undefinedじゃなければconsole.logが実行される
    console.log("undefinedではない");
}
// => プロパティageが存在しているが何も表示されない = プロパティの値がundefinedのためif文内の処理が実行されていない

in演算子

  • "プロパティ名" in オブジェクト;で指定したオブジェクトにプロパティが存在するかを判定できる。
  • in演算子はプロパティの値は関係なく、プロパティが存在するかの判定を行う。
  • tureもしくはfalseが返される。
object.js
// オブジェクト「obj」を作成
const obj = {
    "name": "Taro",
    "age": undefined
};

// "プロパティ名" in オブジェクト;でプロパティが存在するかを判定
console.log("name" in obj);  // => true
console.log("age" in obj);   // => 値はundefinedだがプロパティが存在するためtrue
console.log("city" in obj);  // => プロパティが存在しないためfalse

hasOwnPropertyメソッド

  • オブジェクト.hasOwnProperty("プロパティ名");でプロパティが存在するかを判定できる。
  • hasOwnPropertyメソッドの引数には、存在を判定したいプロパティ名を指定する。
  • hasOwnPropertyメソッドもプロパティの値は関係なく、プロパティが存在するかの判定を行う。
  • tureもしくはfalseが返される。
object.js
// オブジェクト「obj」を作成
const obj = {
    "name": "Taro",
    "age": undefined
};

// オブジェクト.hasOwnProperty("プロパティ名");でプロパティが存在するかを判定
console.log(obj.hasOwnProperty("name"));  // => true
console.log(obj.hasOwnProperty("age"));   // => 値はundefinedだがプロパティが存在するためtrue
console.log(obj.hasOwnProperty("city"));  // => プロパティが存在しないためfalse

【Tips】Optional chaining演算子(?.)

  • ES2020ではOptional chaining演算子(?.)が導入された。
  • ネストしたプロパティの存在確認アクセスを簡単に行えるのが特徴。
  • (プロパティを持つオブジェクトの場合)オブジェクト?.プロパティ名と指定しアクセスする。
  • 左辺のアクセス対象がnullまたはundefinedの場合は、それ以上評価せずundefinedを返す。
  • プロパティが存在する場合は、プロパティの評価結果を返す。
object.js
// オブジェクト「obj」を作成
const obj = {
    "team_a": {
        "name": "Taro",
        "age": undefined,
        "e_mail": "main@mail.com"
    }
};

// ドット記法やブラケット記法の場合、ネストしたプロパティのいずれかが「undefined」の場合、例外が発生してしまう
console.log(obj.team_b.name);        // => Uncaught TypeError: Cannot read properties of undefined (reading 'name')
console.log(obj["team_b"]["name"]);  // => Uncaught TypeError: Cannot read properties of undefined (reading 'name')

// オブジェクト.hasOwnProperty("プロパティ名");でプロパティが存在するかを判定
console.log(obj?.team_a?.name);        // => Taro
console.log(obj?.team_a?.age);         // => undefined
console.log(obj?.team_a?.["e_mail"]);  // => main @mail.com(ブラケット記法との組み合わせも可能)
console.log(obj?.team_b?.name);        // => 例外の発生、「team_b」以降の評価はされず「team_b」の評価結果「undefined」が返される

toStringメソッド

  • toStringメソッドはオブジェクト自身を文字列化するメソッド。
  • Stringコンストラクタ関数でこのtoStringメソッドが呼び出されている。
  • オブジェクト.toString();でオブジェクトを文字列化可能。
object.js
// オブジェクト「obj」を作成
const obj = {
    "team_a": {
        "name": "Taro",
        "age": undefined,
        "e_mail": "main@mail.com"
    }
};

// オブジェクト「obj」をtoStringメソッドで文字列化する
console.log(obj.toString());  // => オブジェクトを文字列化すると[object Object]という文字列になる

オブジェクトの静的メソッド(スタティックメソッド)

  • オブジェクトの静的メソッドとは、インスタンスの元となる「Object」そのものから呼び出せるメソッドのことである
  • オブジェクトの列挙やマージなどオブジェクトを操作する静的メソッドが存在する。

オブジェクトの列挙

オブジェクトのプロパティを列挙する3つの以下の静的メソッドが存在する。

  • Object.keysメソッド(オブジェクトのプロパティ名を配列で返す)
  • Object.valuesメソッド(オブジェクトの値を配列で返す) ※ES2017から
  • Object.entriesメソッド(オブジェクトのプロパティ名と値の配列を返す) ※ES2017から
object.js
// オブジェクト「obj」を作成
const obj = {
    "name": "Taro",
    "age": undefined,
    "e_mail": "main@mail.com"
};

// Object.keys(オブジェクト);でプロパティ名を配列で返す
console.log(Object.keys(obj));    // => (3) ['name', 'age', 'e_mail']

// Object.values(オブジェクト);でオブジェクトの値を配列で返す
console.log(Object.values(obj));  // => (3) ['Taro', undefined, 'main@mail.com']

// Object.entries(オブジェクト);でオブジェクトのプロパティ名と値の配列を返す
console.log(Object.entries(obj));  // => [Array(2), Array(2), Array(2)]
                                   //     0: (2)['name', 'Taro']
                                   //     1: (2) ['age', undefined]
                                   //     2: (2) ['e_mail', 'main@mail.com'] ...

オブジェクトのマージと複製

  • Object.assginメソッドは、あるオブジェクトを別のオブジェクトに代入することが可能。
  • オブジェクトの複製やマージを行うことが可能。
  • 既存のオブジェクトには影響を与えずマージしたオブジェクトを作ることができるため、第一引数(上記ではコピー先オブジェクト)には空のオブジェクトを指定することが典型的な方法とされている。
  • プロパティ名が重複した場合は、後ろのオブジェクトのプロパティにより上書きされることに注意。
  • ES2015から使用可能。
object.js
// オブジェクト「returnObj」を作成
const returnObj = {};

const objA = {
    "name": "Hanako",
    "age": 22,
    "e_mail": "main@mail.com"
};

const objB = {
    "name": "Eita",
    "age": 28
};

// 結果的にobjAを複製した形でオブジェクト「returnObj」が返される
console.log(Object.assign(returnObj, objA));        // => {name: 'Hanako', age: 22, e_mail: 'main@mail.com'}

// objAとobjBではプロパティ「name」と「age」が重複しているためobjAのプロパティの値が上書きされている
console.log(Object.assign(returnObj, objA, objB));  // => {name: 'Eita', age: 28, e_mail: 'main@mail.com'}

【Tips】オブジェクトのspread構文(...)

  • ES2018からオブジェクトのspread構文(...)が追加された。
  • ES2015で配列の要素を展開するspread構文はサポートされていたが、オブジェクトに対してはES2018からサポートされた。
  • 新たにオブジェクトを作成するオブジェクトリテラル({ })の中に指定し、使用する。
  • プロパティ名が重複した場合は、後ろのオブジェクトのプロパティにより上書きされることに注意。
object.js
const objA = {
    "name": "Hanako",
    "age": 22,
    "e_mail": "main@mail.com"
};

const objB = {
    "name": "Eita",
    "age": 28
};

// spread構文でマージするオブジェクトを指定
const returnObj = {
    ...objA,
    ...objB
};

// マージしたオブジェクトを確認してみる
console.log(returnObj);  // => {name: 'Eita', age: 28, e_mail: 'main@mail.com'}
2
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
2
0