どうも。つじけ(tsujikenzo)です。このシリーズでは2021年8月からスタートしました「ノンプロ研EffectiveJavaScript輪読会」についてお送りします。今日は第7回目です。
前回のおさらい
前回は、「型が異なるときに==を使わない」をお届けしました。
今回は、「セミコロン挿入の限度を学ぼう」 をお届けします。
テキスト第1章「JavaScriptに慣れ親もう」の項目6に対応しています。
今日のアジェンダ
- セミコロン挿入ルール1
- セミコロン挿入ルール2
- セミコロン挿入ルール3
セミコロン挿入ルール1
セミコロン 挿入 のルール1は以下の通りです。
– “}” トークンの前
– 1個以上の改行の後
– プログラム入力の末尾
言い換えると、セミコロンを 省略 できるのは、以下に限られます。
– 行(ステートメント)末
– ブロック末尾
– プログラム末尾
なので、このように記述できるセミコロンの省略と、記述できない省略があります。
function myFunction1_6_02() {
const square = x => {
var n = +x
return n * n
}
const area = r => { r = +r; return Math.PI * r * r }
const add1 = x => { return x + 1 }
const x = 10;
const r = 10;
console.log(square(x)); //100
console.log(area(r)); //314.1592653589793
console.log(add1(x)); //10
//保存すらできない
//const area2 = r => { r = +r return Math.PI * r * r }
}
セミコロン挿入ルール2
セミコロン 挿入 のルール2は以下の通りです。
– 次の入力トークンを字句解析できないときだけ
例文で見てみましょう。
function myFunction1_6_03() {
let a = 10;
const b = () => { return '私はb関数の戻り値です' };
const f = () => { return '私はf関数の戻り値です' };
//正しく解析される(セミコロンは挿入されない)
a = b
(f());
console.log(a); //私はb関数の戻り値です
//以下と等しい
a = b(f());
console.log(a); //私はb関数の戻り値です
//2つのステートメントとして解釈される
a = b
f();
console.log(a); //[Function: b]
console.log(f()); //私はf関数の戻り値です
}
とくに、ステートメントの先頭が、(, [, +, -, /, の5つである時は、1つ上の行にセミコロンがあるかどうか 注意が必要です。
配列と、正規表現を例に見てみましょう。
テキストでは、正規表現が除算になると書かれていましたが、オートフォーマットをすると、その理由がわかるでしょう。
function myFunction1_6_04() {
//正しく解析される
let a, b;
['a', 'b', 'c'].forEach(element => console.log(element)); //a,b,c
//保存はできるが、エラーが発生する
// a = b
// ['a', 'b', 'c'].forEach(element => console.log(element)); //TypeError: Cannot read property 'forEach' of undefined
//正しく解析される
const fail = () => console.log('右辺のfailをtryします');
let str = 'Hokkaido';
/love/i.test(str) && fail(); //ログなし
/ai/i.test(str) && fail(); // //右辺のfailをtryします
//除算する(オートフォーマットするとわかる)
const ai = 100;
const i = /tsujike/;
a = b
/ai/i.test(str) && fail();
console.log(a); //NaN
}
セミコロン挿入ルール3
セミコロン 挿入 のルール3は以下の通りです。
– forループ頭部の区切りとして暗黙的に挿入されない
– 本体が空のループに挿入されない
for文の歴史を解説しましたLT(いつかブログにUPします)で紹介しましたが、条件式は省略できますが、セミコロンは省略できません。
function myFunction1_6_05() {
//for文の条件式内のセミコロン
for (; ;) {
console.log('無限ループ');
break; //阻止
}
//whileの本体が空の末尾
//保存すらできない
// const infinityLoop = () => {while(true)}; //構文エラー: SyntaxError: Unexpected token '}'
const infinityLoop = () => { while (true); };
}
実務で意識するなら
実務を意識するなら、ずばり 「セミコロンは省略しない」 が正解です。
ほとんどのステートメント末尾には、セミコロンを付けます。
セミコロンをつけないのは、以下の3つです。
– for文やwhile文やfunctionなどのブロックスコープの末尾
– 文字列やカンマ区切りの配列、オブジェクトなどの要素の改行
– 戻り値やプロパティを利用したチェーン記法
function myFunction1_6_06() {
//制御構文や関数宣言の末尾
for (const value of []) { }
while (true) { break }
//関数リテラルは式の中で宣言された関数なのでセミコロン必要です。
const func = () => { };
//要素の改行
const array = [
'a',
'b',
'c'
]
const obj = {
x: 10,
y: 20,
z: 30
}
const msg = `お疲れ様です。
退社します。
今までお世話になりました。
「そっちの退社かい!」`;
//チェーン記法
const value = '東京オリンピック'
.replace('東京', '北京')
.replace('オリン', 'パラリン');
console.log(value); //北京パラリンピック
}
基本はリーダブルコード
このような書き方ができることを今回学びましたが、正直、読み辛いです。。。ワンライナーで書こうとせず、改行できる人間になりましょう。
function myFunction1_6_07() {
//ワンライナーを意識しすぎるのはダメ
const area = r => { r = +r; return Math.PI * r * r }
//改行した読みやすいコードこそイケメンです
const area2 = r => {
r = +r;
return Math.PI * r * r;
};
}
まとめ
以上で、「セミコロン挿入の限度を学ぼう」をお届けしました。
われわれGASノンプログラマーにとって、JavaScriptのセミコロンは省略しないほうがいいでしょう。
さらに、読みやすさの点では、新IDEではワンライナーで書いたり、縦に長い記述を防ぐ必要はあまりなくなってきました。
オートフォーマット(通称ぐわし)や、関数の折りたたみを積極的に利用しましょう。
次回は、「文字列は16ビットの符号単位を並べたシーケンスとして考えよう」 をお届けします。
このシリーズの目次
[EffectiveJavaScript輪読会]ノンプロ研EffectiveJavaScript輪読会とは
[EffectiveJavaScript輪読会]どのJavaScriptをつかっているのかを意識しよう
[EffectiveJavaScript輪読会]JavaScriptの浮動小数点を理解しよう
[EffectiveJavaScript輪読会]暗黙の型変換に注意しよう
[EffectiveJavaScript輪読会]オブジェクトラッパーよりもプリミティブが好ましい
[EffectiveJavaScript輪読会]型が異なるときに==を使わない
[EffectiveJavaScript輪読会]セミコロン挿入の限度を学ぼう
[EffectiveJavaScript輪読会]文字列は16ビットの符号単位を並べたシーケンスとして考えよう