什么是执行期上下文
首先,按照ECMAScript的规范,一共有三种类型的代码,全局代码(游离于任何函数体之外),函数代码,以及eval代码(eval接受字符串)。全局上下文仅有一个,函数上下文和eval上下文则可能有多个。引擎在调用一个函数时,进入该函数上下文,并执行函数体,函数体内可以有递归,也可以调用其他函数(进入另外一个上下文,此时调用者被阻塞,直至返回)。调用eval会有类似的情况。
对应的,执行期上下文对象也有三类,每个上下文对象都有一些必须的属性用以为执行于其上的代码服务,以及记录/跟踪代码执行状态等。
一个典型的上下文对象的结构如下:
{
Execution:context,variable:object,scope:chain,this:value,
}
执行期上下文对象是以栈(先进后出)存储的,全局上下文对象第一个进栈,然后函数上下文和eval上下文对象依次进栈。
什么是this
this是执行期上下文对象的一个属性,指向执行期上下文对象自身,可以称之为上下文对象。
对于全局上线文对象,this就是全局上下文对象自身
什么是作用域链scope
每个上线文对象都有一些可访问变量variable,当执行代码调用的变量在当前上下文未定义时,编译器会沿着作用域链顺序向上一级上下文对象查找,最外层的上下文对象即为全局上下文对象。
如下代码演示scope:
var gbl_top = 1;
(function outter(){
var func_top = 2;
(function inner(){
var func_last =3;
console.log("%s,%s,%s",gbl_top,func_top,func_last);
})();
})();
inner上下文对象的作用域链就是 outterContext->globalContext;
对象的属性链
与作用域链相类似,对象的fields也是使用的链式查找方式,当在当前对象的fields中查找不到匹配的field时,就会从对象的__proto__属性的fields中查找匹配;如果__proto__的fields中也找不到匹配的时,则会继续搜索__proto__.__proto__,以此纵向查找,直到匹配或__proto__为null;
__proto__是什么?
__proto__是原形对象,对Function对象来说默认情况下__proto__就是声明时创建的第一个实例对象。
new都做了什么
先定义一个函数对象var sharp = function(name){this.sharp_name = name;}
,然后我们来看看new是怎么工作的:var circle = new sharp("circle")
这段代码相当于var circle = {};sharp.apple(circle,["circle"])
,我们看到new其实就是一个委托调用的语法糖。