質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
ECMAScript

ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

デザインパターン

デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

2回答

4348閲覧

JavaScript (node.js) 結局のところ関数は 関数式で書くべきか? 関数宣言で書くべきか?

bleurouge

総合スコア161

ECMAScript

ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

デザインパターン

デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

2クリップ

投稿2016/04/16 11:00

JavaScriptにおいて、関数式で書くべきか、関数宣言で書くのか、おそらく正解はなく、すでに様々なところで議論されていると思いますが、みなさんはどのように書いているのでしょうか?両者の違いについての質問・回答はすでにいくつかありましたが、結局のところ2016年時点でどのような使い方が良しとされているのかについては明確ではなく、興味があったので質問してみました。

es6への対応も進み、ある程度型が絞れそうな node.js でのケースを例に書いてみました。関数式と関数宣言を混在させる気持ち悪さがありますが、関数宣言の巻き上げは利用価値ががあると思っています。

javascript

1'use strict'; 2const zzzFunc = require('./lib/zzz'); 34function AAA() { 5 // 基本的には関数式で書く 6 const bbbFunc = () => { 78 CommonA(); 9 CommonB(); 1011 }; 12 const cccFunc = () => { ... CommonA(); ... }; 13 const dddFunc = () => { ... CommonB(); ... }; 14 15 // 複数の関数式内で呼ばれる関数は関数宣言にしておく 16 function CommonA() { ... } 17 function CommonB() { ... } 18 19 // 実行 20 bbbFunc() 21 .then(cccFunc) 22 .then(dddFunc) 23 .then(zzzFunc) 24 .catch( e => console.log('ERR: ', e) ); 25 26 /*// OR モジュールを外部から利用 27 return { 28 bbb : bbbFunc, 29 ccc : cccFunc, 30 ddd : dddFunc 31 }; 32 *//////////// 33} 34 35module.exports = AAA;

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

関数宣言と関数式

関数宣言/関数式は用途に合わせて使い分けるものなので統一的にどちらを選択するか検討すべきところではないと思います。

無名関数式と名前付き関数式

無名関数式は頻繁に使うものではないと思います。
無名関数式は Function#name がないのでデバッグ時に切り分けがやりづらくなります。
無名関数式は名前付き関数式に変更しても動く為、基本的には名前つき間数式を使うと良いと思います。

アロー関数

アロー関数は関数スコープで this 値を束縛したくない場合において有効です。

JavaScript

1function Hoge (x) { this.x = x; } 2Hoge.prototype.foo = function foo () { 3 setTimeout(() => console.log(this.x), 1000); 4}; 5 6new Hoge(3).foo();

ただし、アロー関数も名前がないので必要な時だけ利用する事になります。

更新履歴

  • 2016/04/16 22:30 名前付き関数式/アロー関数の説明を追記

Re: bleurouge さん

投稿2016/04/16 11:42

編集2016/04/16 13:30
think49

総合スコア18162

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bleurouge

2016/04/16 12:45

ありがとうございます。”関数宣言/関数式は用途に合わせて使い分けるもの” このそれぞれの用途というところが、どうも不明瞭なのです。 関数宣言/関数式それぞれが何者なのか?についての解説はweb上でもかなり見かけるのですが、では、それぞれはどのように使われるべきなのか?については、まとまった解説を見たことがありません。 無名関数式については、本当にやるかどうかは別として、デバッグ時は名前付きにしておくという方法があったと思います。アロー関数については最近使ってみた程度のため実際のところよくわかりませんが、そうなのですね。ありがとうございます。 また、これは著者の考え方によるところもあるのかもしれませんが、 [O'Reilly Japan - シングルページWebアプリケーション](http://www.oreilly.co.jp/books/9784873116730/) では、無名関数式の利用に徹していると感じました。ではなぜ、この本の著者はこの書き方をしたのか?という思想的なところについては、残念ながらよく分かりませんでした。その辺の不明瞭感を取り除きたいと思いこちらで質問しました。 ▼書籍内で扱うコードです(github上に上がっているコードを拝借して) https://github.com/inouetakuya/spa/blob/master/ch09/9.5.4-caching/lib/crud.js
think49

2016/04/16 13:12 編集

無名関数式で書かれているところは名前付き関数式に変えても動きます。つまり、関数式は無名関数式である必要性はないのです。 アロー関数は this 値が束縛されない為、this 値を変更したくない場合において利用価値があります。
raccy

2016/04/16 14:05 編集

> 無名関数式は名前付き関数式に変更しても動く為、基本的には名前つき間数式を使うと良いと思います。 名前付き関数式が書けないCoffeeScriptは滅ぶべしということ言うことですね。わかります、わかります。激しく同意しておきます。 (えっ、自分の回答ではCoffeeScript使っているとかいってなかったかって?まぁ、あれはあれだ、きっと偽物とか、別人格とか、平行世界の俺とかそういうのに違いない)
bleurouge

2016/04/16 15:47

ありがとうございます。いや、目的によって使い分けるものであるのだよ。と。なぜそれなのか?という方針という面で、説得力のある使い分けができそうです。さて、Coffeeの話題も出ていますが、CoffeeScriptから入ってes6を使い始めるとアロー関数で書けるならーとコンパイルしていたことが忘れ去られて、なんでもアローなことになってしまいそうです。勉強になりました。 まだ、他の視点の意見も出てきそうなので、もうすこしオープンで置いておきたいと思います。
think49

2016/04/17 02:57

> 匿名関数式(アロー関数式も)でもES2015からは代入文等名前が付けられそうなコンテキストであればFunction#nameは付きます。 なるほど、と思って試してみましたが、Google Chrome と Firefox で異なる動きをしました。 - Google Chrome も Firefox も Function#name が変更されない - Google Chrome は関数を参照コピーした後に元の変数 fn1, fn2 に null を代入すると TypeError (関数名がないので自然な動き) - Firefox は上記の null 代入後に TypeError にならないがコンソールに何も出力されない (???) https://jsfiddle.net/j9mt2euf/1/ しかし、アロー関数で関数名を指定できるとなると以前の質問内容も訂正しておく必要がありそうですね…。 https://teratail.com/questions/24115
think49

2016/04/17 08:37

ありがとうございます。今一度、検証し直してみます。
guest

0

私自身は基本的にCoffeeScriptしか書かないので、悩んだことはありません。CoffeeScriptでは関数宣言にあたる記法はありませんが、問題になったことはありません。そもそも、基本的にクラスを書くことになるため、クラスとは関係ない関数を単独で書くことはラムダ式扱いの無名関数を除くとほとんどありません。


私自身のことは置いておいて、2016年で最も良い方法は?と言われた場合、お勧めするのは、

TypeScriptを用いてクラスベースで書く

です。

複雑かつ大規模化する昨今のJavaScriptにおいて、TypeScriptの静的型付けはかなり大きなアドバンテージを得られます。また、基本的にクラスのメソッド(メンバー関数)として書くようにすることで、関数を単独で書くこと自体をなくします。ですので、関数宣言と関数式のどちらでもなく、クラスでのメソッドの書き方とラムダ式としての無名関数以外で関数を書くことがなくなります。

プロトタイプベースオブジェクト指向はとても柔軟で強力ですが、いかんせん使いこなすにはテクニカルな部分が多く、かなりの知識と慣れが必要になります。反面、クラスベースオブジェクト指向はデザインパターンなどの研究も進んでおり、他言語での採用が多いことから、扱いやすさと言う面では圧倒的と言っても良いでしょう。クラスベースオブジェクト指向を前面に出し、クラスを基本として記述することが最良と考えています。

JavaScriptを関数型言語として扱い、関数を主体としたいと考える人もいるでしょう。しかし、JavaScriptは関数型言語としては不十分な点が多く、扱いにくいと私は思っています。TypeScriptも関数型言語としての側面は重要視しておらず、JavaScriptに準じています。より関数型言語のように扱いたければ、PureScriptやLiveScriptの採用を検討すべきです。これらには、関数のカリー化や部分適用、関数合成、パイピング、リスト内包表記、モナド(PureScriptのみ)、そして強力なPreludeが用意されており、関数型プログラミングがとても書きやすくなっています。

ECMAScript2015でも良いのではと思うかも知れませんが、TypeScriptの静的型付けが強力なため、ECMAScript2015を使うメリットがあまりありません。Reactを使う場合はBabelを使ってJSX変換で優位というのもありましたが、TypeScriptがJSX表記に対応したため、TypeScriptを使わない理由が無くなりました。node.jsやElectronであれば、ネイティブである程度対応しているというのは確かにありますが、V8エンジンも全てに対応しているわけで無いこと、他ブラウザ向けにするときはES5に変換が必須なことを考えると、結局、TypeScriptと同じように変換は必要になったりします。そもそもその変換も多くのタスクツールが用意されているため、それほど問題になりません。また、規模が小さく、静的型付けを使うほどでも無いというのであれば、CoffeeScriptを使った方がはるかに楽です。

以上、かなり偏った意見ですが、参考になれば幸いです。なお、私自身はOpalを検討中ですが、色々とうまくいかないところがあるのでちょっと悩み中です。

投稿2016/04/16 13:46

編集2016/04/16 14:10
raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bleurouge

2016/04/16 15:44

これは致し方ないところなのだと思いますが、単純にJavaScriptと言った場合でも範囲の広がりがすさまじいですね。規模を考えた場合の切り口と、さらにブラウザ向けを考える時の切り口も入れると、選択肢多彩で、適宜要件に応じて考えろ。と。トランスコンパイラもなんだか乱立で、いや最初からrubyで書いたほうがいいじゃんwみたいなものまで出てくると果たしてJavaScriptとは何であるのか、みたいな。JavaScriptを捉える視点が多様化している様でおもしろいです。素敵な回答をありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問