JavaScript执行环境及作用域

执行环境(executin context)是JS中最为重要的一个概念。执行环境定义了变量或函数有权访问的其他数据决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保存在这个对象中。虽然我们编写的代码无法访问这个对象

,但解析器在处理数据时会在后台使用它。

全局执行环境是最外围的一个执行环境。根据JS实现的宿主环境不同,表示执行环境的对象也不一样。在Web浏览器中,全局执行环境被认为是Window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。某个执行环境中的所有代码执行完毕后,改环境被销毁,保存在其中的所有变量和函数定义也随之销毁(全局执行环境直到应用程序退出-例如关闭网页或浏览器时才会被销毁);

每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。JS程序中的执行流正是由这个方便的机制控制着。

当代码在一个环境中执行时,会创建变量对象的一个作用链域(scope chain)。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象(activation object)作为变量对象。活动对象在最开始时只包含一个变量,即arguments对象(这个对象在全局环境变量中是不存在的)。作用域链中的下一个变量对象来自包含(外部)环境,而再下一个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域中的最后一个对象。

标识符解析是沿着作用域一级一级地搜索标识符的过程。搜索过程始终从作用域链的前端开始,然后逐级的向后回溯,直至找到标识符为止(如果找不到标识符,通常会导致错误发生)。

var color="blue";
	function changeColor(){
		if(color==='blue'){
			color="red"
		}else
		color="blue";
	}
	changeColor();
	alert("Color is now "+color);

在这个简单的例子中,函数changeColor()的作用域链包含两个对象:它自己的变量对象(其中定义着arguments对象)和全局环境的变量对象。可以在函数内部访问变量color,就是因为可以再这个作用域链中找到它。

此外,在局部作用域中定义的变量可以再局部环境中与全局变量互换使用。

var color="blue";
	function changeColor(){
		var color1="red";
		function swapColors(){
			var color2=color1;
			color1=color;
			//这里可以访问所有的变量
		}
		//这里只能访问color1和color;
	}
	//这里只能访问color;
	changeColor();
	alert("Color is now "+color);

以上代码共涉及三个执行环境:全局环境,changeColor()的局部变量和swapColors()的局部变量环境。方法函数里面可以访问全局变量,但是无法访问比这个方法函数范围更小的局部变量,因为那两个环境都是它的父执行环境。

内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量和函数。这些环境之间的联系是线性,有次序的。每个环境都可以向上搜索作用域链,以查询变量和函数名;但任何环境不能通过向下搜索作用域链而进入另一个执行环境。在上面的这个例子中swapColors里包含三个对象:他会先从自己的变量对象中搜索变量和函数名,如果搜索不到则再搜索上一级作用域链。

延长作用域链:

虽然执行环境的类型只有两种-全局和局部。但还是有其他办法来延长作用域链。就是在有些语句可以再作用域链的前端临时增加一个变量对象,改变量对象会在代码执行后被移除。再两种情况下会发生这种现像。具体来说,就是当执行流进入下列任何语句的时候,作用域就会得到加长:

try-catch语句的catch块;

with语句;

这两个语句都会在作用域链的前端添加一个变量对象。对with语句来说,会将指定的对象添加到作用域链中。对catch语句来说,会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。

var add = function(a,b){
if(typeof a!="number"||typeof b!="number"){
throw{
name:"类型错误",
message:"参数需要number类型"
}
}
}
try{
add(1,"fg");
}catch(e){
	alert(e.name);
}
finally{
alert("finally");
}

当我们执行到if这段代码的时候会创建异常类,我们在throw里面会指定异常的名称和异常的提示。再catch里面会创建一个新的变量对象,但是我们在这个对象里面,可以得到这个所抛出的异常,这就是创建一个新的变量对象,并且它的作用域延长了。

没有块级作用域:

JS没有块级作用域经常会导致理解上的困惑。在我比

较熟悉的Java语言里面,由花括号封闭的代码都有自己的作用域。因而支持根据条件来定义变量。

if(true){
			var color="blue";
		}
		alert(color)

执行完这段代码,发现可以打印为blue;在Java中,color变量会在if语句执行完毕后被销毁。而在我们的JS中,if语句和for循环语句会被添加到当前的执行环境也就是全局变量中;

for(var i=0;i<=10;i++){

		}
		alert(i); //11

当执行完循环之后,i的值为11,有人说这里为什么不是10啦。我也很奇怪,在早起的JS里面这个i打印出来应该是10的,后来为了区分开来,在for循环结束之后又累加了一次。

声明变量:

使用var声明的变量会自动被添加到最近的环境中,也就是我们所谓的函数局部环境,在with语句中,最接近的环境是函数环境。如果初始化时变量没有使用var声明,该变量为自动被添加到全局环境。

function add(num1,num2){
		 sum=num1+num2;
		return sum;
		}
		var result=add(1,2);
		alert(sum); //3

查询标示符:

这个很好理解,当我们在某个环境中需要读取而引用一个标识符代表某种特定含义的时候,必须通过搜索来确定该标识符。搜索才有由近到远,由局部到全局,由小到大,如果查询到了相应的标示符将停止搜索;

var color="blue" ; //标示为黄色
		function getColor(){
		var color="red"; //标识为红色
			return color;
		}
		alert(getColor()); //red

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-21 12:59:37

