Javascriptの特徴・記法をいくつかまとめてみました。
記法では、特に間違いやすいところを抜粋してます。
まず初めに
Javascriptとは、ブラウザー向けのスプリプト言語。
誤解を招きやすいが、JavaとJavaScriptは言語仕様に似た部分はあるものの、全くの別言語であり互換性もない。
Javascriptは、1995年にNetscape Navigator2.0で実装されたのを皮切りに、1996年にはInrernet Exploer3.0でも実装され、ブラウザー標準のスクリプト言語として定着した。
その後、20年程を経て、現在ではGoogleChrome、 Firefore、 Safari...など主要なブラウザのほとんどで実装されている。
##言語としての4つの特徴
######(1)スクリプト言語である
スクリプト言語とは、要は簡易であることを目的として作られたプログラミング言語のこと。
プログラミングが初めてとういう方でも短期間で習得することが可能。
その一方でオブジェクト指向的な構造も持ち合わせており、再利用・保守性に富んだコードも記述しやすいつくりになっている。
######(2)インタプリター型の言語である
インタプリター言語とは、プログラミングを先頭から逐一解析し、コンピューターに理解できる形式に翻訳しながら実行していく言語のこと。
そのためコンパイル言語に比べると動作が遅いという問題はあるが、反面、プログラムを実行するためにコンパイルのような特別な手続きじゃ必要ないというメリットがある。コードを書いてそのまま実行できる手軽さが魅力的。
######(3)さまざまな環境で利用できる
元々はブラウザー上で動作することを想定して作られた言語だが、現在はブラウザー上での用途にとどまらない。様々な環境で動作している。
Javascriptひとつ学んでおけば、その知識はブラウザーだけでなく様々な環境で活用できる。
######(4)いくつかの機能から構成される
Javascriptはいくつかの機能に分類できる。
環境に依存しない標準的な機能を提供する部分や、Javascript以外のプログラミング言語からドキュメントを動作的に操作できる凡庸的な仕様、ブラウザー上での操作を Javascriptから制御するための機能。。
このようにjavascriptは様々な要素から構成されている。
Javascriptの基本的な記法
<script>
要素
JavascriptのコードをHTMLに組み込むのは、<script>
要素の役割。
<script>
を記述する場所
######(1)<body>
要素の配下(任意の位置)
<script>
要素での処理結果をページに直接出力するために利用する。
コンテンツとコードが’混在するのは、可読性や保守性の観点から望ましくないため、現在ではほとんど使われていない、基本は使うべきではない。
######(2)<body>
要素の配下(</body>
閉タグの直前)
一般的なブラウザーでは、スクリプトの読み込みや実行が完了するまで、以降の描写は行わない。
このため、読み込みに時間がかかるスクリプトはそのままページ描写の遅れに直結する。
そこで、ページ高速化の方法としてページ末尾((</body>
閉タグの直前)に、<script>
要素を配置することが多い。
これによって、ページの描写を終えたと、徐にスクリプトの読み込み、実行が行われ、表示が早くなる。
######(2)<head>
要素の配下
ただし、(2)でまかなえないときがある。Javascriptでは「関数をよびだすための<script>
要素よりも。関数定義の<script>
要素を先に記述しなければならないというルールがある。
たとえば、<body>
の中で呼び出す必要のある関数は、<head>
要素の配下で直前に読み込んでおく必要がある。
まずは(2)を基本とし、それでまかえない場合のみ(3)を利用すると理解しておくとよさそう。
定数に入れるべきとき
######1.ただの数値は意味を表さない
例えば、下記のコード。
const price = 100
console.log(price * 1.08)
この1.08は誰にとっても理解しやすい数値、ではない。
一般的にただの数値は自分以外の人間にとっては意味を持たない、謎の値だと考えるべきで、定数にいれるべきである。
またこの値をマジックナンバーという。
######2.同じ値がコードに散在する
将来的には消費税は変わりうる。
そんなのとき、コードのあちこちに1.08が散在していると、検索&修正の手間がかかる。面倒であり、修正漏れでバグの原因にもなりうる。
そこで、1.08という値は定数に書き換えるのが良い。
const TAX = 1.08
const price = 100
console.log(price * 1.08)
定数の命名規則は、定数であることが分かりやすいように、全てを大文字&アンダースコアで区切るのが一般的。
データ型
数値、文字列、配列、オブジェクト、、などあるが
ここでは特に、よく間違えやすいundefinedとnullの違いを説明する。
######undefined(未定義)
undefinedはある変数の値が定義されていないことを表す値。
const obj = { a: 123 }
console.log( obj.d ) //結果;undefined
######null
Javascriptにはもう1つ、該当する値がないことを意味するnullという値が用意されている。
undefinedが、「定義されていない、そもそも参照することを想定していない」とういう状態を表すのに対し、
nullは、「空である」という状態を表す値。
例えば、文字列を表示するprint関数があるとする。関数はあくまで表示するためだけのもので、結果を期待されていないので、戻り値はundefinedとなる。
一方で、ページからアンカータグを取得するgetAnchor関数があるとする。
アンカータグが見つからなかった場合、undefinedは不自然。ここでは、該当する値がなかった=空だった」という値を意図して伝えようとしているので、nullを返すべき。
とはいえ、実際は区別が曖昧になる。
まずは、意図した空を表すにはnull、そうでなければundefinedという大まかな区別を覚えておくと良さそう。
演算子
いくつか抜粋して下記に書きます。
####1.小数点を含む計算に注意
以下は、ごく当たり前の少数計算であるのに、正しい結果を得られないケース。
console.log(0.2 * 3) //結果;0.6000000000000001
これは、Javscriptnが内部的には数値を10進数でなく、2進数で演算しているための誤差。
同様に、以下はfalseとなる。
console.log(0.2 * 3 === 0.6) //結果;false
少数を含む計算で厳密に結果を得る必要があるとき、または値の比較をするときは、下記のようにすると良い。
1 値を一旦整数にしてから演算する
2 1の結果を再び少数に戻す
console.log((0.2 * 10) * 3 / 10) //結果;0.6
####2.比較演算子
######(1)等価演算子(==)
==演算子は、左辺・右辺の値を比較し、等しい場合にtrue、等しくない場合にfalseを返す。
が!しかし
以下のようにデータの型によって比較の基準が異なるので、注意が必要。
左辺・右辺の型 | データ型 | 評価基準 |
---|---|---|
同じ | 文字列・数値・論理型 | 単純に双方の値が等しいかを判定 |
同じ | 配列・オブジェクト | 参照先が等しいかを判定 |
同じ | null・undefined | 双方ともnull,undefinedまたはnullとundefinednの比較は全てtrue |
異なる | 文字列・数値・論理 | 文字列・論理型を数値に変換した上で判定 |
異なる | オブジェクト | 基本型に変換した上で判定 |
==演算子は、「データ型が異なる場合にもデータ型を変換して、『なんとか等しいと見做せないか』と試みる」ということ。
例えば、下記はtrueになる。
console.log(1 == true) //true
ただし、比較対象が配列やオブジェクトなどのいわゆる参照型同士である場合には要注意!
const data1 = ['a', 'b', 'c']
const data2 = ['a', 'b', 'c']
console.log(data1 ==data2) //false
基本型では変数に値を直接格納するのに対し、
参照型ではその参照値が格納される。
そして、==演算子で参照型を比較する場合は、参照値、メモリ上でもアドレスが正しい場合のみtrueを返す。
なので、見た目上は同じオブジェクトであっても、それが異なるオブジェクト(異なるアドレスに登録されたもの)であれば、等価演算子はfalseを返す!
######(2)同価演算子(===)
上記の==演算子が、邪魔になる場合がある。
例えば以下は必ずtrueにされてしまう。
console.log('2,1467' == 2) //true
console.log('0x0' == 16) //true
このような時に使用するのが===演算子。
===演算子では、上記のconsole.logは全てfalseになる。
ただし、===演算子では、'1'と「1」のように一見同じに見えるリテラルも異なるものとみなされてしまうので注意。
より大規模なアプリを開発する上では、Javascriptの寛容さはかえってバグの元になりうるので、値の比較はなるだけ===演算子を使うと良い。
######(3)ショートカット演算子
例えば
&&演算子の場合、左辺がfalseと評価された時点で右辺が読まれずに条件式全体がfalseになる。これがショートカット演算子。
この時、1と2は同じ意味合いになる。
if ( x == 1) cosole.log('こんにちは') //1
x == 1 && cosole.log('こんにちは') //2
しかし、②のような記述は原則として避けるべきである。
「条件分岐であることが一見して分かりづらいこと」、そもそも「右辺が実行されるかどうかが曖昧になるため、思わぬバグの温床になりかねない」から。
基本は
論理演算子の後方は、関数の呼び出し・インクリメント/デクリメント演算子・代入演算しなど、値を実際に操作するような式を含めるべきではない
####3.制御構文
######switch構文
if文で書くには条件が冗長すぎるときに使う。
switch(式){
case 値1 :
式=値1の時に実行される命令
case 値2 :
式=値2の時に実行される命令
....
default:
式の値が全ての値に合致しない場合に実行される命令
}
以下の順で実行されている
1 先頭の式をまず評価
2 1の値に一致する case句を実行
3 一致するものが見つからない場合には、最終的にdefault句を呼び出す
基本breakは書くべき。
条件に合致するものが見つかり、実行されたとしても、その句を終えても、十同的にswitchブロックを終了するわけではない。
breakを指定しない場合は、次のcaseブロックが続けて実行されてしまい、意図した結果にならないことがある。
基本はbreakを書くこと!
ただし、例外として、
switch(式){
case 値1 :
case 値2 :
case 値3 :
console.log("yay!")
break;
case: 値4 :
console.log("booo")
break;
....
default:
式の値が全ての値に合致しない場合に実行される命令
}
いずれかにが合致するブロックを表現したい場合、このように空caseブロックを列記する。
1,2,3いずれがである場合、「yay!」というメッセージを、4の場合はboooが表示される。
👉注意点
switchの式とcase句の値は==演算子ではなく、===演算子で比較されているので注意!
下記でcase0は実行されない!
const x = '0'
switch(x){
case 0 :
命令 //実行されない
case 値2 :
命令
....
default:
式の値が全ての値に合致しない場合に実行される命令
}