You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jun 2, 2022. It is now read-only.
Variable object is a container of data associated with the execution context. It's a specail object that stores variables and function declarations defined in the context.
JavaScript Core
An object
我们定义了一个变量
foo
,它有两个自己的显性属性和一个内含的属性__proto__
,它就是foo
原型的索引。那原型的存在是有什么作用吗?
A prototype chain
原型对象也仅仅只是简单的对象而已,它们同样可能有自己的原型对象。假如一个原型有一个非
null
的索引,指向它的原型,如此这般,就称为原型链。传统面向对象语言是一句类的继承,而ECMAScript中没有类的概念,所以有了基于原型的继承。
正是由于原型链的存在,
c
和b
才能访问到a
中的calc
方法。而这其中的规则也是很简单的:假如一个属性或者方法不能在它本身找到,那就会沿着原型链,直到找到为止,或者返回undefined
。如果需要实例化很多个对象,它们拥有相似结构,但是却又有不同的值,这时候我们就需要Constructor了。
Constructor
构造函数不仅仅是新建对象的模式,同时它还自动为新建对象设置了
__proto
属性。这个原型对象存储在ConstructorFunction.prototype
属性中。通过使用构造函数我们重新之前的例子:
Execution context stack
ECMAScript规定有三种不同类型的代码:全局代码,函数级代码,eval代码。每一类都有自己的执行上下文。其中全局执行上下文总是只有一个,而每一次函数调用都有函数执行上下文生成和执行相应的代码的过程,eval同样也有eval执行上下文生成和执行相应的代码的过程。一个函数可能会的执行可能会生成有限个执行上下文,从逻辑上说,这形成了一个成为执行上下文栈的栈结构。
激活另一个上下文的上下文称为caller,被激活的上下文称为callee。而callee同样可能是另一个上下文的caller。
当caller激活一个callee时,caller会先挂起自己的运行,并控制权交给callee。callee被推倒栈的顶部,成为运行的执行上下文。callee执行结束后,程序控制权交还给caller,caller上下文继续执行,直到结束。
所有的ECMAScript程序运行时都可以看为执行上下文栈,其中顶部即为当前运行的上下文:
上图就是ECMAScript运行系统对代码执行的管理过程。
执行上下文
我们可以将执行上下文抽象为一个简单的对象。它用一系列的属性(执行状态)来跟踪记录程序执行:
变量对象
变量对象是一个抽象对象。不同类别的上下文,用不同的对象来表示。例如,在全局上下文中,全局变量对象就是全局对象本身,这也就是为什么能直接通过全局对象的属性来访问全局变量的原因。
全局变量对象可以用下图表示:
Activation object
当一个函数被它的caller调用时,会新建一个激活对象。它包含有形参和一些特殊的参数对象,这个对象就是函数上下文的变量对象。
一个函数的变量对象也仅仅是简单的对象而已,只是除开变量和函数声明外,还储存有形参和arguments。
Scope chain
它的规则和原型链相似:当一个变量不能再自己的作用中找到时,它会沿着父级作用域查询,直到找到为止。
我们可以假设,作用域对象中存在一个
__parent
的属性,它指向作用域中的下一个对象。另外,我们可以把作用域链简化为一个数组。利用__parent__
的概念,我们可以讲以上的代码表示为下图,其中父级变量对象保存在函数的[[Scope]]
属性中。The text was updated successfully, but these errors were encountered: