javascriptscopelexical-scopeprototype-chain

Javascript prototype chain vs scope chain


I created a javascript code snippet and here's the link to visualiser

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()

I have several questions:

  1. In which stage is prototype object aka Foo.prototype created? When the interpreter loads Foo to global scope or when new Foo() is been called for the first time, or in any other stage? In which lexical scope is its reference stored? (since there's no such ref in visualiser)

  2. Should foo and bar share the method speak() which belongs to Foo.prototype rather than owning their own copies as shown in visualiser?

  3. Are prototype chain and scope chain unrelated? For example, when foo.speak() is called, first we trace scope chain to get value of foo, then prototype chain to get speak()?

enter image description here


Solution

  • In which stage is prototype object aka Foo.prototype created? When the interpreter loads Foo to global scope?

    Yes, the prototype object is created when the Foo function is created.

    In which lexical scope is its reference stored? (since there's no such ref in visualiser)

    In none at all. It's stored only in a property of Foo.

    Should foo and bar share the method speak() which belongs to Foo.prototype rather than owning their own copies as shown in visualiser?

    Yes. It seems like that visualiser was built for Python and does not support prototype links at all.

    Are prototype chain and scope chain unrelated? For example, when foo.speak() is called, first we trace scope chain to get value of foo, then prototype chain to get speak()?

    Yes, yes.

    Notice however that the visualiser you found does not display the scope chain, it only does display the call stack, and does very bad at visualising lexical scope and closures correctly.