Node.js 4.0.0が来たので、勉強がてら(これ始める前は4.0.0で〜とか思ってたけど、見てみたら4.1.1来てたのか...)
本記事は Node.js 4.1.1
で試しています
> process.version
'v4.1.1'
Arrow function
単純な使い方(void)
var a = () => {
console.log(1);
};
a();
//=> 1
let b = () => {
console.log(2);
};
b();
//=> 2
//=> 注意これはインタプリタの場合だと成功しますが、 node app.js のように実行する場合は失敗します
//=> [追記] use strictを使えば問題なかった
var c = () => console.log(3);
c();
//=> 3
let d = () => console.log(4);
d();
//=> 4
//=> 注意これはインタプリタの場合だと成功しますが、 node app.js のように実行する場合は失敗します
//=> [追記] use strictを使えば問題なかった
// 失敗例
$ node b.js
let b = () => console.log(2);
^^^
SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:413:25)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:475:10)
at startup (node.js:117:18)
at node.js:951:3
returnをしたい場合
var a = () => {
return 1;
};
console.log(a());
//=> 1
var b = () => 2;
console.log(b());
//=> 2
var b = () =>
2;
console.log(b());
//=> 2
var c = () => return 3;
//=> SyntaxErrorです
var c = () => return 3;
^^^^^^
SyntaxError: Unexpected token return
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:413:25)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:475:10)
at startup (node.js:117:18)
at node.js:951:3
引数をつけたい場合
var hoge = (a) => a * 2;
console.log(hoge(5));
//=> 10
console.log(hoge(5 * 2));
//=> 20
var hoge = (cb) => cb();
hoge( () => console.log(1) );
//=> 1
hoge( () =>
console.log(1)
);
//=> 1
hoge(
() => console.log(1)
);
//=> 1
hoge( ()
=> console.log(1)
);
//=>
=> console.log(1)
^^
SyntaxError: Unexpected token =>
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:413:25)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:475:10)
at startup (node.js:117:18)
at node.js:951:3
引数を受け取って更にその中で関数を実行させる場合
let arr = ['abc', 'de', 'f'];
console.log(arr.map(v => v.toUpperCase()));
//=> [ 'ABC', 'DE', 'F' ]
var sum = (arr) =>
arr.reduce( (a, b) => a + b );
console.log(sum([1, 2, 3, 4, 5, 6, 7, 8, 9]));
//=> 45
var fibo = (n) => {
if (n < 2) return n;
return fibo(n - 2) + fibo(n - 1);
};
console.log(fibo(10));
//=> 55
var fibo = (n) =>
if (n < 2) return n;
return fibo(n - 2) + fibo(n - 1);
console.log(fibo(10));
//=>
if (n < 2) return n;
^^
SyntaxError: Unexpected token if
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:413:25)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:475:10)
at startup (node.js:117:18)
at node.js:951:3
デフォルト引数を使ってみたい場合
var f = (x, y = 7) => x + y;
console.log(f(1));
//=>
var f = (x, y = 7) => x + y;
^
SyntaxError: Unexpected token =
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:413:25)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:475:10)
at startup (node.js:117:18)
at node.js:951:3
残念(◞‸◟)
レキシカル this は?
let arr = [1, 2, 3];
arr.forEach(v => console.log(v, this));
//=>
1 {}
2 {}
3 {}
arr.forEach(function(v) {
console.log(v, this);
});
//=>
1 undefined
2 undefined
3 undefined
arr.forEach(function(v) {
console.log(v, this);
}.bind(this))
//=>
1 {}
2 {}
3 {}
この this
が関数定義時に決まっているっぽいので、それを考えると例えば下記のような結果になるという事だろうか?
function hoge(target, evtName) {
target.addEventListener(evtName, function() {
console.log(this); //=> targetがthisになる
});
}
var hoge = (target, evtName) => {
target.addEventListener(evtName, () => console.log(this)); //=> hogeがthisになる
}
即時実行関数をしたい場合
(() => console.log(1))();
//=> 1
((a, b) => console.log(a, b))(1, 'hoge');
//=> 1 'hoge'
(=> console.log(1))();
//=> SyntaxErrorです
(=> console.log(1))();
^^
SyntaxError: Unexpected token =>
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:413:25)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:475:10)
at startup (node.js:117:18)
at node.js:951:3
Block Scopeどうなってんの?
{
(() => console.log(this))();
}
//=> {}
上記のコードは下記のように解釈されているっぽい
(function() {
(function() { console.log(this); })();
})();
ともすると、JSONと読み間違えたりしないだろうか
[余談] require
$ ls
> b.json c.js
b.json
{
"id": 1
}
c.js
{
(() => console.log('cのファイル'))();
}
a.js
{
var b = require('./b');
var c = require('./c');
console.log(b);
console.log(c);
}
$ node a.js
cのファイル
{ id: 1 }
{}
b.json
と c.js
の拡張子を入れ替えます
b.js
"id": 1
^
SyntaxError: Unexpected token :
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:413:25)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object.<anonymous> (~~/a.js:2:11)
at Module._compile (module.js:434:26)
at Object.Module._extensions..js (module.js:452:10)
c.json
module.js:463
throw err;
^
SyntaxError: /Development/ruby_work/vagrants/vagrant/virtualbox/vbox-develop/c.json: Unexpected token (
at Object.parse (native)
at Object.Module._extensions..json (module.js:460:27)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object.<anonymous> (/Development/ruby_work/vagrants/vagrant/virtualbox/vbox-develop/a.js:3:11)
at Module._compile (module.js:434:26)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
杞憂みたいですね
こんな所かな?
とりあえずワンライナーへのサポートが凄い( return
は抜けるし {}
は抜いていいし)
これ試して欲しいとかあれば、コメント欄に書いてもらえれば
PRを送ってもらっても良いです