JavaScriptの勉強始めたけど、なんか基本が抜けている気がするなー
本記事では、そんな悩みをもった方向けにJavaScriptの基本についてまとめました。
僕も、JavaScriptに苦手意識があるのですが一緒に勉強してプログラミングを楽しみましょー!
本記事の信頼性
30歳から異業種への転職をして、Shopify Experts企業で1年半ほどフルリモートで勤務していました。
現在は名古屋の自社開発企業のフロントエンドエンジニアしています。フリーランスとしても活動しています。
変数の宣言(var, let, const)
一応説明しておくと、変数=値が変わるもので定数=値が変わらないものということは理解しておくといいですね。
変数・定数 | 再代入 | 再宣言 |
var | ○ | ○ |
let | ○ | ✕ |
const | ✕ | ✕ |
var(再代入=可能 / 再宣言=可能)
かなーりゆるい変数だという認識でOKです。後述するlet
, const
ができてからは使う必要がなくなったみたいです。
ですが、実際業務をしていると結構コードでvar
を使われているのを見ます。
ただ今後新規で開発するときには使わないようにしたほうがいいみたいですね。
// 再代入 = 可能
var hoge = 'おはよう'
hoge = 'こんにちは'
console.log(hoge); //こんにちは
// 再宣言 = 可能
var hoge = "おはよう";
var hoge = "こんにちは";
console.log(hoge); //こんにちは
let(再代入=可能 / 再宣言=不可)
var
よりも少し厳しくなります。
再宣言不可ということで実際に宣言してみるとSyntaxError(構文エラー)で
”もうその変数は使われているよ〜”
と怒られてしまいます。
// 再代入 = 可能
let hoge = "おはよう";
hoge = "こんにちは";
console.log(hoge); //こんにちは
// 再宣言 = 不可
let hoge = "おはよう";
let hoge = "こんにちは";
console.log(hoge); //エラーがでる
const(再代入=不可 / 再宣言=不可)
定数なので値が変わることがないです。
Reactの勉強をしているとだいたいconst
が使われています。変わってしまう危険性があるものは使わずに一度決めたものはずっと使っていこうぜって感じ?
プロジェクトが大きくなったときに恩恵を受けるのかなと。(僕はそんなプロジェクトやったことないのでいまのところ恩恵受けておらず、、w)
再代入をしようとすると
const hoge = "おはよう";
hoge = "こんにちは";
console.log(hoge);
読み取り専用だーと怒られます。
次に、再宣言を試すと、
let
のときと同様に、定数hoge
は既に宣言されているよーと怒られます。
ここまでで、変数・定数の基礎理解はできたと思います。
せっかくなので少し深ぼってみます。
JavaScriptの変数は2つのデータ型に分類されます。
左がプリミティブ型。右がオブジェクト型。
ここで大切なのがオブジェクトでは、const
で定義していても中身を書き換えることができるということです。
const hoge = {
name: "オカ",
age: 31
};
console.log(hoge.age); //31 が表示される
hoge.age = 32;
console.log(hoge.age); //32 が表示される
ちょっと応用で定数で定義された年齢をオブジェクト内で定義したメソッドで更新してみます。
const hoge = {
name: "オカ",
age: 31,
addAge: function () {
hoge.age++;
}
};
console.log(hoge.age); //31
hoge.addAge();
console.log(hoge.age); //32
オブジェクト内で定義したメソッドを実行するときはhoge.func()
のように()
が必要なのです。
ここまで行ったことは、こちらにまとめてありますので自分で少し書き換えたりして遊んでみてください。
関数の宣言と実行
関数=特定の処理をまとめておいて、いつでも呼び出せるようにしておくといった理解をしておきましょう。
フロントエンジニアは基本アロー関数 (=>
こういうやつ)を使えば良さそうですが、長く使われてきた書き方についてもまとめて紹介します。
関数宣言
たぶん一番ポピュラーな書き方。
function hoge1() {
console.log("関数宣言ですー");
}
hoge1(); 関数宣言ですー //関数宣言ですー
関数式(関数リテラル)
関数を宣言する際に、関数名を省略できる書き方。関数を変数の値として代入する書き方で無名関数と呼ばれていたりします。
const hoge2 = function () {
console.log("関数式ですー");
};
hoge2(); //関数式ですー
引数に値をいれてみるパターン。
const hoge3 = function (age) {
console.log(age + "歳です");
};
hoge3(31); //31歳です
またreturn
というものも触れておきましょう。
const hoge4 = function (radius) {
//実行される処理
const calcArea = radius * radius * 3.14;
//戻り値
return calcArea;
};
const area = hoge4(10);
console.log(area); //314
ここでは、半径を求める関数を作成しています。
radius
という引数が、実行される処理のなかに渡されます。
そこで実行された処理(半径×半径×3.14)がcalcArea
として定義され、戻り値として返却されます。
新たにarea
を定義して、定数のhoge4
の引数に10を渡して、console.log
で吐いて中身を確認すると314となっています。
ちょっとややこしいですが、自分でコードを書いて実行してみると腑に落ちてくるのでぜひやってみてください〜
アロー関数
弓矢っぽくみえるからアロー関数と呼ばれているそうです。ES2015から導入されたので比較的新しい書き方ですね。
まずは、基本の書き方をみてみます。
const hoge5 = () => {
console.log("アロー関数ですー");
};
hoge5(); //アロー関数ですー
引数ありのパターン
const hoge6 = (name, lang) => {
console.log(name + "は" + lang + "を勉強中です");
};
hoge6("オカ", "アロー関数"); //オカはアロー関数を勉強中です
Raise Tech内で教わっったアロー関数の特徴についてもまとめておきます。
こんな書き方あるんだなぁと知っておけば、いざ現場で出会ったときにビックリすることもないので抑えておくとよさそう。
※codesandboxだと自動補完されてしまうため記事内のコードと異なっていることがあります。
■引数が1つのときは省略可能。引数が2つのときは()が必要。
const hoge7 = name => {
return name + "です。";
};
console.log(hoge7("オカ")); //オカです。
const hoge8 = (name,age) => {
return name + "です。"+ age + "歳です。";
};
console.log(hoge8("オカ","31")); //オカです。31歳です。
■処理が1行で終わるときは、{} とreturn が省略可能。
const hoge9 = (name) => name + "です";
console.log(hoge9("省略可能なオカ")); //省略可能なオカなです
演算子
比較演算子
足し算・引き算・掛け算・割り算のことをいいます。むずかしくないのでさらっと。
// 四則演算子
const num1 = 10 + 20;
console.log(num1) //30
const num2 = 100 - 20;
console.log(num2) //30
const num3 = 4 * 3;
console.log(num3) //12
const num4 = 12 / 3;
console.log(num4) //4
const num5 = 50 % 20;
console.log(num5) //10
ちょっと気をつけないといけないのが、インクリメント演算子とデクリメント演算子です。
インクリメント演算子
++
で1を足すという処理をするのですが、記述位置によって評価するタイミングが異なります。
let num6 = 20;
//num6に先に1をプラスする
console.log(++num6) //21
let num6 = 20;
//num6にあとで1をプラスする
console.log(num6++); //20
console.log(num6) //21
デクリメント演算子
こちらも上記と同様の考え方です。
--
で1を引くという処理をするのですが、記述位置によって評価するタイミングが異なります。
let num7 = 20;
console.log(--num7); //19
let num7 = 20;
//num7にあとで1をマイナスする
console.log(num7--); //20
console.log(num7); //19
比較演算
これはも割と理解しやすいかなと思います。
==
と ===
は同じなのかを比較するのですが、===
を基本は使ったほうがよいです。
===
のほうが厳密に判定してくれるみたいですね。num1
は数値で、str1
は文字なのですが、==
だとtrue判定されてしまうのですが、===
だとfalse判定で正しく判定されます。
const num1 = 10;
const str1 = "10";
console.log(num1 == str1); //true
console.log(num1 === str1); //false
補足ですが、こんな感じでtypeof演算子を使うと変数に何が入っているか確認できます。
console.log(typeof num1); //number
console.log(typeof str1); //string
!=
と !==
は異なるかどうかを比較するのですが、上記と同様の理由で!==
を使ったほうがよいですね。
const num2 = 10;
const str2 = "10";
console.log(num2 != str2); // false
console.log(num2 !== str2); //ture
論理演算
「&&(かつ)」 と「||(または)」と「!(でない)」
まずは&&
をみていきます。if
の()のなかがtrue
なら{}
が実行されるのですが、()の中身をみるとtrueFlag
とfalseFlag
をみておりfalseFlag
がfalse
となっているので実行されません。
||
はまず左辺をみてfalse
判定されている場合には、右辺を返します。 ややこしいのですが、trueFlag
がtrue
判定なのでここではfalse
判定されてしまうのです。
const trueFlag = true;
const falseFlag = false;
// &&(かつ)左辺がtrueなら右辺を返す(
if (trueFlag && falseFlag) {
console.log("実行されない");
}
// ||(または)左辺がfalse判定なら右辺を返す(
if (trueFlag || falseFlag) {
console.log("実行される");
}
そして、この説明だと&&と||はtrue
かfalse
を見てくれるものなのねと思ってしまうのですが、実は違っております。
詳しく知りたい人はこの記事を読むといいかなと思います。
https://qiita.com/isoken26/items/de2de485288b3913e90f
そして、!
は否定の意味を持ちます。
flaseFlag
(false)の反対ならtrue
となるため、{}
内が実行されます。
const trueFlag = true;
const falseFlag = false;
if (!falseFlag) {
console.log("実行される");
}
三項演算子(A ? B : C)
こちらが基本の構文です。
変数 = 条件式 ? trueの時の値 : falseの時の値 ;
では、実際に適当なコードを書いてみていきます。
// 3項演算子
const calcNum = Math.random() * 100 > 50;
const check = calcNum ? "larger" : "smaller";
console.log(calcNum);
console.log(check);
1行目のMath.random()
で0以上1未満の乱数を生成します。
半分の確率でMath.random() * 100
は50以上の数字になりますね。
そして、2行目でcheck
でcalcNum
の数字がtrue
であればlarger、 false
であればsmallerと判定させるようにしております。
3行目、4行目でconsole.log
に値を吐いて、実際に確認している感じですね。
例)70が生成されたたら、true
になる。true
なのでlargerが表示される。
制御構文
条件分岐や繰り返し処理などのことを制御構文というみたいです。知らなかった〜。
結構重要なのでしっかり理解していきましょー。
for / while
for文は現在はほとんど使われないようです。下にサンプルおいておきますが文章が長くて分かりづらいですよねぇ。
基本の構文
for ([初期化式]; [条件式]; [加算式])
基本の形です。
0からはじまり100回繰り返すので、99まで出力されます。
for (let i = 0; i < 100; i++) {
console.log(i);
} //0 1 2 3 ..... 99
配列のパターン
names
に配列が定義されております。
let names = ["田中", "山田", "佐藤"];
for (let i = 0; i < names.length; i++) {
console.log(names[i]);
}
//田中
//山田
//佐藤
そして、配列だとfor of文というものも使えるみたいです。
let names = ["田中", "山田", "佐藤"];
for (let name of names) {
console.log(name);
}
//田中
//山田
//佐藤
while文
let number = 1;
while (number <= 10 ){
console.log(number);
number++;
}
//1
//2
//3
//4
//5
//6
//7
//8
//9
//10
while文 〜応用編〜
let flag = true;
while (flag) {
// 0〜9までの乱数を代入
let num = Math.floor(Math.random() * 10);
console.log(num);
// 乱数が1になったら繰り返しを抜ける
if (num === 1) flag = false;
console.log(num);
}
こういう色々な書き方ができると結局何を使えばいいのとなってしまうタイプです。。
if else
これはめちゃくちゃ使います!僕もShopifyの受託開発でliquidファイルを触るのですが、よく使う構文です。
言語関係なく頻出なので覚えておきましょう!
country
の中身が日本だったらこんにちはと表示されます。もし、タンザニアだったらジャンボ!!と表示されます。
それ以外の国だったら、Helloと表示されるといったコードになります。
const country = "日本";
if (country === "日本") {
console.log("こんにちは");
} else if (country === "タンザニア") {
console.log("ジャンボ!!");
} else {
console.log("Hello");
}
//こんにちは
ただ、同じもの(今回だと国)を評価するときにif else
で確認していくのはいけていないみたいです。
そのときに便利なのが、次で紹介するswitch文
となります。
switch
ある変数(country
)の値に応じて、処理が分岐されます。
const country = "日本";
switch (country) {
case "日本":
console.log("こんにちは");
break;
case "タンザニア":
console.log("ジャンボ!!");
break;
default:
console.log("Hello");
break;
}
//こんにちは
breakがないと判定が続いてしまいます。
const country = "日本";
switch (country) {
case "日本":
console.log("こんにちは");
case "タンザニア":
console.log("ジャンボ!!");
default:
console.log("Hello");
}
// こんにちは
// ジャンボ!!
// Hello
コンソールでもcase
の前にはbreakをつけろよーと教えてくれるので問題ないかなぁと。
Breakがないと処理が続くということで、case “タンザニア”とdefault:と行が無視されて、console.logが吐かれているということなのかな?
ちょっとここの理解が怪しい。。
try catch
例外処理を行うための構文となります。
まず、try
のなかの処理1が実行されます。その中でエラーが起きなければ、この文の処理は終了になります。ただ今回はalert(hoge)
のhoge
が定義されていないため、処理1は中断されて、処理はcatch
の中の処理2に移行します。
処理2でhoge is not defiend
がコンソールで吐かれます。
try {
// 処理1
alert(hoge);
throw new Error("例外発生");
alert("hogehogehoge");
} catch (error) {
// 処理2
console.log(error.message);
}
こちらのパターンもみていきます。
// パターン2
try {
// 処理1
console.log("パターン2");
throw new Error("例外発生");
alert(hogehogehoge);
} catch (error) {
// 処理2
console.log("エラーがでたーーーーーー!");
console.log(error.message);
}
//コンソール結果
//パターン2
//エラーがでたーーーーーー!
//例外発生
まず、tryのなかで処理が走ります。console.log("パターン2");
は問題なく処理されます。
throw new Error("例外発生");
でErrorコンストラクターでエラーオブジェクトを生成します。
throw文で例外として投げられたオブジェクトは、catch文でアクセスできるようになります。
処理2に移行して、console.log("エラーがでたーーーーーー!");
の処理後に、console.log(error.message);
で先程生成したErrorオブジェクトのなかみに格納したmessageを表示させている感じです。
Errorオブジェクトを生成して、引数のmessageに”例外処理”を入れた感じかな?すんません、ちょっと理解が怪しい…
まとめ
いやー、改めてJavaScriptの基本文についてまとめてみると非常に勉強になりました。
なかなか自分でだとこうやってまとめよーっという気持ちになれないので、課題とかでだされてやらなければいけない状況に身を置くのはいいですね!
今後も、JavaScriptやReactについて学んだことなどを記事でまとめていきますー!