js执行过程之上下文对象(Context)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

js执⾏过程之上下⽂对象(Context)
在js的学习中,我们已经不满⾜于仅了解js的基础知识,⽽是开始追求更深层次的学习。

因为你会发现,仅了解js的基础知识,在开发项⽬的过程中是远远不够的。

今天就来介绍⼀下在js执⾏过程中的⼀些相关内容了。

JavaScript运⾏环境
JavaScript的运⾏不是像C++,Java等编译语⾔编译后直接在操作系统上运⾏,因为它是脚本语⾔,运⾏时必须要借助引擎来运⾏,所以它可以在封装了引擎的环境下运⾏。

⽽当js运⾏时,它会有不同的运⾏环境。

Global Code -- JavaScript代码开始的默认运⾏环境
Function Code -- 代码执⾏在JavaScript函数中
Eval Code -- 使⽤eval()执⾏代码
JavaScript运⾏过程
Js的执⾏过程可分为两个重要的时期预编译期(预解析期)和执⾏期。

预编译期
1. 浏览器的JavaScript引擎“解析”js代码
2. 建⽴arguments对象,函数,参数,变量
3. 建⽴作⽤域链
4. 确定this的指向
执⾏期
按照从上到下的顺序执⾏代码。

执⾏上下⽂
概念
如何区分不同的运⾏环境,需要引出的⼀个概念就是执⾏上下⽂(Execution Context)。

它是⼀个对象,由js的执⾏引擎创建,具有三个属性:变量对象(variable object),作⽤域链(scope chain),this指针。

上下⽂栈
js在执⾏过程中会有⼀个上下⽂栈,上下⽂栈中存放的就是不同的上下⽂对象(你可以理解为不同的js运⾏环境)。

⽐如当js开始执⾏⼀个函数,那此时它的运⾏环境从原来的Global Code变为Function Code,js引擎会创建⼀个context对象,并将其压如栈中。

当这个函数执⾏完后,这个对象将会弹出。

故⽽,当前执⾏代码的context对象总是在栈顶。

var a = 1;
function plus(a, b) {
var c;
c = a + b;
return c;
};
plus(1, 2);
function minus() {
var d = 3;
function get() {
var e = 4;
return e;
}
return d - get();
};
minus();
变量对象
变量对象是context对象中的⼀个重要属性,其创建过程如下:
1. 创建arguments对象,其中保存有多个属性,属性的key值是'0','1','2'......,value值就是传⼊的参数的实际值。

2. 找到这个作⽤域内的所有var和function的声明,作为属性存储在变量对象中,如果是function,那属性名就是函数名,属性值是函数的
引⽤。

如果是var,那属性名就是变量名,属性值是undefined.
理解了变量对象创建的过程,你就可以理解为什么会有变量提升这个特性了。

console.log(a); // undefined
var a = 1;
以上代码预解析后的实际过程可理解为:
var a;
console.log(a);
a =1
function声明的函数也是⼀样的原理:
f(); // 1
function f() {
var a = 1;
console.log(a);
}
以上代码预解析后的实际过程可理解为:
function f() {
var a = 1;
console.log(a);
}
f(); // 1
既然var声明和function声明都具有变量提升的特性,那var和function哪⼀个的声明在前呢?其实从上⾯的变量对象的创建过程中我们就已经知道了,为了看的清楚,我们⽤函数表达式的⽅式来声明⼀个函数检测⼀下。

f();
var f = function (){
var a = 1;
console.log(a);
};
function f(){
var b = 2;
console.log(b);
};
f();
控制台打印效果
显然是function的声明在前。

看了变量对象的创建过程,是不是觉得它和js执⾏过程中预编译期的第2步⾮常相似。

没错,其实在js的预编译时期所做的⼯作实际上就是创建Global Execution Context的过程。

它的第2步,就是context对象中创建变量对象的过程。

看到这⾥,是不是⼜有⼀个新的疑惑,为什么在最初的时候我们是在代码还没有开始执⾏的时候就已经创建了Global Execution Context对象,⽽之后是在要执⾏函数之前,才创建context对象呢?需要理解的⼀点就是函数体的预解析发⽣在函数被调⽤之时,被调⽤时先进⾏函数体的预编译,然后按顺序进⾏执⾏。

如果这段js代码是运⾏在浏览器端的,那么你猜到此时的Gobal Execution Context中的变量对象是什么了吗?没错,它就是window对象。

但是当它是运⾏在服务器端的时候,全局上下问的变量对象却不是它的全局对象global。

为什么呢?各位可爱的读者可以⾃⼰来探索⼀下哦。

相关文档
最新文档