次のコードを検討してください。
<!DOCTYPE html>
<script>
console.log(a);
function a() {}
</script>
a
が定義される前にアクセスされているように見えることに注意してください。コンソール出力は次のとおりです: ( jsfiddle )
function a() {}
関数名と変数名は他のコードが実行される前に定義されるため、console.log 呼び出しはここで機能します。これを巻き上げといいます。
ただし、関数が関数呼び出しでパラメーターとして定義されている場合、これは機能しません。このコードを見てください。
<!DOCTYPE html>
<script>
function a() {}
a(function b() {});
console.log(b);
</script>
b
関数が への呼び出し内で定義されていることに注意してくださいa
。クロージャーの内部ではなく、呼び出しの内部。コンソール出力は次のとおりです: ( jsfiddle )
Uncaught ReferenceError: b is not defined
なぜこれが起こるのか疑問に思っています。これは意図した動作ですか?これは、Chrome と Firefox の両方で発生します。
更新:このjsfiddleは、関数式の名前が、それらが定義されているスコープでは使用できないことを示しています。ただし、名前は関数自体のスコープ内で定義されます。つまり、名前付き関数式は名前を参照できますが、関数内でのみ参照できます。name
名前は、関数のパラメーターにも格納されます。
<!DOCTYPE html>
<script>
console.log(a); // undefined
var a = function b() {
console.log(b); // function b() { … };
};
a(); // function b() { … };
console.log(a); // function b() { … };
console.log(a.name); // b
console.log(b); // Uncaught ReferenceError: b is not defined
</script>