LoginSignup
0
2

More than 5 years have passed since last update.

JavaScriptの関数内関数の変数スコープ

Posted at

基本的にはJavaScriptは現在のスコープからグローバルに向かって参照が行われます。
…が、少し想像していた動きと違ってしまうことがあったので調査してました。

test.js

var x = 0;
function a() {
  var x = 1;
  function b() {
    console.log("func b:x=" + x);
  }
  function c(v) {
    x = v;
  }
  return {"b":b,"c":c};  
}

console.log("Hello!");
console.log("x=" + x);
func = a();
func["b"]();
x=10;
console.log("x=" + x);
func["b"]();
console.log("x=" + x);
func["c"](15);
console.log("x=" + x);
func["b"]();
console.log("x=" + x);

次に実行結果を。

result.log
Hello! // こんにちは
x=0 // グローバルのxは今日も0なのである
// ここで関数aから関数bとcを取り出す
func b:x=1 // おそらく関数a内のxが参照されている
// グローバルのxを10に書き換える
x=10 // グローバルのxは書き換わったようだ
func b:x=1 // しかし関数bの返り値であるxは書き換わっていない
x=10 // しつこく見てみるが、グローバルのxも書き換わっていない
// そこで関数cによってxを書き換えてみる
x=10 // グローバルのxは書き換わらない
func b:x=15 // 関数a内のxは書き換わっている
x=10 // やっぱり書き換わってない

最近の言語は単純なスタックモデルを想定しているとうまく行かないのですね。
自分は関数aの変数xは関数x終了時に破棄されると思っていました。
この結果だと、関数bとcがアクセスできる状態であれば関数aの変数xも生きているようです。

ちゃんと書いてありました。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Functions#Preservation_of_variables

この場合、関数bとcがアクセスできなくなった場合にメモリが開放されるということで。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2