筆者と当記事を書き始めた経緯について
当方、資格集めが趣味のエンジニアです。
資格の保有数は20種類に到達したんですが、いまだにJS関連の資格は持っていないし、仕事でVue.js
を書いたりすることもあるものの、JSがそんな得意なわけでもないといったところでJS系の資格の取得を検討しております。
一応、今狙ってるのはJS InstituteのJSE – Certified Entry-Level JavaScript Programmer Certificationという資格です。
こちらはめちゃくちゃ初学者向けの資格なんですが、受けられる言語が英語しかないので、英語のお勉強も兼ねてひとまずこの資格をターゲットとすることにしました。
JS自体は個人的な感覚にもなりますが、そこまで特殊な言語ではない(筆者が一番多用するのはJavaなので、無意識にJavaと比較してます)と思うんですが、それでも
「こんな仕様があるんだなぁ」
と勉強しながら思うことがあるので、忘れないうちに記載していこうと思います。
「いやいや、そんなんJS的には周知の挙動でしょ。つか、他の言語でも普通にある仕様でしょ。」と思われるかもしれませんが、ご容赦を。
当記事について
こちらの教材を使って勉強しているんですが、まだまだ教材を1周もしきってないので、初見の仕様に出くわす度に当記事は更新していこうと思います。
初見だったJavascriptの仕様
Hoisting
※Hoisting MDN
Hoisting
、和訳すると巻き上げとなるそうですが、これは
varで変数を宣言した場合に、その変数の宣言は当該変数の属するスコープの先頭にリライトされること
だそうです。
なので例えば、
下記のhoisting1.js
とhoisting2.js
は両方ともweight
を参照した際にReferenceError
を発生させるように見えますが、
var height = 180;
console.log(height);
console.log(weight);
var height = 180;
console.log(height);
console.log(weight);
var weight = 70;
console.log(weight);
実際の挙動は異なり、hoisting2.js
は実際に実行されるソースは下記のようになるため実際にはhoisting2.js
に限っては、undefined
とコンソールに出力されることになります。
var height = 180;
var weight;
console.log(height);
console.log(weight);
weight = 70;
console.log(weight);
単項プラス
※単項プラス演算子 MDN
皆さんは↓のソースの計算結果わかります?
const str1 = 42 + "1";
他の言語でもそうですが、文字列と何かを+演算子にかけると計算対象の値の両方が文字列として評価されます。
なので上記の計算結果は421
となります。
では"1"
を数値として扱って43
という計算結果を得るためにはどうしたらいいでしょう?
素直に考えたら
const str1 = 42 + Number("1");
が一番パッと出てくる解だと思いますが、実は↓でも同様の解を得られます。
const str1 = 42 + +"1";
僕は最初見たとき意味が分からなかったんですが、こちらはJavascriptの単項プラス演算子による働きのためによるものです。
単項プラス演算子は直後の値をNumber
型に変換します。
そのため"1"
がNumber
型になることで43
という解を得ることができるようになります。
因みに+"あ"
みたいなNumber
に変換できない値を引数として受けた場合はNaN
が戻り値となります。
Boolean型の複合代入演算子
他の言語でもよくある仕様なのか、これまで実務で使ったことないからわからないんですが、複合代入でよく使うのは数値型(JavascriptならNumber
)での複合代入だと思います。
let compoundAssignmentNum = 1;
compoundAssignmentNum += 1 // compoundAssignmentNum === 2
これは実務でも8000万回くらいつかってきたんですが、同様に複合代入がBoolean
でも行えます。
let compoundAssignmentBool = true;
compoundAssignmentBool &= false; // compoundAssignmentBool === false
// もちろんショートサーキットもいける
let compoundAssignmentBool = true;
compoundAssignmentBool &&= false; // compoundAssignmentBool === false
// ORも同様
let compoundAssignmentBool = true;
compoundAssignmentBool ||= false; // compoundAssignmentBool === true
論理積、論理和の戻り値
※論理積 MDN
※論理和 MDN
&&
(論理積)や||
(論理和)の戻り値は
-
&&
:両方のオペランドがtrue
の場合にtrue
を返却する、その他の場合はfalse
を返却する。 -
||
:両方のオペランドがfalse
の場合にfalse
を返却する、その他の場合はtrue
を返却する。
と認識していましたが、正確には挙動は少し違くて
-
&&
:最初に遭遇したfalsyなオペランドの値を返却し、すべてがtruthyな値の場合には最後のオペランドの値を返却する。 -
||
:最初のオペランドがtruthyな値の値の場合には、最初のオペランドの値を返却する。そのほかの場合は、2つ目のオペランドの値を返却する。
「いやいや、元々の解釈と何が違うのよ。一緒じゃん。」
と思うかもしれませんが、truthyな値、falsyな値ってのが、ミソなんですねぇ。
オペランドがBoolean
型の値なら想定通りの挙動なんです。
console.log(true && true); // --> true
console.log(true || false); // --> true
しかしながら、javascriptは以下の値をfalsyな値(≒false
)として扱います。
- false
- null
- NaN
- 0
- 空文字列 ("" または '' または ``)
- undefined
加えて、論理積、論理和が返却するのは、Boolean
型の値ではなく、あくまでオペランドの値です。
なのでオペランドがBoolean
型の値でない場合は以下のような戻り値を返却することになります。
console.log("Hello" && "World"); // --> "World"
console.log(1 && 2); // --> 2
console.log("Hello" || "World") // --> "Hello"
console.log(1 || 0); // --> 1
Boolean
のtrue
、false
とtruthy
、falsy
、ここら辺の解釈が厄介ですね。
でも今思うと、javascriptで空文字のチェックってif(string/*string型の変数*/)
とかでやってて、javascriptで空文字はfalsy
な値だから、先ほどのif文は空文字のチェックができるみたいなことを8000万回くらいやってたから、よくよく考えてみたらこのトピックの一部は既知の内容だったかもですね。
IIFE
※IIFE MDN
こちらは、Immediately Invoked Function Expression、略してIIFEです。
和名だと単純に即時実行関数式となります。
例えば↓です。
(function(){
let a = 'II';
let b = 'FE';
console.log(`${a}${b}`);
})();
関数を宣言すると同時に即時実行しています。
もちろん、アロー関数も使えます。
(() => {
let a = 'II';
let b = 'FE';
console.log(`${a}${b}`);
})();