問題
名前付き関数式を使用しています- 関数式の名前はその関数のスコープ外では使用できません:
// Function statement
function statement() {
console.log("statement is a type of " + typeof statement);
}
statement();
console.log("statement is a type of " + typeof statement);
結果:
statement is a type of function
statement is a type of function
一方:
// Function expression with a name
var expression = function namedExpression() {
console.log("namedExpression is a type of " + typeof namedExpression);
};
expression();
// namedExpression(); // uncommenting this will cause an exception
console.log("expression is a type of " + typeof expression);
console.log("namedExpression is a type of " + typeof namedExpression);
生成されます:
namedExpression is a type of function
expression is a type of function
namedExpression is a type of undefined
ソリューション
何をしようとしているかに応じて、次のいずれかを実行します。
ステートメントを使用するように関数宣言を変更してから、関数にエイリアスを設定します。
function addNums(a, b) {
return a + b;
}
var add = addNums;
両方の名前を式にエイリアスします。
var add = addNums = function addNums(a, b) {
return a + b;
};
なぜ JavaScript はこのように動作するのでしょうか?
名前付き関数式は、それ自体の内部で関数を参照でき、デバッガーで参照する名前を与えるので便利です。ただし、関数を値として使用する場合、通常、関数の一部が外側のスコープに漏れることは望ましくありません。検討:
(function setup() {
var config = retrieveInPageConfig();
if (config.someSetting) {
performSomeOtherSetup();
}
kickOffApplication();
})();
これは関数式の完全に正当な使用法です。このような場合、名前が外側のsetup
スコープに漏れることは期待できません。名前付き関数式を変数に代入することは、これの特殊なケースであり、たまたま関数ステートメントの宣言のように見えます。