谈一谈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 相关文章推荐
JavaScript 保存数组到Cookie的代码
Apr 14 Javascript
关于文本框的一些限制控制总结~~
Apr 15 Javascript
js切换光标示例代码
Oct 10 Javascript
只需一行代码,轻松实现一个在线编辑器
Nov 12 Javascript
jquery使用ajax实现微信自动回复插件
Apr 28 Javascript
简述JavaScript对传统文档对象模型的支持
Jun 16 Javascript
jQuery遍历DOM的父级元素、子级元素和同级元素的方法总结
Jul 07 Javascript
ES6新特性之变量和字符串用法示例
Apr 01 Javascript
微信分享调用jssdk实例
Jun 08 Javascript
微信小程序动态添加view组件的实例代码
May 23 Javascript
如何在postman测试用例中实现断言过程解析
Jul 09 Javascript
vue中可编辑树状表格的实现代码
Oct 31 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
php 伪造本地文件包含漏洞的代码
2011/11/03 PHP
Yii2 GridView实现列表页直接修改数据的方法
2016/05/16 PHP
php实用代码片段整理
2016/11/12 PHP
PHP正则匹配反斜杠'\'和美元'$'的方法
2017/02/08 PHP
Laravel框架模板继承操作示例
2018/06/11 PHP
基于node.js的快速开发透明代理
2010/12/25 Javascript
jquery事件机制扩展插件 jquery鼠标右键事件
2011/12/21 Javascript
JavaScript设计模式之观察者模式(发布者-订阅者模式)
2014/09/24 Javascript
JavaScript学习小结(一)——JavaScript入门基础
2015/09/02 Javascript
javascript实现自动填写表单实例简析
2015/12/02 Javascript
Bootstrap按钮下拉菜单组件详解
2016/05/10 Javascript
使用jquery提交form表单并自定义action的实现代码
2016/05/25 Javascript
javascript 数组的正态分布排序的问题
2016/07/31 Javascript
基于JS实现发送短信验证码后的倒计时功能(无视页面刷新,页面关闭不进行倒计时功能)
2016/09/02 Javascript
jQuery实现三级联动效果
2017/03/02 Javascript
JavaScript中闭包的详解
2017/04/01 Javascript
使用Vue.js和Flask来构建一个单页的App的示例
2018/03/21 Javascript
微信小程序错误this.setData报错及解决过程
2019/09/18 Javascript
vue-element-admin 菜单标签失效的解决方式
2019/11/12 Javascript
vue组件入门知识全梳理
2020/09/21 Javascript
JavaScript十大取整方法实例教程
2020/12/03 Javascript
[01:54]TI4西雅图DOTA2选手欢迎晚宴 现场报道
2014/07/08 DOTA
将Django使用的数据库从MySQL迁移到PostgreSQL的教程
2015/04/11 Python
Python模拟简单电梯调度算法示例
2018/08/20 Python
Tensorflow使用支持向量机拟合线性回归
2018/09/07 Python
Python Numpy库安装与基本操作示例
2019/01/08 Python
Python设计模式之适配器模式原理与用法详解
2019/01/15 Python
Python3爬虫里关于代理的设置总结
2020/07/30 Python
python模拟点击在ios中实现的实例讲解
2020/11/26 Python
什么是Remote Module
2016/06/10 面试题
财务方面个人工作的自我评价
2013/12/28 职场文书
大学生就业求职信
2014/06/12 职场文书
2014年学校体育工作总结
2014/12/08 职场文书
2015年端午节活动策划书
2015/05/05 职场文书
vue项目配置sass及引入外部scss文件
2022/04/14 Vue.js
关于windows server 2012 DC 环境 重启后蓝屏代码:0xc00002e2的问题
2022/05/25 Servers