##はじめに
先日勉強会に参加したところES6の話題が多かった印象を受けたので、勉強会で出てきた言葉を元に少し調べました。
js自体がまだちゃんと書けていない私としては、ES6を学ぶのはしんどいですが、いつか輝く為に少しずつ学ぼうと思います。
##Template literal
Template literalを使うと、文字列の連結をスッキリかけるようになります。
+
やjoin()
を使わなくてもいいのです!
やり方は、${}
と`
(バッククオート)を利用して文字列の連結を行います。
バッククオート内の${}
の中が評価され、その結果が置き換わります。
#####ES5
var str1 = 'スーパー';
var str2 = '合体';
var str = 'Template literalで文字列の' + str1 + 'の' + str2 + '!';
console.log(str);//Template literalで文字列のスーパーの合体!
#####ES6
var str1 = 'スーパー';
var str2 = '合体';
var str = `Template literalで文字列の${str1}の${str2}!`;
console.log(str); //Template literalで文字列のスーパーの合体!
###式を評価して表示
${}
の中には変数だけでなく式をいれることができます。
#####ES5
var str = 5 * 5 + "は" + (5 + 5 + 5 + 5 + 5) + "!";
#####ES6
var str = `${5*5}は${5+5+5+5+5}!`;
##Default parameters
JavaScriptでの、関数の引数は、undefinedが初期値となります。
ES5では、引数の初期値を自由に設定することができなかった為、関数内で引数をチェックして、
undefinedなら初期値を設定するようなことをやってました。
ES6からは、下記例のように引数の初期値を設定できます。
#####ES5
function defaultParameters(a) {
var b = arguments.length <= 1 || arguments[1] === undefined ? 'あるとうれしい!' : arguments[1];
return a + b;
}
var str = defaultParameters('初期値が');
console.log(str); //初期値があるとうれしい!
#####ES6
function defaultParameters(a, b = 'あるとうれしい!') {
return a + b;
}
var str = defaultParameters('初期値が');
console.log(str);//初期値があるとうれしい!
##Rest parameters
今まで引数が可変の(いくつ渡ってくるかわからない)場合、argumentsを使用してやりくりしていましたが、Rest parametersを使用すれば、引数を可変長で受け取ることができます。
#####ES5
function rest() {
for (var _len = arguments.length, values = Array(_len), _key = 0; _key < _len; _key++) {
values[_key] = arguments[_key];
}
console.log(values);
}
rest(1, 2, 3);//[1,2,3]
#####ES6
function rest(...values) {
console.log(values);
}
rest(1,2,3);//[1,2,3]
Rest Parametersのルールとして、引数の最後で渡す必要があります。
下記の場合、可変長引数の...values
が第1引数として設定されている為、エラーとなります。
function rest(...values,value) {
console.log(values);
}
下記ばOK。
function rest(value,...values) {
console.log(values);
}
##Spread operator
Spread operatorを使うと配列同士を結合したりする場合に便利です。
#####ES5
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
var arr3 = [].concat(arr1, arr2);
arr1.push.apply(arr1, arr2);
console.log(arr1); // [0, 1, 2, 3, 4, 5]
console.log(arr3); // [0, 1, 2, 3, 4, 5]
#####ES6
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
var arr3 = [...arr1,...arr2];
arr1.push(...arr2);
console.log(arr1); // [0, 1, 2, 3, 4, 5]
console.log(arr3); // [0, 1, 2, 3, 4, 5]
##Destructuring
Destructuringは分割代入という、新しい変数代入の方法です。
#####配列で受け取る
var [a,b] = [1,2];
console.log(a,b)//1 2
var [a, b, ...rest] = [1, 2, 3, 4, 5];
console.log(a,b,rest)//1 2 [3,4,5]
#####関数の戻り値で受け取る
var [a,b] = (function(){return [1,2];})();
console.log(a,b)//1 2
#####一部省略や、デフォルト値を設定する
var [a,,[b,c],d=5] = [1,2,[3,4],5];
console.log(a,b,c,d);//1,3,4,5
####オブジェクトで受け取る
var obj = {name:'太郎',sex:'男',age:30};
//必要なプロパティだけ代入
var {name:n,age:a} = obj;
console.log(n,a)//太郎 30
上記をES5で書くとこんな感じ。こっちのほうがわかりやすいような気がするのは、私が未熟なせいでしょう。。。
#####ES5
var obj = { name: '太郎', sex: '男', age: 30 };
var n = obj.name;
var a = obj.age;
console.log(n, a); //太郎 30
##Blockscope
###let
letを使うことで、関数スコープでなく、ブロックスコープを使用することができます。
#####letを使った場合
if(true){
let a = 1;
console.log(a);//1
}
console.log(a);//error
#####varを使った場合
if(true){
var a = 1;
console.log(a);//1
}
console.log(a);//1
ES5の場合は即時関数を利用してスコープをつくってました。
var a = 0;
(function(){
var a = 1;
console.log(a);//1
})();
console.log(a);//0
ES6はletを使うことでスコープの範囲がわかりやすくなりました。
var a = 0;
{
let a =1;
console.log(a);//1
}
console.log(a);//0
###関数宣言をブロックスコープ内に定義
関数宣言もブロックスコープ内に定義することができます。
{
function block(){return 1;}
console.log(block());//1
{
function block(){return 0;}
console.log(block());//0
}
console.log(block());//1
}
##const
定数を定義することができます。
const a = 1;
console.log(a);//1
//再定義はエラーとなる
const a = 1;//error
//代入は無視される
a = 0;
console.log(a);//1
##Arrow Function
アロー関数を使用することで、関数の定義が短くかける。
#####ES5
[1, 2, 3].map(function (v) {
console.log(v);
});
#####ES6
//引数が一つの時には「(v)の()」を省略できる
[1,2,3].map(v=>{console.log(v);});
//下記でもOK
//[1,2,3].map((v)=>{console.log(v);});
###Arrow Functionのthis
アロー関数のthisは、関数が実行されれたときに決まるのではなく、関数が定義されたときに決まる。
アロー関数を使うことで、selfとか_thisとかを使わないくて済むようになる。
function Myfunc(){
this.name = '太郎';
setTimeout(()=>{
console.log(this.name);//太郎
})
}
new Myfunc();
従来のfunctionで定義した場合
function Myfunc(){
this.name = '太郎';
setTimeout(function(){
//thisはwindowを参照する
console.log(this.name);//undefined
},100)
}
new Myfunc();
##Async関数(ES7)
async、awaitを使うと非同期処理を、まるで同期処理を書いているように書けます。
下記の例のように、await
を追加した関数は、その処理が終わるまで次の処理に移りません。
awaitを使う場合は、awaitを使う関数をasync function
をにする必要があります。
※このあたりまだちゃんと理解できていない為、記載の表現に誤りがあるかも。。。
function asyncGet(req, wait){
return new Promise(
resolve => setTimeout(function(){resolve(req)}, wait)
);
}
async function test(){
console.log(await asyncGet("リクエスト1", 1000));
console.log(await asyncGet("リクエスト2", 100));
console.log(await asyncGet("リクエスト3", 3000));
console.log(await asyncGet("リクエスト4", 200));
//リクエスト1
//リクエスト2
//リクエスト3
//リクエスト4
};
test();
いままでは下記のように書いてました。
上記にくらべると冗長な感じがしますし、
async、awaitを使ったほうがコードの見通し良くなった気がします。
function asyncGet(wait){
return new Promise(
resolve => setTimeout(function(){resolve()}, wait)
);
}
function test(){
asyncGet(1000)
.then(function(){
console.log("リクエスト1");
return asyncGet(1000);
})
.then(function(){
console.log("リクエスト2");
return asyncGet(100);
})
.then(function(){
console.log("リクエスト3");
return asyncGet(3000);
})
.then(function(){
console.log("リクエスト4");
return asyncGet(200);
});
};
test();
##終わり
ES6からはClassも使えるようになり、色々やれることが増えるようです。
記載の内容以外にも沢山便利な機能があるようなので、今後も調べていこうと思います。