LoginSignup
27
32

More than 5 years have passed since last update.

[Node.js] ES6 Arrow Function をいろんな書き方で書いてみた

Last updated at Posted at 2015-09-26

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と読み間違えたりしないだろうか :question: :question:

[余談] 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.jsonc.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)

杞憂みたいですね :smiley:


こんな所かな?

とりあえずワンライナーへのサポートが凄い( return は抜けるし {} は抜いていいし)

これ試して欲しいとかあれば、コメント欄に書いてもらえれば :sunglasses:
PRを送ってもらっても良いです :exclamation:

27
32
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
27
32