谈一谈js中的执行环境及作用域


Posted in Javascript onMarch 30, 2016

最近在面试时被问到了对作用域链的理解,感觉当时回答的不是很好,今天就来说说js中的作用域链吧。

首先来说说js中的执行环境,所谓执行环境(有时也称环境)它是JavaScript中最为重要的一个概念。执行环境定义了变量或函数有权访问的其他数据 ,决定了它们各自的行为。而每个执行环境都有一个与之相关的变量对象,环境中定义的所有变量和函数都保存在这个对象中。

理解了执行环境,现在就看看什么是作用域链吧。每个函数都有自己的执行环境,当代码在执行环境中执行时,就会创建变量对象的作用域链。作用域链保证了对执行环境有权访问所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在的环境的变量对象,如果环境是一个函数,那么它的变量对象就是该函数的活动对象。作用域链的下一个变量对象来自包含(外部)环境,再下一个变量对象来自下一个包含环境。这样一直延续到全局执行环境,记住,全局执行环境的变量对象永远是作用域中的最后一个对象。

请看下面的例子:

var scope="global";
function foo(){
  console.log(scope);
}  
foo();

在这个例子中,函数foo()的作用域链包含了两个对象,一个是它自身对象,另一个是全局环境中的变量对象。因为我们可以在这个作用域链中找的scope,所以可以在函数内部里访问到它。

在看一个例子:

var color = "blue";
function changeColor(){
  var anoterColor = "red";
  function swapColor(){
    var tempColor = anoterColor;
    anoterColor = color;
    color = tempColor;
    console.log(color);
  }
  swapColor();
}
changeColor();

在这个例子中,有三个执行环境:全局环境、changeColor()的局部环境和swapColor()局部环境。我们来看看这个例子的作用域链是怎样的吧。

谈一谈js中的执行环境及作用域

图中的矩形表示特定的执行环境。我们可以看到变量tempColor只能在swapColor()环境中访问到,而在changeColor()的局部环境还是全局环境中都无法访问到它。因此我们可以得到一个结论:内部的环境可以通过作用域链访问所有的外部环境,但外部的环境无法访问内部的环境中的任何变量和函数。每个环境都可以向上搜索作用域链,以查询变量和函数名;但是任何环境都不能通过向下搜索作用域而进入另一个执行环境。

作用域中我还想说说的是:js没有块级作用域

为什么说js没有块级作用域呢?我们来看下面的代码:

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

咦,为什么color在if语句执行完毕后被销毁呢?哈哈,如果在C、C++或Java中,color确实会被销毁,但在JavaScript中,if语句中的变量声明会将变量添加到当前的执行环境中(在这里是全局环境)中。特别地,在for语句时要牢记这一差异,例如:

for(var i = 0;i< 10; i++){
doSomething(i);
}
alert(i);    //10

记住:在JavaScript中,由for语句创建的变量i即使在for循环执行结束之后,也依然会存在于循环外部的执行环境中。

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
event.srcElement+表格应用
Aug 29 Javascript
浅析JQuery获取和设置Select选项的常用方法总结
Jul 04 Javascript
剖析Node.js异步编程中的回调与代码设计模式
Feb 16 Javascript
老生常谈JavaScript数组的用法
Jun 10 Javascript
jQuery查找节点方法完整实例
Sep 13 Javascript
jquery,js简单实现类似Angular.js双向绑定
Jan 13 Javascript
微信小程序 安全包括(框架、功能模块、账户使用)详解
Jan 16 Javascript
JavaScript严格模式下关于this的几种指向详解
Jul 12 Javascript
全面介绍vue 全家桶和项目实例
Dec 27 Javascript
Vue 开发音乐播放器之歌手页右侧快速入口功能
Aug 08 Javascript
Async/Await替代Promise的6个理由
Jun 15 Javascript
vue-cli3项目配置eslint代码规范的完整步骤
Sep 10 Javascript
js实现(全选)多选按钮的方法【附实例】
Mar 30 #Javascript
用JS生成UUID的方法实例
Mar 30 #Javascript
如何通过js实现图片预览功能【附实例代码】
Mar 30 #Javascript
jquery $.trim()去除字符串空格的实现方法【附图例】
Mar 30 #Javascript
jquery实现简单的banner轮播效果【实例】
Mar 30 #Javascript
jquery实现一个简单的表单验证实例
Mar 30 #Javascript
js实现密码强度检测【附示例】
Mar 30 #Javascript
You might like
dedecms后台验证码总提示错误的解决方法
2007/03/21 PHP
php array_flip() 删除数组重复元素
2009/01/14 PHP
PHP+MySQL删除操作实例
2015/01/21 PHP
PHP获得数组交集与差集的方法
2015/06/10 PHP
复制本贴标题和地址的js代码
2008/07/01 Javascript
使用JavaScript构建JSON格式字符串实现步骤
2013/03/22 Javascript
Jquery动态更改一张位图的src与Attr的使用
2013/07/31 Javascript
JavaScript创建对象的写法
2013/08/29 Javascript
jQuery中trigger()方法用法实例
2015/01/19 Javascript
js创建jsonArray传输至后台及后台全面解析
2016/04/11 Javascript
JavaScript:Array类型全面解析
2016/05/19 Javascript
js实现页面a向页面b传参的方法
2016/05/29 Javascript
AngularJS基础 ng-readonly 指令简单示例
2016/08/02 Javascript
easyui combogrid实现本地模糊搜索过滤多列
2017/05/13 Javascript
nodejs中安装ghost出错的原因及解决方法
2017/10/23 NodeJs
微信小程序progress组件使用详解
2018/01/31 Javascript
layer设置maxWidth及maxHeight解决方案
2019/07/26 Javascript
[50:01]Ti4 冒泡赛第二天 NEWBEE vs Titan
2014/07/15 DOTA
python3使用tkinter实现ui界面简单实例
2014/01/10 Python
Python获取远程文件大小的函数代码分享
2014/05/13 Python
Python自动化运维和部署项目工具Fabric使用实例
2016/09/18 Python
目前最全的python的就业方向
2018/06/05 Python
python实现简单登陆系统
2018/10/18 Python
kali中python版本的切换方法
2019/07/11 Python
python使用HTMLTestRunner导出饼图分析报告的方法
2019/12/30 Python
pycharm实现在子类中添加一个父类没有的属性
2020/03/12 Python
香港通票:Hong Kong Pass
2019/02/26 全球购物
.net工程师笔试题
2012/06/09 面试题
什么是ESB?请介绍一下ESB?
2015/05/27 面试题
事业单位辞职信范文
2014/01/19 职场文书
《太阳》教学反思
2014/02/21 职场文书
留学顾问岗位职责
2014/04/14 职场文书
小学兴趣小组活动总结
2014/07/07 职场文书
2014年校务公开工作总结
2014/12/18 职场文书
宝葫芦的秘密观后感
2015/06/11 职场文书
药品销售员2015年终工作总结
2015/10/22 职场文书