2015年09月30日

ES6の基本 - Generator

BabelでES6を始めるにあたってES6の基本文法とBabelがどのようにコンパイルするかを理解するためにまとめておきます。

Generator



function名の前に*(アスタリスク)をつけると実行時にGenerator Objectを生成します。Generator Objectのnextメソッドを実行するとyield宣言した箇所まで関数を実行します。yieldの値はvalueプロパティで取得できます。

// ジェネレータを返す関数を定義する
function *func(){
console.log(1,"in");
yield 1;
console.log(2,"in");
yield 2;
console.log(5,"in");
yield 5;
console.log("foo","in");
yield "foo";
console.log("last","in");
}

// ジェネレータを取得する
var gen = func();

console.log(gen.next().value,"out");
console.log(gen.next().value,"out");
console.log(gen.next().value,"out");
console.log(gen.next().value,"out");
console.log(gen.next().value,"out");


var marked0$0 = [func].map(regeneratorRuntime.mark);
function func() {
return regeneratorRuntime.wrap(function func$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
console.log(1, "in");
context$1$0.next = 3;
return 1;

case 3:
console.log(2, "in");
context$1$0.next = 6;
return 2;

case 6:
console.log(5, "in");
context$1$0.next = 9;
return 5;

case 9:
console.log("foo", "in");
context$1$0.next = 12;
return "foo";

case 12:
console.log("last", "in");

case 13:
case "end":
return context$1$0.stop();
}
}, marked0$0[0], this);
}

// ジェネレータを取得する
var gen = func();

console.log(gen.next().value, "out");
console.log(gen.next().value, "out");
console.log(gen.next().value, "out");
console.log(gen.next().value, "out");
console.log(gen.next().value, "out");


以下のように無名関数を利用して一気にGenerator Objectを生成することも可能です。

// ジェネレータを取得する
var gen = (function *(){
console.log(1,"in");
yield 1;
console.log(2,"in");
yield 2;
console.log(5,"in");
yield 5;
console.log("foo","in");
yield "foo";
console.log("last","in");
})();
タグ:BABEL ES6 generator
posted by ねこまんま at 13:27 | Comment(0) | TrackBack(0) | 関数/文法 | 更新情報をチェックする

2015年09月28日

ES6の基本 - Class

BabelでES6を始めるにあたってES6の基本文法とBabelがどのようにコンパイルするかを理解するためにまとめておきます。

Class



これまでnew functionなどを利用してclassを利用してきたがES6で他の言語と同等のclassが追加されました。

class Person{
//コンストラクタ
constructor(name) {
this.name = name;
}
//メソッド
say() {
return 'My Name is ' + this.name;
}
//静的メソッド
static say2(name) {
return '私の名前は' + name;
}
}
var taro = new Person('太郎');
console.log(taro.say());//My Name is 太郎
console.log(Person.say2("taro "));//私の名前はtaro

class Man extends Person{
isMan() {
return true;
}
}
class Woman extends Person{
isMan() {
return false;
}
}

var taro = new Man('太郎');
console.log(taro.isMan());//true
var hanako = new Woman('花子');
console.log(hanako.isMan());//false


var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

var Person = (function () {
//コンストラクタ

function Person(name) {
_classCallCheck(this, Person);

this.name = name;
}

//メソッド

_createClass(Person, [{
key: 'say',
value: function say() {
return 'My Name is ' + this.name;
}

//静的メソッド
}], [{
key: 'say2',
value: function say2(name) {
return '私の名前は' + name;
}
}]);

return Person;
})();

var taro = new Person('太郎');
console.log(taro.say()); //My Name is 太郎
console.log(Person.say2("taro ")); //私の名前はtaro

var Man = (function (_Person) {
_inherits(Man, _Person);

function Man() {
_classCallCheck(this, Man);

_get(Object.getPrototypeOf(Man.prototype), 'constructor', this).apply(this, arguments);
}

_createClass(Man, [{
key: 'isMan',
value: function isMan() {
return true;
}
}]);

return Man;
})(Person);

var Woman = (function (_Person2) {
_inherits(Woman, _Person2);

function Woman() {
_classCallCheck(this, Woman);

_get(Object.getPrototypeOf(Woman.prototype), 'constructor', this).apply(this, arguments);
}

_createClass(Woman, [{
key: 'isMan',
value: function isMan() {
return false;
}
}]);

return Woman;
})(Person);

