#ES2015とは?
将来的にはブラウザに対応される予定の 「今までのJS(ES5)に様々な機能が追加された新仕様」 のこと。
ES6とも言ったりします。
現在は一部のみ(Chromeは対応)で機能が実装されていたり、されていなかったり。
Babelのドキュメントに機能の一覧がまとめられています。
https://babeljs.io/docs/learn-es2015/
##BABELって?
ES2015仕様のJavascriptをES5仕様に整形するツール です。
ES2015に対応していないブラウザのために、
「ES2015の記法で書いたコード」 => 「ES5」
としてくれる。
##対応していないんなら必要ないのでは?
将来的にはブラウザに実装されていく ものなので、今から使って慣れておいた方がよさそうです。
#ES2015で書いてみよう
ES2015についてのチュートリアルがあったのでやってみました。
http://ccoenraets.github.io/es6-tutorial/setup-babel/
ES2015全ての内容をさらえているわけではないですが、
「勉強しなきゃいけない...とはわかっているんだけど...」と重い腰があがらない者としてはとっかかりとしてあるととっても助かります。
変数がブロックスコープでのみ有効になる let
が追加
ブロックスコープが効かないjs
var calculateMonthlyPayment = function (principal, years, rate) {
if (rate) {
var monthlyRate = rate / 100 / 12;
}
var monthlyPayment = principal * monthlyRate / (1 - (Math.pow(1 / (1 + monthlyRate), years * 12)));
return monthlyPayment;
};
phpなどと違って、jsにはブロックレベルでのスコープが無い、ので if
の中で定義した monthlyRate
が外でも使える。
phpとかと同じ感覚で書いてしまうと、意図しないところで変数が上書きされたりしそうで危険。
##letを使う
ES2015で追加された let
を使うと、ブロックスコープを有効に出来る様になる。
let calculateMonthlyPayment = function (principal, years, rate) {
let monthlyRate = 0; //letはブロックスコープで有効なので、外で定義が必要になった
if (rate) {
monthlyRate = rate / 100 / 12;
}
let monthlyPayment = principal * monthlyRate / (1 - (Math.pow(1 / (1 + monthlyRate), years * 12)));
return monthlyPayment;
};
オブジェクトの書き方がシンプルに
キーとバリューが同じなら書かなくても済むようになった
return {principal, years, rate, monthlyPayment, monthlyRate};
と書くだけで、
return { principal: principal,
years: years,
rate: rate,
monthlyPayment: monthlyPayment,
monthlyRate: monthlyRate };
と同じ意味になる。
同じものを使うやつ
let {monthlyPayment, monthlyRate} = calculateMonthlyPayment(principal, years, rate);
とすれば
var mortgage = calculateMonthlyPayment(principal, years, rate);
var monthlyPayment = mortgage.monthlyPayment;
var monthlyRate = mortgage.monthlyRate;
となる。
わかりやすくかくと
let {Tom, John} = profile(years, birthday);
は
var mortgage = profile(years, birthday);
var Tom = mortgage.Tom;
var John = mortgage.John;
みたいな?
function(){}
が ()=>{}
で済むようになった
スペルミスが減るというメリット。
あとは this
が使えなくなるらしいです。
let calculateAmortization = (principal, years, rate) => {
let {monthlyRate, monthlyPayment} = calculateMonthlyPayment(principal, years, rate);
let balance = principal;
let amortization = [];
for (let y=0; y<years; y++) {
let interestY = 0; //Interest payment for year y
let principalY = 0; //Principal payment for year y
for (let m=0; m<12; m++) {
let interestM = balance * monthlyRate; //Interest payment for month m
let principalM = monthlyPayment - interestM; //Principal payment for month m
interestY = interestY + interestM;
principalY = principalY + principalM;
balance = balance - principalM;
}
amortization.push({principalY, interestY, balance});
}
return {monthlyPayment, monthlyRate, amortization};
};
#Module化の記法がシンプルに
##今までは require
をする必要があった
###読み込む方
var sub1 = require(“./modules/sub1.js”);
var sub2 = require(“./modules/sub2.js”);
sub1.hello( );
sub1.goodmorning( );
sub2( );
###読み込まれる方
module.exports.hello = function( ){
console.log(“hello!”);
};
module.exports.goodmorning = function(){
console.log(“goodmorning”);
};
##新記法
###読み込む方
「**という名前で(as)***ディレクトリから(from)インポートする」という書き方になった。
import * as mortgage from './mortgage';
import * as hoge from './hoge';
###読み込まれる方
export
を関数の前につけるだけ。
export let hoge = () => {
console.log("piyopiyo")
}
#Classが使える
作ったクラスは export default
でエクスポートする。
export default class Mortgage {
constructor(principal, years, rate) {
this.principal = principal;
this.years = years;
this.rate = rate;
}
get monthlyPayment() {
let monthlyRate = this.rate / 100 / 12;
return this.principal * monthlyRate / (1 - (Math.pow(1/(1 + monthlyRate),
this.years * 12)));
}
get amortization() {
let monthlyPayment = this.monthlyPayment;
let monthlyRate = this.rate / 100 / 12;
let balance = this.principal;
let amortization = [];
for (let y=0; y<this.years; y++) {
let interestY = 0;
let principalY = 0;
for (let m=0; m<12; m++) {
let interestM = balance * monthlyRate;
let principalM = monthlyPayment - interestM;
interestY = interestY + interestM;
principalY = principalY + principalM;
balance = balance - principalM;
}
amortization.push({principalY, interestY, balance});
}
return amortization;
}
}
インポートするときはModuleのときと同じように。
import Mortgage from './mortgage2';
#Promiseを使う
Promise
をnewして、
let rates = [
{
"name": "30 years fixed",
"rate": "13",
"years": "30"
},
{
"name": "20 years fixed",
"rate": "2.8",
"years": "20"
}
];
export let findAll = () => new Promise((resolve, reject) => {
if (rates) {
resolve(rates);
} else {
reject("No rates");
}
});
こんな感じで使う。
import * as service from './rate-service-mock';
service.findAll()
.then(rates => {
let html = '';
rates.forEach(rate => html += `<tr><td>${rate.name}</td><td>${rate.years}</td><td>${rate.rate}%</td></tr>`);
document.getElementById("rates").innerHTML = html;
})
.catch(e => console.log(e));
エラーのときの処理は catch
に書いてる。
Promiseについてのいい記事
Promiseと仲良くなって気持ち良く非同期処理を書こう - Qiita
#出てきてないけど勉強すべき項目
- Destructuring
- Default + Rest + Spread
- Const
- Iterators + For..Of
- Map + Set + WeakMap + WeakSet
- Proxies
この辺はまた次の機会にでも。
#感想
- 記法がシンプルになった感じ
- とはいえ、正直なところ元の記法にあまり慣れていなかったのでいまいちピンとこない
- 逆に言えば、この記法に慣れてしまえばいいのでは?
- Promiseのところとかは「非同期処理」自体についてもう少し勉強したほうがいいかも