#背景
なんとなくネットで調べてJavaScriptを書いています。
変数の宣言はvarで書くものだとばかり…信じて疑わなかったワタシ
調べた記事に謎の書き方を見かけることがあって
function( ) とか ( なんで関数の名前無いのー! )
=( ) => { とか ( 矢印って何なのー!記号だけとか怖すぎるー! )
こんな表記があったらページから離脱して、今までの知識で何とかなる方法で書き続けてきました。
最近関わり始めたプロジェクトで、上のような記号満載のコードを目の当たりにして
さすがにちゃんと理解しないとなーって調べたら超便利じゃーん!と思ったので書き残します。
#謎の =>
ワタシが最も苦手意識を抱いていた => コレ 矢印
矢印って認識は間違っていなく、弓矢の矢(英語でアローというらしい)
だから、=> はアロー関数というのを表しているらしいのですが、
これはES2015(ES6)というJavascriptの新しい書き方なんだとわかりました。
#ES2015(ES6)
ワタシが var 〇〇 って宣言してたのはES5というバージョンで書いてたってことで、
ESは**ECMAScript(エクマスクリプト)の略
2015年にバージョンアップしたからES2015という名称なんだけど通称ES6**とも言われている。
このES2015で色々追加されてとても素敵に書けるようになったってことみたいです。
ES2015以降は毎年改訂されて、ES+年号で呼ぶことになったらしい。(ES2016、ES2017...)
## サンプルのコード
順番に変えていった方が自分なりに分かりやすかったので、5パターン用意しました。
//1~5まで全部同じ挙動(5秒後にQiitaの記事を開くコード)です。
<!DOCTYPE html>
<html lang ="ja">
<head>
<meta charset ="utf-8">
<title>TEST</title>
</head>
<body>
<script type="text/javascript">//1.今まで書いていたコード
function openNewPage(){
window.open("https://qiita.com/tedkuma/items/6d4342232ca4433d2566","page");
}
window.setTimeout(openNewPage,5000);
</script>
<!-- <script type="text/javascript">//2.関数を変数に入れる
let newPage =function openNewPage(){
window.open("https://qiita.com/tedkuma/items/67f012b364dda4b03bf1","page");
}
window.setTimeout(newPage,5000);
</script> -->
<!-- <script type="text/javascript">//3.無名関数にする
let newPage =function(){
window.open("https://qiita.com/tedkuma/items/4d0f66443b1cefdd2392","page");
}
window.setTimeout(newPage,5000);
</script> -->
<!-- <script type="text/javascript">//4.アロー関数にする
let newPage =() => {
window.open("https://qiita.com/tedkuma/items/b98cc4d0dee782323096","page");
}
window.setTimeout(newPage,5000);
</script> -->
<!-- <script type="text/javascript">//5.関数の中が一文だけなら{}で囲まなくていいらしい
let newPage =() => window.open("https://qiita.com/tedkuma/items/91021e9160ef9ab38087","page");
window.setTimeout(newPage,5000);
</script> -->
</body>
</html>
###1.今まで書いていたコード
指定したURLを開くopenNewPageという関数を作りました。
setTimeoutで5秒後にopenNewPage関数が呼び出されます。
function 関数名( ){ 処理を記入 }
window.setTimeout( 関数名 , 秒数指定 );
function openNewPage(){
window.open("https://qiita.com/tedkuma/items/6d4342232ca4433d2566","page");
}
window.setTimeout(openNewPage,5000);
###2.関数を変数に入れる
ES2015で追加されたものに let と const があります。今までは何でもかんでもvarで宣言してましたが
ES2015(ES6)以降 変数はlet、定数はconstで宣言します。…ということで早速 let 使ってみました。
ここで上との違いは関数を変数に入れられるよってこと。
今まではsetTimeoutの引数に関数を入れてましたが関数が入った変数でも同じ動きをするらしいです。
let 変数名 = function 関数名( ){ 処理を記入 }
window.setTimeout( 変数名 , 秒数指定 );
let newPage =function openNewPage(){
window.open("https://qiita.com/tedkuma/items/67f012b364dda4b03bf1","page");
}
window.setTimeout(newPage,5000);
こんな感じでscriptタグでコメント切り替えて動作確認してみてください。
###3.無名関数にする
変数に関数を入れる(代入する)時は関数名を省略できるそうです。これを 無名関数 と言います。
…で、この無名関数を変数に入れる行為を 関数リテラル と呼びます。
関数リテラルって言葉も今まではピンと来てなかったので、これが分かって なるほどー!ってなりました。
あと、function( ){ って表記の苦手意識 やっとここで克服出来ました
let 変数名 = function ( ){ 処理を記入 }
window.setTimeout( 変数名 , 秒数指定 );
let newPage =function(){
window.open("https://qiita.com/tedkuma/items/4d0f66443b1cefdd2392","page");
}
window.setTimeout(newPage,5000);
###4.アロー関数にする
はい、ついに来ました。アロー関数です。これは更にfunctionを => に置き換えられるよってことです。
( )の前の function を消して( ) の後ろに => を書くと同じことが出来るんですー!凄いですよねー
let 変数名 = ( )=>{ 処理を記入 }
window.setTimeout( 変数名 , 秒数指定 );
let newPage =() => {
window.open("https://qiita.com/tedkuma/items/b98cc4d0dee782323096","page");
}
window.setTimeout(newPage,5000);
###5.関数の中が一文だけなら{ }で囲まなくてもいいらしい
そのままなんですけど、関数の中の処理が一文だけなら{ }中括弧は省略していいそうです。
順番に理解してきたら、たったの2行になりました。素敵~
let 変数名 = ( )=> 処理を記入
window.setTimeout( 変数名 , 秒数指定 );
let newPage =() => window.open("https://qiita.com/tedkuma/items/91021e9160ef9ab38087","page");
window.setTimeout(newPage,5000);
#配列を操作するときはmapメソッドが便利
あと、すごく便利だなーって思ったのがmapメソッドというものなんですが、
さっき出てきたアロー関数と組み合わせることで、めーちゃめちゃ簡単に配列の操作が出来ます。
## サンプルのコード
単純な配列と連想配列のmap&アロー関数使う時との比較で、4パターン用意しました。
//6~9まで全部同じ挙動(イベント名の配列に★マークを付けて画面に書出し)です。
<!DOCTYPE html>
<html lang ="ja">
<head>
<meta charset ="utf-8">
<title>TEST</title>
</head>
<body>
<script type="text/javascript">//6.今までの配列の加工
var event = ['仙台ハーフ','青葉まつり','仙台七夕','ジャズフェス','光のページェント'];
var result = [];
for(var i=0; i<event.length; i++) {
result.push("★"+event[i]);
}
document.write(result);
</script>
<!-- <script type="text/javascript">//7.mapメソッド&アロー関数使って配列の加工
const event = ['仙台ハーフ','青葉まつり','仙台七夕','ジャズフェス','光のページェント'];
const result = event.map(sendai => "★"+ sendai);
document.write(result);
</script> -->
<!-- <script type="text/javascript">//8.今までの連想配列の加工 for...in ループ
const event = [
{'category':'sports','day':'5/13', 'name':'仙台ハーフ'},
{'category':'festival','day':'5/19~20', 'name':'青葉まつり'},
{'category':'festival','day':'8/6~8', 'name':'仙台七夕'},
{'category':'music','day':'9/8~9', 'name':'ジャズフェス'},
{'category':'illumination','day':'12月(未定)', 'name':'光のページェント'},
]
const result = []
for (const key in event) {
result.push("★"+(event[key].name));
}
document.write(result);
</script> -->
<!-- <script type="text/javascript">//9.mapメソッド&アロー関数使って連想配列の加工
const event = [
{'category':'sports','day':'5/13', 'name':'仙台ハーフ'},
{'category':'festival','day':'5/19~20', 'name':'青葉まつり'},
{'category':'festival','day':'8/6~8', 'name':'仙台七夕'},
{'category':'music','day':'9/8~9', 'name':'ジャズフェス'},
{'category':'illumination','day':'12月(未定)', 'name':'光のページェント'},
]
const result = event.map(sendai => "★"+ sendai.name);
document.write(result);
</script> -->
</body>
</html>
###6.今までの配列の加工
空の配列に、for文で配列の要素数 = 回数分の処理(要素に★を結合して追加)する。
var 変数名1 = [ 配列 ];
var 変数名2 = [ ];
for( var i=0 ; i < 変数名1.length ; i++ ) {
変数名2.push( "★"+変数名1 [ i ] );
}
document.write( 変数名2 ) ;
var event = ['仙台ハーフ','青葉まつり','仙台七夕','ジャズフェス','光のページェント'];
var result = [];
for(var i=0; i<event.length; i++) {
result.push("★"+event[i])
}
document.write(result);
###7.mapメソッド&アロー関数使って配列の加工
map( ) を使うと今までfor文回してた処理がたったの1行で済んでしまいます。
コールバック関数・・・引数として渡される関数で、外側の関数で何らかの処理やアクションを実行する。
コールバック関数って解説だけだとイマイチよくわからないですよね。map( )の引数として渡されてます。
ワタシは 変数名.map( ) されたら、配列のコピーを作ってるんだー ってイメージしました。
…で、そのコピーに => やってほしい処理 書いているのだなーと ( 間違っていたらごめんなさい)
const 定数名1 = [ 配列 ];
const 定数名2 = 定数名1.map( コールバック関数名 => "★"+ コールバック関数名 );
document.write( 定数名2 );
const event = ['仙台ハーフ','青葉まつり','仙台七夕','ジャズフェス','光のページェント'];
const result = event.map(sendai => "★"+ sendai);
document.write(result);
###8.今までの連想配列の加工 for...in
連想配列っていうのは { key:value , key:value , key:value } みたいに
keyとvalueがペアになってる配列です。配列の中に入れてる内容はこんな感じです。
キーのところにkeyが取れています。 for...inして連想配列の指定したkeyに対するvalueを取得しています。
const 定数名1 = [ 連想配列 ];
const 定数名2 = [ ];
for ( const キー in 定数名1 ) {
定数名2.push( "★"+( 定数名1 [ キー ] .キーの指定 ) );
}
document.write( 定数名2 );
const event = [
{'category':'sports','day':'5/13', 'name':'仙台ハーフ'},
{'category':'festival','day':'5/19~20', 'name':'青葉まつり'},
{'category':'festival','day':'8/6~8', 'name':'仙台七夕'},
{'category':'music','day':'9/8~9', 'name':'ジャズフェス'},
{'category':'illumination','day':'12月(未定)', 'name':'光のページェント'},
]
const result = []
for (const key in event) {
result.push("★"+(event[key].name));
}
document.write(result);
###9.mapメソッド&アロー関数使って連想配列の加工
またしても値取り出して加工する処理が1行で済んでしまいました。map( )って素晴らしいですね。
const 定数名1 = [ 連想配列 ];
const 定数名2 = 定数名1.map( コールバック関数名 => "★"+ コールバック関数名.キーの指定 );
document.write( 定数名2 );
const event = [
{'category':'sports','day':'5/13', 'name':'仙台ハーフ'},
{'category':'festival','day':'5/19~20', 'name':'青葉まつり'},
{'category':'festival','day':'8/6~8', 'name':'仙台七夕'},
{'category':'music','day':'9/8~9', 'name':'ジャズフェス'},
{'category':'illumination','day':'12月(未定)', 'name':'光のページェント'},
]
const result = event.map(sendai => "★"+ sendai.name);
document.write(result);
まだES2015について理解していない部分が多いので、わかったら追記しようと思います。