var taro = new Man('太郎');
console.log(taro.isMan()); //true
var hanako = new Woman('花子');
console.log(hanako.isMan()); //false


このようにconstructorで簡単にコンストラクタの設定ができ、staticで静的メソッドが定義できます。
タグ:ES6 BABEL class
posted by ねこまんま at 19:23 | Comment(0) | TrackBack(0) | 関数/文法 | 更新情報をチェックする

ES6の基本 - concise methods

BabelでES6を始めるにあたってES6の基本文法とBabelがどのようにコンパイルするかを理解するためにまとめておきます。

concise methods



ES6ではメソッドの定義が簡潔になりました。以下のように「:function」を省略できるようになっています。

var bar = {
fuga : "ok",
foo() {
console.log(this.fuga);
}
};

bar.foo();//ok


var bar = {
fuga: "ok",
foo: function foo() {
console.log(this.fuga);
}
};

bar.foo(); //ok
posted by ねこまんま at 18:30 | Comment(0) | TrackBack(0) | 関数/文法 | 更新情報をチェックする

2015年09月26日

ES6の基本 - Function Arguments

BabelでES6を始めるにあたってES6の基本文法とBabelがどのようにコンパイルするかを理解するためにまとめておきます。

可変長の引数



ES5以前では可変長の引数を受け取る際にargumentsを利用していましたが、ES6では任意の変数名で受け取ることができます。引数宣言時に.(ドット)を3つつなげて記述します。また、Arrayオブジェクトに変換されるためargumentsより使いやすいですね。

var bar = (...arg) => {
console.log(arg);//[1, 2, 3, 4]
console.log(Array.isArray(arg));//true
};

bar(1,2,3,4);


var bar = function bar() {
for (var _len = arguments.length, arg = Array(_len), _key = 0; _key < _len; _key++) {
arg[_key] = arguments[_key];
}

console.log(arg); //[1, 2, 3, 4]
console.log(Array.isArray(arg)); //true
};

bar(1, 2, 3, 4);


引数の初期値



関数の引数に初期値を設定できるようになりました。

function bar(foo = 3) {
console.log(foo);
}
bar(4);//4
bar();//3


function bar() {
var foo = arguments.length <= 0 || arguments[0] === undefined ? 3 : arguments[0];

console.log(foo);
}
bar(4); //4
bar(); //3


var bar = (foo = 3) => {
console.log(foo);
}
bar(4);//4
bar();//3


var bar = function bar() {
var foo = arguments.length <= 0 || arguments[0] === undefined ? 3 : arguments[0];

console.log(foo);
};
bar(4); //4
bar(); //3
posted by ねこまんま at 12:14 | Comment(0) | TrackBack(0) | 関数/文法 | 更新情報をチェックする

ES6の基本 - const

BabelでES6を始めるにあたってES6の基本文法とBabelがどのようにコンパイルするかを理解するためにまとめておきます。

const



constは定数宣言を行う構文です。定数は習慣的に大文字で宣言を行います。

BABELでは1回しか定数宣言されていない場合はvar宣言に変換を行います。

const FOO ="bar";
console.log(FOO);//bar


var FOO = "bar";
console.log(FOO);


しかし、2回以上同一の定数が宣言された場合コンパイルを行わずにエラーを出力します。

const FOO ="bar";
console.log(FOO);//bar
FOO ="bar2";
console.log(FOO);
タグ:ES6 CONST BABEL
posted by ねこまんま at 11:54 | Comment(0) | TrackBack(0) | 関数/文法 | 更新情報をチェックする

ES6の基本 - let

BabelでES6を始めるにあたってES6の基本文法とBabelがどのようにコンパイルするかを理解するためにまとめておきます。

let



letは局所的変数宣言でブロクスコープ内のみで有効な変数を宣言できます。
ブロック外で利用した場合は単純にvarと同じ機能を提供しますのでBabelはvarに変更してコンパイルを行います

let foo0 ="bar0";
console.log(foo0);//bar0
if(true){
foo0 = "bar00";
console.log(foo0);//bar00
}


var foo0 = "bar0";
console.log(foo0); //bar0
if (true) {
foo0 = "bar00";
console.log(foo0); //bar00
}


以下のようにブロック内でlet宣言をおこなってみましょう。Babelは大幅な変更を行います。

