首页 文章

封闭函数在执行后或返回闭包函数后驻留在哪里?

提问于
浏览
1

了解了闭包的基本知识后,有一个疑问仍然困扰着我:

Where does enclosing function reside post its execution or after returning closure function ?

我相信函数驻留在堆栈数据结构中,并且一旦函数完成其执行/返回任何值,就会从堆栈顶部敲掉 .

但是在Closures中,内部函数仍然必须访问Enclosing函数的状态,如何?

function sayHello(name) {
  var text = name + ' !!!'; // Local variable
  return function(wish) { console.log(wish + ', ' +text); }
}

var say = sayHello('Bob');

say('Hey');
say('Hello');

一旦它返回一个函数, sayHello 在哪里,从函数堆栈框架中删除它?

1 回答

  • 1

    这是一篇非常好的文章 .

    https://dmitryfrank.com/articles/js_closures

    范围链

    当任何JavaScript代码执行时,它需要一些地方来存储其本地变量 . 让我们将这个地方称为范围对象(有些人将其称为LexicalEnvironment) . 例如,当您调用某个函数,并且函数定义局部变量时,这些变量将保存在范围对象上 . 您可以将其视为常规JavaScript对象,但明显不同的是您无法直接引用整个对象 . 您只能修改其属性,但不能引用范围对象本身 .

    范围对象的这个概念与C或C非常不同,其中局部变量存储在堆栈中 . 在JavaScript中,范围对象在堆中分配(或者至少它们的行为类似),因此即使函数已经返回,它们也可能保持分配状态 . 稍后会详细介绍 .

    正如您所料,范围对象可能具有父对象 . 当代码尝试访问某个变量时,解释器会查找当前范围对象的属性 . 如果该属性不存在,则解释器将移动到父作用域对象,并在那里查找 . 依此类推,直到找到 Value ,或者没有更多的父母 . 让我们将这个范围对象序列称为范围链 .

    在范围链上解析变量的行为与原型继承非常相似,同样有一个值得注意的区别:如果您尝试访问常规对象的某些不存在的属性,并且原型链也不包含此属性,这不是错误:未定义的是静默返回 . 但是,如果您尝试访问作用域链上的不存在的属性(即访问非现有变量),则会发生ReferenceError .

相关问题