认识javascript范围和作用域链
范围
作用域就是变量和函数的可訪问范围。控制着变量和函数的可见性与生命周期,在JavaScript中变量的作用域有全局作用域和局部作用域。
全局和局部作用域以下用一张图来解释:
单纯的JavaScript作用域还是非常好理解的。
作用域链
全局运行环境是最外层的一个运行环境,在web浏览器中全局运行环境是window对象,因此全部全局变量和函数都是作为window对象的属性和放大创建的。每一个函数都有自己的运行环境,当运行流进入一个函数的时候。函数的环境会被推入一个函数栈中。而在函数运行完成后运行环境出栈并被销毁,保存在当中的全部变量和函数定义随之销毁,控制权返回到之前的运行环境中,全局的运行环境在应用程序退出(浏览器关闭)才会被销毁。
当代码在一个环境中运行时。会创建变量对象的一个作用域链(scope chain)来保证对运行环境有权訪问的变量和函数的有序訪问。
用一张图来解释作用域链的执行:由里向外执行。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemx0czAwMA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
当一个函数创建后。它的作用域链会被创建此函数的作用域中可訪问的数据对象填充,比如定义以下这样一个函数:
function add(num1,num2) {
var sum = num1 + num2;
return sum;
}
在函数add创建时,它的作用域链中会填入一个全局对象,该对象包括了全部全局变量。例如以下图所看到的:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemx0czAwMA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
函数add的作用域将会在运行时候用到。比如运行例如以下代码:
function a(sum1,sum2){
var sum=num1+num2;
return sum;
}
var tatal=a(5,10);
执行此函数时会创建一个称为“执行期上下文(execution context)”的内部对象,执行期上下文定义了函数执行时的环境。每一个执行期上下文都有自己的作用域链,用于标识符解析,当执行期上下文被创建时。而它的作用域链初始化为当前执行函数的[[Scope]]所包括的对象。
这些值依照它们出如今函数中的顺序被拷贝到执行期上下文的作用域链中。它们共同组成了一个新的对象,叫“活动对象(activation object)”,该对象包括了函数的全部局部变量、命名參数、參数集合以及this,然后此对象会被推入作用域链的前端。当执行期上下文被销毁,活动对象也随之销毁。新的作用域链例如以下图所看到的:
在函数运行过程中,没遇到一个变量,都会经历一次标识符解析过程以决定从哪里获取和存储数据。该过程从作用域链头部。也就是从活动对象開始搜索,查找同名的标识符。假设找到了就使用这个标识符相应的变量,假设没找到继续搜索作用域链中的下一个对象,假设搜索全然部对象都未找到。则觉得该标识符没有定义。
总结
依据上述讲的作用域链的结构能够看出,定义的标识符的越深。那么读写的速度也就越慢。而全局变量总是处于作用域链的最末端。所以当变量解析的时候,查找全局变量是最慢的,所以在编写代码的时候要尽可使用全局变量的可以少。使用局部变量越好。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
认识javascript范围和作用域链的更多相关文章
- javascript的关键所在---作用域链
javascript的关键所在---作用域链 javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript ...
- javascript闭包和作用域链
最近在学习前端知识,看到javascript闭包这里总是云里雾里.于是翻阅了好多资料记录下来本人对闭包的理解. 首先,什么是闭包?看了各位大牛的定义和描述各式各样,我个人认为最容易一种说法: 外部函数 ...
- javascript笔记:javascript的关键所在---作用域链
javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript技巧也是围绕作用域进行的,今天我要总结一下关于 ...
- Javascript——闭包、作用域链
1.闭包:是指有权访问另一个函数作用域中的变量的函数.创建闭包的常见方式:在一个函数内部创建另一个函数. function f(name){ return function(object){ var ...
- [译]JavaScript:函数的作用域链
原文:http://blogs.msdn.com/b/jscript/archive/2007/07/26/scope-chain-of-jscript-functions.aspx 在JavaScr ...
- JavaScript中的作用域链原理
执行环境 作用域链的形成与执行环境(Execution Environment)相关,在JavaScript当中,产生执行环境有如下3中情形: 1 进入全局环境 2 调用eval函数 3 调用func ...
- javascript 关于 this 作用域链
使用 function f() {} 或者 var f = function() {} 来定义的函数,this 是指向 全局对象 var a = { b: 1, c: funct ...
- javascript深入浅出图解作用域链和闭包
一.概要 对于闭包的定义(红宝书P178):闭包就是指有权访问另外一个函数的作用域中的变量的函数. 关键点: 1.闭包是一个函数 2.能够访问另外一个函数作用域中的变量 文章首发地址于sau交流学习社 ...
- JavaScript深入之作用域链
前言 在 <javascript深入之执行上下文栈> 中讲到,当javascript代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution ...
随机推荐
- hibernate得知——Set设置配置
Set设置配置 创建数据表:表关系的员工有多重身份 create table EMPLOYEE ( id INT NOT NULL auto_increment, first_name VARCHAR ...
- Problem and Solution Code Snippets
(积累知识,遇到发展,本文仅用于备忘录,不时它需要召回准备) Problem: 依据String的大小来调整Label的frame.在view中又一次更新views的layout并显示. Soluti ...
- Lucene全文检索的【增、删、改、查】 实例
创建索引 Lucene在进行创建索引时,根据前面一篇博客,已经讲完了大体的流程,这里再简单说下: Directory directory = FSDirectory.open("/tmp/t ...
- SWT的CheckBoxTreeView
其实CheckBoxTreeView和TreeView基本上是一样的,他们共同的方法有: TreeViewer 类封装了tree控件.树查看器按照父子关系来显示分等级的对象列表.此查看器需要设置标签供 ...
- ubuntu 12.10 软件更新源列表
ubuntu 12.10正式版已经发布了,国内各大开源软件源也陆续更新了资源.今天分享一下ubuntu 12.10 软件更新源列表. 首先,习惯性的备份一下ubuntu 12.04 原来的源地址列表文 ...
- Android平台调用Web Service:螺纹的引入
连接文本 剩下的问题 MainActivity的onCreate方法中假设没有有这段代码: // 强制在UI线程中操作 StrictMode.setThreadPolicy(new StrictMod ...
- 提高SQL执行效率
原文地址:http://www.cnblogs.com/hlxs/archive/2012/05/07/2487082.html 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 ...
- 数据库采用多表连接查询,对应javaBean文件连接方式
在一个Web项目中,只要是存在数据库就一定会有JavaBean文件.一个JavaBean文件会对应一张数据库中的表,供dao中的代码来调用用来存取数据.我们都知道,在数据库设计的时候,如果A.B两张表 ...
- 打开或导入项目,从脱机 Outlook 数据文件 (.ost)
打开或导入项目,从脱机 Outlook 数据文件 (.ost) Microsoft Outlook 2010 doesn\rquote t 支持手动打开或导入项目,从一个 脱机 Outlook 数据文 ...
- JavaScript采用append添加的元素错误
1.错误叙述性说明 于IE览器上: Uncaught HierarchyRequestError:Failed to excute 'appendChild' on 'Node':The new ch ...