JS object への property の新規追加 とアクセスの仕方 -- obj.name, obj['name']
Problem
JS の obj のプロパティにアクセスするには
obj.propName
obj['propName']
この2つのやり方がある
前者はお馴染みの内部のプロパティへのアクセスの仕方。
後者は連想配列としてのアクセスになる。
const array = [ 'hoge', 'foo', 'bar',] const people = { 'name': 'Taro', 'tel': '070-1111-111', 'adress': 'Tokyo', }
前者 array [1] でアクセスするのと同じように
後者を pepole ['tel'] としてアクセスするのと同じと考えるとわかりやすい
基本的には前者の方がプロパティのアクセスとしてわかりやすいので
前者で書くべきだが、後述の関数のように、後者の書き方でしかできない場合がある。
プロパティを追加する時と引き出し時の挙動をそれぞれ見ていく。
なお、プロパティを後から追加するのはコードが汚くなるので非推奨。
基本的には
const person: { name: null, tel: null, } person.name = 'Taro'
のようにあらかじめプロパティは用意しておくべき。
obj.propName での追加
const person = { num : 0, } person.dotName = 'dotName' console.log(person); // { num: 0, dotName: 'dotName' }
obj.propName
で追加する場合は、この dotName というものは未定義で、
いきなり person に付け加えて問題ない。プロパティがこの時に作成される。
しかし、[ ] で追加する場合は、後述のように、プロパティを先に定義しておかないとエラーになる。
obj[propName] では追加エラー が出る
const person = { num : 0, } person[name] = 'bracketName' console.log(person); // ReferenceError: name is not defined
さっきの person.name
を person[name]
に変えた。
この形では新規代入させることはできない。
name が変数として扱われているので、person の何プロパティにアクセスしているか、わからないからだ。
obj['propName'] で追加する
const person = { num : 0, } person['name'] = 'Tak' console.log(person); // { num: 0, name: 'Tak' }
obj['propName'] で入れる場合は問題ない。
obj.propName と全く同じで、obj の propName プロパティを参照してくれる
全部を比較する
const person = { name: 'tak', } function printPersonNameByBracket(obj) { console.log(obj.name); // tak console.log(obj['name']); // tak console.log(obj[obj.name]); // undef console.log(obj[name]); // return err } printPersonNameByBracket(person)
ドットでアクセスする方は当然成功する
文字列を直接 []
の中に書き込む方法も成功する
[]
の中身として引数.name を入れるのは読み取らない
ここでは obj[obj.name] -> obj[person.name] -> obj['tak'] となって
obj['tak'] は存在しないからだ。
[]
の中身として name を入れるのも name に何が入っているかが定義されていないので、読み取ってくれない。
結論
const person = {} person.name = 'Takeshi'
obj の中身を obj.prop で入れるときは .prop に値する key value が未定義の状態でも入れることはできる。素直に person オブジェクトの name プロパティに入れてくれる。
const person = {} const propName = 'propName' person[propName] = 'Tak'
しかし obj[propName] で入れるときは propName が変数扱いなので、必ず先に定義する必要がある
特別な場合 -- obj, prop を取る関数が必要な場合
引数に応じてobj の中身を object[propName] のやり方で引き出す関数を実装する場合は
const person = { a: 'a', b: 'b', c: 'c', } const getObjProp = (obj, propName) => { return obj.propName } console.log( getObjProp(person, 'b') // undef );
obj.prop のやり方だと、変数だと解釈してくれないのでこれはダメだが
const getObjProp = (obj, propName) => { return obj[propName] } console.log( getObjProp(person, 'b') // b );
逆に obj[prop] のやり方だと、変数として解釈されるので、引数のプロパティにこのコードでアクセスできる。
よって関数で、中身を出しnたり入れたりするときは obj[prop] を使う必要がある。