質問するログイン新規登録

回答編集履歴

2

Babelを紹介

2016/01/08 21:19

投稿

raccy
raccy

スコア21784

answer CHANGED
@@ -59,4 +59,4 @@
59
59
 
60
60
  `this`の束縛ですが、コード内に`this`がなければfunctionを使った無名関数と動作は同じですが、`this`があれば**必ず**動作は異なります。こちらについては**回避方法はありません。**定義している環境の`this`に強制的に束縛したい場合は、アロー演算子を使った方が簡単に書けると言うだけです。呼び出し方によって`this`の束縛が変わるような関数を作成したい場合は、**functionを使う以外方法はありません**。
61
61
 
62
- 単純に短く書きたいだけであれば、最初からCoffeeScriptで書いた方がいいです。
62
+ functionを単純に短く書けるようにした物ではないため、単に短く書きたいだけであれば、最初からCoffeeScriptで書いた方がいいです。アロー関数が本来のES5ではどう解釈されるかはBabel等を用いて変換してみるとわかるかと思います。[Babel: Try it out](https://babeljs.io/repl/)で色々試してみてください。

1

再帰の時の名前とか

2016/01/08 21:19

投稿

raccy
raccy

スコア21784

answer CHANGED
@@ -1,15 +1,62 @@
1
1
  > **(1) アロー関数は名前付き関数式を指定できない**
2
2
 
3
- 関数宣言式の利点は**巻き上げ**ぐらいで、ほとんどありません。関数にある名前を使ってその関数に**アクセスしているわけではない**からです。
3
+ 関数宣言式の利点は**巻き上げ**ぐらいで、ほとんどありません。関数外部から関数にある名前を使ってその関数に**アクセスしているわけではない**からです。
4
4
  参考: [stackoverflow jp: function hoge() と hoge = function() の違いは?](http://ja.stackoverflow.com/questions/2781/function-hoge-%E3%81%A8-hoge-function-%E3%81%AE%E9%81%95%E3%81%84%E3%81%AF)
5
5
  また、関数宣言式にしても後からの破壊的代入を防げるわけではありません。名前の破壊を防ぎたいのであれば、`const`を使って定数にすべきでしょう。
6
6
 
7
+ 上とは別に、名前付き関数の利点として、関数内部でその関数名の関数スコープである暗黙の**ローカル変数**が作成され、それが**上書きされない**という利点があります。アロー関数で全く同じ方法をとることはできませんが、関数を返す関数を実行して、上書きされない関数スコープのロカール変数を使えばできます。下記の`fn1`を参考にしてみてください。
8
+
9
+ ```JavaScript
10
+ "use strict";
11
+ var fn0 = (i) => {
12
+ return i < 10 ? fn0(++i) : i;
13
+ };
14
+ var fn0x = fn0;
15
+ console.log(fn0x(0)); // 10
16
+ fn0 = (i) => {
17
+ return 0;
18
+ };
19
+ console.log(fn0x(0)); // 0 になっちゃう。あかんわ。
20
+
21
+ var fn1 = () => {
22
+ var _fn1 = (i) => {
23
+ return i < 10 ? _fn1(++i) : i;
24
+ };
25
+ return _fn1;
26
+ }();
27
+ var fn1x = fn1;
28
+ console.log(fn1x(0)); // 10
29
+ fn1 = (i) => {
30
+ return 0;
31
+ };
32
+ console.log(fn1x(0)); // 10 のまま!やったぜ!
33
+ ```
34
+
35
+ ただ、そもそも関数自体が上書きされること自体が想定外の動作を起こす可能性があるため、単に`const`をつけて上書き禁止にした方がES6っぽいかと思います。
36
+
37
+ ```JavaScript
38
+ "use strict";
39
+ const fn2 = (i) => {
40
+ return i < 10 ? fn2(++i) : i;
41
+ };
42
+ var fn2x = fn2;
43
+ console.log(fn2x(0)); // 10
44
+ fn2 = (i) => {
45
+ return 0;
46
+ }; // この時点でエラーになる!!
47
+ console.log(fn2x(0));
48
+ ```
49
+
7
50
  > **(2) アロー関数は this 値を束縛できない**
8
51
 
9
52
  これは欠点というよりも一つの利点です。通常、eventなどでコールバック関数に使った場合、thisがそのeventを呼び出した要素になってしまいます。例えば、inputのイベントで書き換わった値を`this.text`に入れたいとかのの動作を実装するときに、`var _this = this;`と書いて`_this.text`として書く必要があるなど非常に不便でした。ですので、どのような呼び出され方をしても関数が定義されている環境のthisに強制的にbindするようにしたのがアロー関数です。
10
53
 
11
54
  > 間違いでしたらどんな方法で制限を回避できるでしょうか。
12
55
 
13
- アロー関数は通常のfunctionの代わりになるものではありません。コード内に`this`がなければfunctionを使った無名関数と動作は同じですが、`this`があれば動作は異なります。定義している環境の`this`に強制的に束縛したい場合は、アロー演算子を使った方が簡単に書けると言うことです。そのようなことがなければ、無理に使わず、functionを使い続けたほうがいいでしょう。
56
+ アロー関数は通常のfunctionの単純なになるものではありません。
14
57
 
58
+ 再帰関数で関数名を用いたときに、その名前の上書きを防ぎたいのであれば、関数を返す関数を実行して、スコープ内に閉じ込めるか、`const`で上書きそのものを防げばいいかと思います。
59
+
60
+ `this`の束縛ですが、コード内に`this`がなければfunctionを使った無名関数と動作は同じですが、`this`があれば**必ず**動作は異なります。こちらについては**回避方法はありません。**定義している環境の`this`に強制的に束縛したい場合は、アロー演算子を使った方が簡単に書けると言うだけです。呼び出し方によって`this`の束縛が変わるような関数を作成したい場合は、**functionを使う以外方法はありません**。
61
+
15
62
  単純に短く書きたいだけであれば、最初からCoffeeScriptで書いた方がいいです。