谈一谈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 相关文章推荐
Stop SQL Server
Jun 21 Javascript
div模拟选择框示例代码
Nov 03 Javascript
当前流行的JavaScript代码风格指南
Sep 10 Javascript
JavaScript基础重点(必看)
Jul 09 Javascript
jQuery实现的兼容性浮动层示例
Aug 02 Javascript
微信小程序-消息提示框实例
Nov 24 Javascript
微信小程序的日期选择器的实例详解
Sep 29 Javascript
Vue.js结合bootstrap前端实现分页和排序效果
Dec 29 Javascript
使用pm2部署node生产环境的方法步骤
Mar 09 Javascript
javascript实现蒙版与禁止页面滚动
Jan 11 Javascript
解决vue项目运行npm run serve报错的问题
Oct 26 Javascript
JS数组的常用方法整理
Mar 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中的一个中文字符串截取函数
2007/02/14 PHP
Drupal 添加模块出现莫名其妙的错误的解决方法(往往出现在模块较多时)
2011/04/18 PHP
PHP 如何获取二维数组中某个key的集合
2014/06/03 PHP
PHP实现通过正则表达式替换回调的内容标签
2015/06/15 PHP
php时间戳转换代码详解
2019/08/04 PHP
基于jquery的放大镜效果
2012/05/30 Javascript
js 定时器setTimeout无法调用局部变量的解决办法
2013/11/28 Javascript
LABjs、RequireJS、SeaJS的区别
2014/03/04 Javascript
js 日期比较相关天数代码
2014/04/02 Javascript
js和jquery设置disabled属性为true使按钮失效
2014/08/07 Javascript
node.js中的path.resolve方法使用说明
2014/12/08 Javascript
jQuery中outerWidth()方法用法实例
2015/01/19 Javascript
jquery实现滑屏大图定时收缩为小banner图片的广告代码
2015/09/02 Javascript
js中实现字符串和数组的相互转化详解
2016/01/24 Javascript
jquery判断对象是否为空并遍历对象的简单实例
2016/07/26 Javascript
JS动画定时器知识总结
2018/03/23 Javascript
Vue 监听列表item渲染事件方法
2018/09/06 Javascript
三种Webpack打包方式(小结)
2018/09/19 Javascript
Javascript之高级数组API的使用实例
2019/03/08 Javascript
JS实现悬浮球只在一侧滑动并且是横屏状态下
2020/08/19 Javascript
[56:29]Secret vs Optic 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
在Python中调用ggplot的三种方法
2015/04/08 Python
Python for循环中的陷阱详解
2018/07/13 Python
Python PyCharm如何进行断点调试
2019/07/05 Python
virtualenv介绍及简明教程
2020/06/23 Python
Python使用requests模块爬取百度翻译
2020/08/25 Python
Python爬取股票信息,并可视化数据的示例
2020/09/26 Python
python安装及变量名介绍详解
2020/12/12 Python
html5+css3之CSS中的布局与Header的实现
2014/11/21 HTML / CSS
美国正版电视节目和电影在线观看:Hulu
2018/05/24 全球购物
某公司Java工程师面试题笔试题
2016/03/27 面试题
协议书格式
2014/04/23 职场文书
人力资源管理专业应届生求职信
2014/04/24 职场文书
工伤私了协议书范本
2014/11/24 职场文书
关于清明节的演讲稿2015
2015/03/18 职场文书
Mysql将字符串按照指定字符分割的正确方法
2022/05/30 MySQL