16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ES6マラソン・1 〜BabelでES6(Class,let,const,DefaultParameter,Destructuring)がどのようにトランスパイルされるか試して理解する〜

Last updated at Posted at 2015-09-02

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年は生きる為
・今トランスパイラを使い続ければ標準化した際に外せばいいだけ

スクリーンショット 2015-08-30 8.46.57.png

Class

moritaクラスのインスタンスから関数を実行する単純なものを作ってどのようにトランスパイルされるかみてみようと思います。

demo

es6
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を書くとこのようにトランスパイルされるみたいです。

javascript:トランスパイラされたJS
'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"**のエラーでます。

スクリーンショット 2015-08-30 12.50.44.png

demo
同じブロック内で定義したのでエラーでます。

ES6
function morita(){
  let x;
  x;
  x = 'kenji'
}
トランスパイラされたjs
'use strict';

function morita() {
  var x = undefined;
  x;
  x = 'kenji';
}

letはvarとして変換され、宣言だけだと初期値にはundefinedが明示的に代入されるみたいです。

const

定数は読み取り専用(上書きや再宣言はError)

ES6
function morita(){
  const x = 'kenji';
  const x; '足させてお願い・・';//再宣言。erepl: Unexpected token (3:9)
}
morita()//エラー箇所で止まるのでトランスパイルされない
ES6
function morita(){
  const x = 'kenji';
  x =+ '!!足してくれたのね!!';//Error repl: Line 3: "x" is read-only
  console.log(x)
}
morita();//エラー箇所で止まるのでトランスパイルされない

read-onlyって出ます。

こちらはエラー出ないでトランスパイルされますが、

ES6
function morita(){
  const x = 'kenji';
  x +  'そろそろ足させてお願い・・';//だから定数だって
}
morita()//undefined

undefinedです。
また、constがvarに変換されていることが確認できます。
「定数」なのにvarになっちゃうと代入可能かどうか分からない。。

js
'use strict';

function morita() {
  var x = 'kenji';
  x + 'そろそろ足させてお願い・・';
}
morita();//undefined

Babelではエラーで無いけど。。
Babelの役割はES5やES3の記述に変換することであってErrorはき出すのではないからだね。

調べたらESLintのドキュメントに書いてあった。
no-const-assignで設定できますね。

Default Parameter

デフォルトパラメーターは関数の仮引数の箇所で初期化できるものです。

demo

babel
function get(firstName = 'morita', lastName = 'kenji'){
  
}

ここまでやって何がされているのかソース見てみた

js
'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って箱つくってたもんな。。

ES6
function add(value,array = []){
  array.push(value);
  return array
}
add(4);//[4]
add(5);//[5]

demo

Destructuring

なんて?
Destructuring[デストラクチャリング(非構造化)]
ality – JavaScript and more
babeljs.io/docs/learn-es2015

①last matching

ES6と一部トランスパイルされたjs
//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

ES6
//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

ES6
//ex1
var [a] = [];
a === undefined;//true


//ex1 after
"use strict";
var _ref = [];
var a = _ref[0];
a === undefined; //true

⑤Fail-soft destructuring with defaults

ES6

//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.

ES6
//2つは同じ意味
let [a,b,c] = ['fafa','fefe','hoho'];
var a = 'fafa', b='fefe', c='hoho'; 

//array patternという初期化処理。
//マッチした箇所に代入されるstring

Object Pattern

ES6
//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

16
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?