JavaScriptにおける関数のレキシカル環境の適用
ある関数が、その結果として別の関数を返すとします:
function test() {
return function() {
}
}
親関数が何らかの変数を持っている場合、それらの変数は返される関数のレキシカル環境に含まれます:
function test() {
let num = 1; // 親関数の変数
return function() {
// レキシカル環境 = {num: 1}
}
}
返される関数のコードに、変数
numの値を出力するconsole.logを記述しましょう:
function test() {
let num = 1;
return function() {
console.log(num);
}
}
では、親関数testを呼び出し、その実行結果を変数funcに代入しましょう:
function test() {
let num = 1;
return function() {
console.log(num);
}
}
let func = test();
変数funcには返された関数が代入されます。この関数を呼び出してみましょう。その結果、変数numの内容が出力されます:
function test() {
let num = 1;
return function() {
console.log(num);
}
}
let func = test();
func(); // 1を出力する
一方、関数の外で変数numを出力しようとすると、アクセスできません:
function test() {
let num = 1;
return function() {
console.log(num);
}
}
console.log(num); // ここでは変数numはアクセスできない
ご覧の通り、ローカル変数numはこの関数のレキシカル環境に結び付けられました。これで、コードのどこでこの関数を呼び出しても、変数numの値を取得できるようになります。たとえ呼び出し場所自体ではその変数が直接アクセスできなくてもです。
実は、変数numをグローバルにすることで同様の結果を得ることができます:
function test() {
return function() {
console.log(num);
}
}
let num = 1; // グローバル変数
let func = test();
func(); // 1を出力する
しかし、ここには重要な違いがあります:
新しいバージョンでは、変数numは関数の外からも変更できます(グローバル変数なので)。
一方、古いバージョンではできません。
コードを実行せずに、コンソールに何が出力されるか決定してください:
function test() {
let num1 = 1;
let num2 = 2;
return function() {
return num1 + num2;
}
}
let func = test();
console.log(func());
コードを実行せずに、コンソールに何が出力されるか決定してください:
function test() {
let num1 = 1;
let num2 = 2;
return function() {
return num1 + num2;
}
}
console.log(test()());
コードを実行せずに、コンソールに何が出力されるか決定してください:
function test() {
let num1 = 1;
return function() {
return num1 + num2;
}
}
let num2 = 2;
let func = test();
console.log(func());
コードを実行せずに、コンソールに何が出力されるか決定してください:
function test() {
let num = 1;
return function() {
return num;
}
}
let num = 2;
let func = test();
console.log(func());