首页 > 解决方案 > Javascript 原型链与作用域链

问题描述

我创建了一个 javascript 代码片段,这里是可视化工具的链接

function Foo(name) {
  this.name = name
  this.speak = function() {
    console.log(this.name)
  }
}

function init() {
  function init_() {
    var foo = new Foo('foo')
    foo.hear = function() {
      console.log('i can hear')
    }
    var bar = new Foo('bar')
    bar.look = function() {
      console.log('i can look')
    }
    foo.speak()
    bar.speak()
  }
  
  init_()
}

init()

我有几个问题:

  1. 原型对象又是在哪个阶段Foo.prototype创建的?解释器何时加载Foo到全局范围或何时new Foo()第一次被调用,或在任何其他阶段?它的引用存储在哪个词法范围内?(因为在可视化器中没有这样的参考)

  2. 应该foobar共享speak()属于Foo.prototype而不是拥有自己的副本的方法,如可视化器所示?

  3. 原型链和范围链不相关吗?例如,当foo.speak()被调用时,首先我们跟踪作用域链来获取 的值foo,然后原型链来获取speak()?

在此处输入图像描述

标签: javascriptscopelexical-scopeprototype-chain

解决方案


原型对象又是在哪个阶段Foo.prototype创建的?解释器何时加载Foo到全局范围?

是的,原型对象是在创建Foo函数时创建的。

它的引用存储在哪个词法范围内?(因为在可视化器中没有这样的参考)

根本没有。它仅存储在Foo.

应该foobar共享speak()属于Foo.prototype而不是拥有自己的副本的方法,如可视化器所示?

是的。看起来可视化器是为 Python 构建的,根本不支持原型链接。

原型链和范围链不相关吗?例如,当foo.speak()被调用时,首先我们跟踪作用域链来获取 的值foo,然后原型链来获取speak()?

是的是的。

但是请注意,您找到的可视化工具不显示范围链,它只显示调用堆栈,并且在正确可视化词法范围和闭包方面做得非常糟糕。


推荐阅读