ES6マラソン・1 〜BabelでES6(Class,let,const,DefaultParameter,Destructuring)がどのようにトランスパイルされるか試して理解する〜
今ちょっとES6を使う機会があってお勉強しております。
今回理解したいのはBabelでトランスパイルされたJSです。
書き出されたそれが何を記述しているのかを把握することで「あ〜なるほどなこういう動きするんだ」と思うのがゴールです。僕の。
なので、ES6から導入されるものを書いて眺めようというちょっとうるさい記事です。
今回みたのは、
- Class
- let
- const
- Default Parameter
- Destructuring
Babel
Babel
・ESトランスパイラツール。ES5、ES3に変換してくれる。(他にライブラリを読み込み、ビルド不要でES6を利用できるESポリフィルがある。)
・使う理由はES6の標準化まで長い期間かかる為。coffeeやTSなどのビルドプロセスが当たり前になってきている為。ってこのまえ登壇していたサイボーズのES6太郎さんっていうこの本書いた人が仰ってた
・ES6対応しないIE11がこれから先4年は生きる為
・今トランスパイラを使い続ければ標準化した際に外せばいいだけ
Class
moritaクラスのインスタンスから関数を実行する単純なものを作ってどのようにトランスパイルされるかみてみようと思います。
class morita {
constructor(firstName){
this.firstName = firstName;
this.lastName = 'kenji';
this.get = ()=>{
return this.firstName + this.lastName;
}
}
}
let firstName = new morita('morita');
firstName.get()//moritakenji
Classを書くとこのようにトランスパイルされるみたいです。
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
var morita = function morita(firstName) {
var _this = this;
_classCallCheck(this, morita);
this.firstName = firstName;
this.lastName = 'kenji';
this.get = function () {
return _this.firstName + _this.lastName;
};
};
var firstName = new morita('morita');
firstName.get();
何か長いところがあります。
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
ここは何しているのでしょうか整形してみます。
function _classCallCheck(instance, Constructor){
if (!(instance instanceof Constructor))
{ throw new TypeError('Cannot call a class as a function'); }
}
...
_classCallCheck(this, morita);
thisを第一引数として渡して、class名のmoritaを第二に渡して
thisは本当にこのコンストラクタか評価しているようです。
let
letは同じ実行コンテキスト内でユニークな変数として宣言します
同じスコープブロック内で使ってみると
**Duplicate declaration "x"**のエラーでます。
demo
同じブロック内で定義したのでエラーでます。
function morita(){
let x;
x;
x = 'kenji'
}
'use strict';
function morita() {
var x = undefined;
x;
x = 'kenji';
}
letはvarとして変換され、宣言だけだと初期値にはundefinedが明示的に代入されるみたいです。
const
定数は読み取り専用(上書きや再宣言はError)
function morita(){
const x = 'kenji';
const x; '足させてお願い・・';//再宣言。erepl: Unexpected token (3:9)
}
morita()//エラー箇所で止まるのでトランスパイルされない
function morita(){
const x = 'kenji';
x =+ '!!足してくれたのね!!';//Error repl: Line 3: "x" is read-only
console.log(x)
}
morita();//エラー箇所で止まるのでトランスパイルされない
read-onlyって出ます。
こちらはエラー出ないでトランスパイルされますが、
function morita(){
const x = 'kenji';
x + 'そろそろ足させてお願い・・';//だから定数だって
}
morita()//undefined
undefinedです。
また、constがvarに変換されていることが確認できます。
「定数」なのにvarになっちゃうと代入可能かどうか分からない。。
'use strict';
function morita() {
var x = 'kenji';
x + 'そろそろ足させてお願い・・';
}
morita();//undefined
Babelではエラーで無いけど。。
Babelの役割はES5やES3の記述に変換することであってErrorはき出すのではないからだね。
調べたらESLintのドキュメントに書いてあった。
no-const-assignで設定できますね。
Default Parameter
デフォルトパラメーターは関数の仮引数の箇所で初期化できるものです。
function get(firstName = 'morita', lastName = 'kenji'){
}
ここまでやって何がされているのかソース見てみた
'use strict';
function get() {
var firstName = arguments.length <= 0 || arguments[0] === undefined ? 'morita' : arguments[0];
var lastName = arguments.length <= 1 || arguments[1] === undefined ? 'kenji' : arguments[1];
}
渡ってきた引数が0かundefinedが初期値だったら..任意の値
それ以外だったらarguments[0]
仮引数のところには書かないで、argumentsオブジェクトで実際の引数を参照、実行コンテキスト内に代入されるんですね。
default parameter・英語
argumentオブジェクト・MDN
こーゆーことできるんだな。楽だな。いままでvar arrayって箱つくってたもんな。。
function add(value,array = []){
array.push(value);
return array
}
add(4);//[4]
add(5);//[5]
Destructuring
なんて?
Destructuring[デストラクチャリング(非構造化)]
ality – JavaScript and more
babeljs.io/docs/learn-es2015
①last matching
//ex1
let [x] = ["morita"];
console.log([x]);//['morita']
//ex2
let [x] = ["morita"];
console.log(x);//morita
//ex3
var [a,,b] = [1,2,3];
console.log(b)//3
//ex3 after
"use strict";
var _ref = [1, 2, 3];//_refという変数に格納される
var a = _ref[0];
var b = _ref[2];//commaを含めて何番目か[(0),(1),(2)]の[2]
console.log(b);//3
//ex4
var [a,,,,,b] = [1,2,3]; //commaの数増やす
console.log(b)//undefined //[1,2,3,undefined,undefined(ココ)]ココを参照しようとしている
//ex4 after
"use strict";
var _ref = [1, 2, 3];
var a = _ref[0];
var b = _ref[5];//5番目にbが割り当てられている
console.log(b);//undefined
//ex5
let [,,,y] = ['a','b','c','d','e']//
//ex5 after
'use strict';
var _ref = ['a', 'b', 'c', 'd', 'e'];
var y = _ref[3];
y//3
②object matching
//ex1 babel
let {a: fa, b:he, c:{a:le}, d:se} = hagehageget
//ex1 after
"use strict";
var _hagehageget = hagehageget;
var fa = _hagehageget.a;
var he = _hagehageget.b;
var le = _hagehageget.c.a;
var se = _hagehageget.d;
③Can be used in parameter position
//ex1 babel
function g({name: x}) {
console.log(x);
}
g({name: 5})//そのまま渡している
//ex1 after
"use strict";
function g(_ref) {
var x = _ref.name;
console.log(x);
}
g({ name: 5 });//5
④Fail-soft destructuring
//ex1
var [a] = [];
a === undefined;//true
//ex1 after
"use strict";
var _ref = [];
var a = _ref[0];
a === undefined; //true
⑤Fail-soft destructuring with defaults
//ex1
var [a = 1] = [];
a === 1;//true
//ex1 after
"use strict";
var _ref = [];
var _ref$0 = _ref[0];
var a = _ref$0 === undefined ? 1 : _ref$0;
a === 1; //true
Object matching
ECMAScript 6 and Destructuring Assignment
上記を参照に。重複するかもしれないけど記しておく
text Variables can be initialized in one go. The following two lines have the same effect, the first one is employing an array pattern.
//2つは同じ意味
let [a,b,c] = ['fafa','fefe','hoho'];
var a = 'fafa', b='fefe', c='hoho';
//array patternという初期化処理。
//マッチした箇所に代入されるstring
Object Pattern
//ex1 babel
function today() { return { d: 6, m: 2, y: 2013 }; }
var { m: month, y: year } = today(); // month = 2, year = 2013
//ex1 after
"use strict";
function today() {
return { d: 6, m: 2, y: 2013 };
}
var _today = today();//関数名が「_変数」になっている
var month = _today.m;//オブジェクトプロパティを参照代入している
var year = _today.y;
// month = 2, year = 2013
//ex2 babel
let obj = { first: 'Jane', last: 'Doe' };
let {first:i,last:s} = obj;//オブジェクトをmatchするところに割り当てている
//ex2 after
'use strict';
var obj = { first: 'Jane', last: 'Doe' };
var i = obj.first;
var s = obj.last;
console.log(i)//Jane
console.log(s)//Doe
今回の記事書いていて感じたことは地味にDestructuringが結構大事なような気がしました。
こちらのJavaScript and moreって記事いいよ。
あと全然関係ないですけど、
この前怖い夢見て、
その夢が、母親が「この世からいなくなる」っていう夢だったんですけど、
要は「死ぬ」みたいな、、
次の日母親から電話掛かってきたんですよ!
まさか!!??この世から居なくなったのか?と思うじゃないですか?
タイミングがタイミングだし、
おそるおそる取るじゃないですか?電話。
そしたら
**「けんちゃん、トマトジュース飲んでる?」**て。
健康にいいよ?て。
参照
WEB+DB PRESSvol87「今すぐ活かす!最新JavaScript」
fail-fast object destructuring (don't add more slop to sloppy mode)
ECMAScript 6 and Destructuring Assignment
http://www.2ality.com/2015/01/es6-destructuring.html
Learn ES2015