2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JS-分割代入ではまった話(初心者向け)

Last updated at Posted at 2025-01-11

まずは下記の簡単なコードをご覧ください。

  const array = [1,2,3,4]
  console.log(array[1], array[3])
  
  [array[1], array[3]] = [array[3], array[1]] //分割代入による値入れ替え
  console.log(array[1], array[3])

こちらですがconsoleにはどのように表示されるでしょうか?
期待されているのは

2 4
4 2

ですが、実際はエラーになります

2 4
test.js:3 Uncaught TypeError: Cannot set properties of undefined (setting '4')

これはJSの自動セミコロン挿入機能(Automatic Semicolon Insertion)によるものと思われます。本来、JSは文末にセミコロンを書くものでしたが、近年では省略しても自動補完してくれます(詳しくはこちら)。

しかし、この機能は前後の文で意図しない挙動になることがあるため、今回のケースではおそらく突然無名の配列に代入しようとしているように受け取られたのだと思います。

なお下記のようにセミコロンを分割代入の前の文末につければ問題なく動きます。

  const array = [1,2,3,4]
  console.log(array[1], array[3]); //セミコロン追加
  
  [array[1], array[3]] = [array[3], array[1]] //分割代入による値入れ替え
  console.log(array[1], array[3])
2 4
4 2

自動補完の挙動をしっかり読めない場合(私みたいな人)は元の仕様に則ってセミコロンをちゃんと書くスタンスのほうがいいと思います。

なお、私は本来セミコロンつける派にも関わらず、console.logを入れてちょっと確認するだけと省略してしまった、というなんとも間抜けなオチでした。(でもこの仕様は知らなかったので、勉強になりました。さすがにコードはもう少し複雑だったので、最初どこが原因かわからずけっこう焦りました。)

ちなみに文末がしっかりと明確であればいいので、セミコロンなしでもたとえば

  const array = [1,2,3,4]
  console.log(array[1], array[3])

  if(true)[array[1], array[3]] = [array[3], array[1]] //絶対に通るif文にする
  console.log(array[1], array[3])

とかでも動作します。こんな書き方する人いないとは思いますが、これでもちゃんと動いた、と一人でおもしろがってました。

2
1
1

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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?