问题描述
我创建了一个javascript代码段,这是指向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()
我有几个问题:
-
在哪个阶段创建了原型对象aka
Foo.prototype
?解释器何时将Foo
加载到全局范围,或者何时第一次调用new Foo()
或处于其他任何阶段?它的引用存储在哪个词法范围内? (因为在可视化工具中没有这样的引用) -
foo
和bar
应该共享属于speak()
的方法Foo.prototype
而不是像可视化工具中所示那样拥有自己的副本吗? -
原型链和作用域链不相关吗?例如,当调用
foo.speak()
时,首先我们跟踪作用域链以获取foo
的值,然后我们跟踪原型链以获取speak()
?
解决方法
在哪个阶段创建了原型对象
Foo.prototype
?解释器何时将Foo
加载到全局范围?
是的,创建Foo
函数时会创建原型对象。
其引用存储在哪个词法范围内? (因为在可视化工具中没有这样的引用)
完全没有。它仅存储在Foo
的属性中。
foo
和bar
是否应该共享属于speak()
的方法Foo.prototype
,而不是像可视化工具所示那样拥有自己的副本?
是的。似乎visualiser是为Python构建的,根本不支持原型链接。
原型链和作用域链不相关吗?例如,当调用
foo.speak()
时,首先我们跟踪作用域链以获取foo
的值,然后我们跟踪原型链以获取speak()
?
是,是。
但是请注意,您发现的可视化工具不会显示作用域链,它只会显示调用堆栈,并且在正确可视化词法作用域和闭包方面非常不利。