LoginSignup
7
4

More than 3 years have passed since last update.

JavaScriptで「オブジェクトのプロパティが`undefined`である」ことと「オブジェクトにまだ割り当てられていないプロパティを取得すると`undefined`が返る」ことは違う

Posted at

JavaScriptで「オブジェクトのプロパティがundefinedである」ことと「オブジェクトにまだ割り当てられていないプロパティを取得するとundefinedが返る」ことは違う

const obj1 = {
    prop1: 'hello',
    prop2: undefined,
};

const obj2 = {
    prop1: 'hello',
};

obj1obj2で検証

違う

  • console.log
  • for-in文
  • Object.keys

console.log

console.log(obj1);
console.log(obj2);
{ prop1: 'hello', prop2: undefined }
{ prop1: 'hello' }

違う

for-in

for(const key in obj1) {
    console.log(`${key}: ${obj1[key]}`);
}

for(const key in obj2) {
    console.log(`${key}: ${obj2[key]}`);
}
prop1: hello
prop2: undefined
prop1: hello

違う

Object.keys

console.log(Object.keys(obj1));
console.log(Object.keys(obj2));
[ 'prop1', 'prop2' ]
[ 'prop1' ]

違う

違わない

  • 指定したプロパティへのアクセス
  • JSON.stringify

指定したプロパティへのアクセス

console.log(obj1.prop2);
console.log(obj2.prop2);
undefined
undefined

紛らわしさの発端

違わない

JSON.stringify

console.log(JSON.stringify(obj1));
console.log(JSON.stringify(obj2));
{"prop1":"hello"}
{"prop1":"hello"}

違わない

有効なJSONデータの値にundefinedが無いので当然

ところでundefinedとは

オブジェクトに割り当てられていないプロパティは undefined です (null ではありません)。

myCar.color; // undefined

でもオブジェクトのプロパティに対して明示的にundefinedを割り当てることはできる。

プロパティの追加・削除・存在確認

追加

JavaScriptではもともと無いプロパティを当然のように追加することができる。

obj1.prop3 = 'value';

削除

delete演算子を使う。

const obj1 = {
  prop1: 'hello',
  prop2: undefined,
}
console.log(obj1); // 消す前
delete obj1.prop1;
console.log(obj1); // 消した後
{prop1: "hello", prop2: undefined}
{prop2: undefined}

存在確認

指定したプロパティに直接アクセスしてundefinedかどうかを確かめる方法は、プロパティの存在確認には使えないことがわかった。

プロパティとして明示的にundefinedが割り当てられていることと、プロパティが割り当てられていないことが異なることがわかったので、その区別の仕方。

'propName' in obj1句を使う。

const obj3 = {
  prop1: undefined,
};
console.log('prop1' in obj3);
console.log('prop2' in obj3);
true
false

ただの感想

  1. 未割当のプロパティを取得した際にundefinedが返る: 納得
  2. プロパティに明示的にundefinedを割り当てられる: 納得
  3. 上2つを両立: ????

1か2、どちらかにしておくべきだったのでは。(TypeScriptやJavaやC#などなどでは1がコンパイルエラー)

2は、未割当のプロパティをとりあえず宣言したい場合に

obj1.prop3 = undefined;

みたいに書くためかもしれない?けど、それならdelete演算子と対になるような「プロパティ追加演算子」を用意すればよかったのでは。。

参考

7
4
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
7
4