セミコロン省略とASI
JavaScriptはセミコロン(;)を用いて文を終了させる言語である。しかし、セミコロンが省略された場合でもJavaScriptエンジンはAutomatic Semicolon Insertion(ASI)という機能によって、コードの適切な場所にセミコロンを自動的に挿入されるため、問題なくコードは実行される。
開発者の中には、この特性を活用してセミコロンを省略する書き方を好む者もいる。しかしながら、セミコロンの省略挟まざまな問題を引き起こす可能性がある。
問題の例
ASIが引き起こす予期せぬ結果
ASIが開発者の意図とは異なる動作を引き起こすことある。
以下はその一例である。
let a = 5
let b = 10
let c = 20
[a, b] = [b, a]上記のコードでは、aとbの値を交換するつもりで書かれている。しかしながら、セミコロンが省略されたために、JavaScriptエンジンは以下のようにこのコードを解釈する。
let a = 5
let b = 10
let c = 20[a, b] = [b, a]これにより、cが未定義のエラーが発生する。これはJavaScriptエンジンが20[a, b]をひとつの文と解釈した結果である。
return文とセミコロンの重要性
return文の直後に値を返さないケースもある。
function getValue() {
return
{ message: "Hello, world!" };
}この関数は意図とは異なり、期待するオブジェクト({ message: "Hello, world!" })ではなくundefinedを返す。これはASIによって、return文と{ message: "Hello, world!" }が別々の文として解釈されるためである(return;と解釈されているため、後続が評価されない)。
この問題を回避するには、return文の後ろに直接値を返す形にするか、または適切にセミコロンを使用する必要がある。
function getValue() {
return { message: 'Hello, world!' };
}IIFEとセミコロンの必要性
JavaScriptでは、即時関数(Immediately Invoked Function Expression: IIFE)というパターンが頻繁に使用される。しかし、セミコロンを省略すると、IIFEの前に書かれたコードが影響を受ける可能性がある。
その一例が以下の通り。
let name = "Dog"
(function() {
console.log(name)
})()上記のコードの場合、JavaScriptエンジンはこれを以下のように解釈するためエラーが発生する。
let name = "Dog"(function() {
console.log(name)
})()これを避けるためには、IIFEの前にはセミコロンを配置すべきである。
let name = 'Dog';
(function () {
console.log(name);
})();インクリメント/デクリメント演算子との不整合
インクリメント(++)やデクリメント(--)演算子との間で予期せぬ問題が発生することもある。
その一例が以下の通り。
let x = 5
let y = 10
x
++yこのコードでは、yをインクリメントしようとしているが、セミコロンの省略により、JavaScriptエンジンは以下のように解釈してしまう。
let x = 5
let y = 10
x++y