JavaScript执行环境及作用域的相关文章

JavaScript 执行环境与作用域

前面我说到过,执行环境是js中最为重要的一个概念.执行环境定义了变量和函数有权访问的其他数据,决定了它们各自的行为. 在JavaScript中,每一个函数都表示为一个对象,更确切地说,是Function对象的一个实例.Function对象与其他的对象一样,都拥有可以编程访问的属性,和一系列不能通过代码访问而仅提供了JavaScript引擎存取的内部属性.譬如[[Call]]属性,表示这个对象可以被执行,其中有一个内部属性是[[Scope]],由ECMA-262标准第三版定义. 内部属性[[Sco

JavaScript 执行环境及作用域

在JavaScript高级程序设计中,执行环境的定义是:定义了变量或函数有权访问的其他数据,决定了它们各自的行为. 每个执行环境都有一个与之关联的变量对象,环境中定义了所有变量和函数都保存在这个对象中. 其实执行环境就是JavaScript中的作用域 每个函数都有自己的执行环境.当执行流进入一个函数时,函数的环境就会被推入一个环境栈中.而且在函数执行完之后,栈将环境推出,把控制权返回之前的执行环境. 内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中任何变量和函数.这些环境

第六章 javaScript执行环境和作用域

这个只是点对于初学者其实大概了解就可以,但是要研究明白javaScript的机制,就是非常必要的,这只是我的一些记录,大家参考即可,如有错误请指出. 执行环境的概念是javaScript一个虚拟的概念,如何定义它呢?它的作用又是什么呢?它是怎么组成的呢? 大家都比较认可的说法:执行环境又称为执行上下文,从实际的表现来看,可以把它理解为由“对象”组成的一个堆栈.既然是堆栈,就是先入后出了. 组成堆栈的对象是什么对象?我没有找到确切的定义,基于我自己的理解,这个对象是一个自定义对象,里边包含有变量.

Javascript执行环境、作用域链

一.执行环境 执行环境(也叫做执行上下文,Execution Context)是Javascript中最为重要的一个概念.执行环境定义了变量或函数有权访问其他数据,决定了它们各自的行为.每个执行环境都有一个与之关联的变量对象,执行环境中定义的所有变量和函数都保存在这个对象中.虽然我们编写的代码无法访问这个对象,但解析器在处理时会在后台使用它. 全局执行环境是最外围的一个执行环境.根据ECMAScript实现所在的宿主环境不同,表示执行环境的对象也不一样.在web浏览器中,全局执行环境被认为是wi

深入理解javascript中执行环境(作用域)与作用域链

相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享. 一般情况下,我们把执行环境分为全局执行环境和局部执行环境,其中局部执行环境我们又可以称之为函数执行环境.那么究竟什么使执行环境呢?通俗的说,执行环境即为代码执行时所处的环境.我们下来看一看如下代码,再进一步分析之. 1 2 3 4 5 6 7 8 9 10 11 <script><br>var name="zhuzhenwei"; functio

深入理解javascript作用域系列第五篇——一张图理解执行环境和作用域

× 目录 [1]图示 [2]概念 [3]说明[4]总结 前面的话 对于执行环境(execution context)和作用域(scope)并不容易区分,甚至很多人认为它们就是一回事,只是高程和犀牛书关于作用域的两种不同翻译而已.但实际上,它们并不相同,却相互纠缠在一起.本文先用一张图开宗明义,然后进行术语的简单解释,最后根据图示内容进行详细说明 图示 查看大图 概念 [作用域] 作用域是一套规则,用于确定在何处以及如何查找标识符.关于LHS查询和RHS查询详见作用域系列第一篇内部原理. 作用域分

Javascript高级程序设计——执行环境与作用域

Javascript中执行环境是定义了变量或函数有权访问的其他数据,决定了各自的行为,每个执行的环境都有一个与之关联的变量对象,环境中定义的所以变量和函数都保存在这个对象中. 全局执行环境是最外围的一个执行环境.全局执行环境被认为是window对象,所有全局变量和函数都作为window对象的属性和方法创建的.某个执行环境中的所有代码执行完后,该环境被销毁,保存在其中的所有变量和函数定义也随之销. 每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中,而在函数执行完

《JavaScript高级程序设计》读书笔记 ---执行环境及作用域

执行环境及作用域 执行环境(execution context,为简单起见,有时也称为“环境”)是JavaScript 中最为重要的一个概念.执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保存在这个对象中.虽然我们编写的代码无法访问这个对象,但解析器在处理数据时会在后台使用它.全局执行环境是最外围的一个执行环境.根据ECMAScript 实现所在的宿主环境不同,表示执行环境的

javascript 执行环境,变量对象,作用域链

前言 这几天在看<javascript高级程序设计>,看到执行环境和作用域链的时候,就有些模糊了.书中还是讲的不够具体. 通过上网查资料,特来总结,以备回顾和修正. 要讲的依次为: EC(执行环境或者执行上下文,Execution Context) ECS(执行环境栈Execution Context Stack) VO(变量对象,Variable Object)|AO(活动对象,Active Object) scope chain(作用域链)和[[scope]]属性 EC 每当控制器到达EC