认识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 ...
随机推荐
- 2014ACM/ICPC亚洲区域赛牡丹江站现场赛-K ( ZOJ 3829 ) Known Notation
Known Notation Time Limit: 2 Seconds Memory Limit: 65536 KB Do you know reverse Polish notation ...
- ubuntu终端方向键不能用(主机名不显示)问题的解决
sudo gedit /etc/passwd 在/etc/passwd中改动该用户相应的shell:/bin/sh改为/bin/bash就可以解决该问题
- Coreseek:indexer crashed神秘
浩哥前两天让我再Coreseek该指数再次这样做,由于需求方面变化不大,公司名称应出现指数.在添加的配置文件的面孔sql_field_string:串场.. 此属性特别有用,因为它不仅作为过滤器的特性 ...
- SVN的log,cat,list,diff的使用
svn log 展示给你主要信息:每个版本附加在版本上的作者与日期信息和所有路径修改. svn diff 显示特定修改的行级详细信息. svn cat ...
- linq 中执行方法
Database1Entities db = new Database1Entities(); protected void Page_Load(object sender, EventArgs e) ...
- Python的包管理
0.Python的包管理 在刚开始学习Python的时候比较头疼各种包的管理,后来搜到一些Python的包管理工具,比如setuptools, easy_install, pip, distribut ...
- NVL NVL2 NVLIF
========Oracle=======NVL (expr1, expr2)->expr1为NULL,返回expr2:不为NULL,返回expr1.注意两者的类型要一致
- 初识缓存以及ehcache初体验
1.缓存的意义 缓存机制就是将数据库中经常使用的数据取出放入内存中.程序调用时直接从内存中取,丌用每次使用 数据都訪问数据库,这样提高了效率. 2.缓存须要关注的问题 1) 缓存的更新 缓存中的数 ...
- android 自己定义开关(SwitchButton)
近期心血来潮,写了一个自己定义仿iPhone的开关. 有须要的同学能够来下载啦.支持点击自己主动滚动,速率能够自己依据须要改动.触摸滚动,大小自己定义,支持改动样式.就不录制动画,就上传了两张图给大家 ...
- oracle spfile和pfile文件(转)
--======================== -->Oracle 参数文件 --======================== /* 参数文件(10g中的参数文件) 主要用来记录数据库 ...