JavaScript js 面向栈的问题

ane · 2014年02月10日 · 最后由 geraldchen 回复于 2014年03月05日 · 2266 次阅读
function testFn() {

  var localVar = 10;

  function innerFn(innerParam) {
    alert(innerParam + localVar);
  }

  return innerFn;
}

var someFn = testFn();
someFn(20); // 30

someFn(20);是如何将 20link 到 innerParam 的?

someFn 就是 innerFn。

#1 楼 @jasli2 此话怎解,可否细细道来

函数也可以返回。

#3 楼 @rasefon 哦,我想通了

#4 楼 @u1378130755 那你知道为什么函数能够调用到 localVar 不?这个想通了才是真想通。

#5 楼 @linjunhalida localVar 被放在 testFn 的堆中

#5 楼 @linjunhalida “localVar 被放在 testFn 的堆中”这样说也不太对。大多数人会解释为“testFn() 的作用链保存了上下文环境”。不知道说的对不对,求进一步详解

#7 楼 @u1378130755 准确的说是保存在了 innerFn 的上下文中,someFn 调用的时候是在 innerFn 的上下文中。

Javascript 的执行环境分为三个 global, function 和 eval code。

// global context
function testFn() {
  // context1
  var localVar = 10;

  function innerFn(innerParam) {
    // context2
    alert(innerParam + localVar);
  }

  return innerFn;
}

var someFn = testFn();
someFn(20); // 30

程序按执行顺序将 执行上下文(栈帧)压入栈 压栈顺序 global -> context1 -> context2 弹栈顺序 context2 -> context1

Javascript 提供了一种机制可以让 context2 访问到 context1,我没找着相关虚拟机实现。 类似 Java 的内部类是在编译时给 内部类一个隐含成员指到外部实例。Javascript 就是通过作用域链查找到上一个执行上下文。

innerFn 在执行前 testFn 是不会出栈的,所以可以在 innerFn 回溯到 testFn 的上下文。

#12 楼 @saiga 好人一生平安

#12 楼 @saiga “类似 Java 的内部类是在编译时给 内部类一个隐含成员指到外部实例。Javascript 就是通过作用域链查找到上一个执行上下文。”这句话让我想起来,当年看 threadlocal 源码的时候遇到过,现在幡然明白,那样写的原因

testFn() = innerFn;//innerFn 保存 testFn 作用域,localVar 在其中 someFn(20) = innerFn(20);

需要 登录 后方可回复, 如果你还没有账号请 注册新账号