if(true){
let foo1 = "bar1";
console.log(foo1);//bar1
}
foo1 ="bar11";
console.log(foo1);//foo1 is not defined


if (true) {
var _foo1 = "bar1";
console.log(_foo1); //bar1
}
foo1 = "bar11";
console.log(foo1); //foo1 is not defined


このようにしてletを擬似的に再現しております。

また、以下のように同一ブロックで同じ変数をletした場合はBabelはエラーを返しコンパイルを行いません。

let foo0 ="bar0";
let foo0 ="bar00";


ブロックの階層が異なれば同一変数名でもlet宣言で定義が可能です。

let foo0 ="bar0";
if(true){
let foo0 ="bar00";
}


var foo0 = "bar0";
if (true) {
var _foo0 = "bar00";
}

タグ:ES6 BABEL Let
posted by ねこまんま at 05:09 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

ES6の基本 - Arrow Function

BabelでES6を始めるにあたってES6の基本文法とBabelがどのようにコンパイルするかを理解するためにまとめておきます。

Arrow Function



代表的な省略構文であるArrow Function。

このようなコードが以下のように変換される。関数リテラルが無名関数ではなく有名関数で生成されているのに違和感ありですが。

var bar = () => {
console.log("ok");
};


var bar = function bar() {
console.log("ok");
};


引数を取った場合も一緒です。

var bar = (x) => {
console.log("ok");
};


var bar = function bar(x) {
console.log("ok");
};


引数の括弧は省略できる

var bar = x => {
console.log("ok");
};


var bar = function bar(x) {
console.log("ok");
};


return を行い1行しかない場合は場合は { }も省略できる

var bar = x => x+1;


var bar = function bar(x) {
return x + 1;
};


jQueryなどを利用している場合は以下のように記述するとfunctionの記述を省略できます。

$(()=>{
console.log("ok");
});


$(function () {
console.log("ok");
});
posted by ねこまんま at 03:56 | Comment(0) | TrackBack(0) | 関数/文法 | 更新情報をチェックする

2015年09月25日

gulpでbrowserifyとBabel

BabelはES6のimport/export構文をrequireに変換してしまうためそのままでは利用できない。

import { main } from './main';
console.log(main(1,2));


これを以下のように変換する

'use strict';

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _mainJs = require('./main');

var _mainJs2 = _interopRequireDefault(_mainJs);

console.log((0, _mainJs2['default'])(1, 2));


このままでは利用できないのでbrowserifyなどを利用してrequire()が利用できるようにしなくていけない。

調べてみるとbrowserifyとbabelifyというツールでコンパイルを行うらしい。

以下のコマンドでインストール。

sudo npm install browserify babelify vinyl-source-stream --save-dev


すると以下の様なタスクでコンパイルできる。

var gulp       = require('gulp'),
browserify = require("browserify"),
babelify = require("babelify"),
source = require("vinyl-source-stream");

gulp.task('babelify', function () {
browserify({
entries: "./babel/script.js",
extensions: [".js"]
})
.transform(babelify)
.bundle()
.on("error", function (err) { console.log("Error : " + err.message); })
.pipe(source("./script.js"))
.pipe(gulp.dest("./asset/js"));
});


babel単体だとグローバルに'use strict'が付与されるのが気になってたけどこれなら各名前空間のみに付与されるのでそれもよさ気だと思った。
posted by ねこまんま at 08:59 | Comment(0) | TrackBack(0) | gulp | 更新情報をチェックする

Babelをgulpで実行

久々に新規サイトを作成するのでBabelを利用してES6で書こうとしております。

BabelはES6をES5形式にコンパイルしてくれるAltJS。CoffeeScriptなど他のAltJSと比較すると学習コストが将来無駄にならない点がよい。

gulpの使い方は「タスクランナーgulp入門」などを参照に。Babelに関しては以下のgulp-babelをインストール。

sudo npm install gulp-babel --save-dev


以下のような設定を追加するとbabelディレクトリの内容をassets/jsディレクトリに書きだしてくれる。

var babel  = require('gulp-babel');

//babel
gulp.task('babel', function () {
gulp.src("/babel/*.js")
.pipe(babel())
.pipe(gulp.dest("/assets/js"));
});


ターミナルでは以下のコマンドを実行する。

gulp babel
posted by ねこまんま at 07:09 | Comment(0) | TrackBack(0) | gulp | 更新情報をチェックする