208
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

Organization

【JavaScript】関数定義いろいろ

JavaScriptで関数を定義する方法は、一般的に3つに分かれる。
ここではそれらの定義方法と挙動の違いに触れる。

関数コンストラクタ

var addConstructor = new Function('x', 'y', 'return x + y');
console.log(addConstructor(1,2)); // 出力:3

関数コンストラクタによる定義方法では、末尾の引数が関数本体を表し、それ以外の引数が関数本体に渡すべき引数を表している。
特長として、「関数の本体部分を文字列として指定できる」点が挙げられるが、記述が他の定義方法に比べてシンプルでないことや、パフォーマンスの観点などから避けるべきとされている。

関数式(関数リテラル)

var addExpression = function(x, y) {
  return x + y;
};
console.log(addExpression(1,2)); // 出力:3

式による関数定義は一番よく見る形である。
関数定義と同時に変数へ代入するような形式をとり、またその関数は名前がついていない場合が多い(無名関数や匿名関数といわれる)。
関数名をつけた場合には再帰を実現することができ、またその関数名は関数本体の外側で使用された場合にエラーとなる。

var foo = function hoge(x) {
  console.log(x);
  x--;
  if(x<0) {return;}
  // 再帰(関数名hogeを使用できる)
  hoge(x);
};
foo(5); // 出力:5 4 3 2 1 0
hoge(5); // エラー:hoge is not defined
// 関数名hogeを関数外で使用することはできない

また、関数が代入された変数には再代入することが可能である。

var calc = function(x, y) {return x + y};
console.log(calc(5, 3)); // 出力:8
// 別関数を再代入
calc = function(x, y) {return x - y};
console.log(calc(5, 3)); // 出力:2

関数宣言

function addStatement(x, y) {
  return x + y;
};
console.log(addStatement(1, 2)); // 出力:3

関数宣言の定義方法は関数式とほぼ同じ形式で、式として扱われているか否かくらいの違いしかない。
ただ、関数宣言にしかない大きな特徴の一つに「ホイスト(巻き上げ)」がある。

console.log(bar(2, 3)); // 出力:6
// 定義は使用する箇所よりもあとに記述されている
function bar(x, y) {
  return x*y;
};

// 関数式による定義では巻き上げしない
console.log(foo(4, 5)); // エラー:undefined is not a function
var foo = function(x, y) {
  return x*y;
};

関数宣言はコード解析時に関数が登録されるため、定義記述前の呼び出しが可能だが、関数式では実行時に関数登録されるためにエラーとなる。

最後に

さらっとまとめましたが、やっぱり詳しく知りたいときはリファレンスが一番です。はい。
関数と関数スコープ

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
208
Help us understand the problem. What are the problem?