谈一谈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 相关文章推荐
vs2003 js文件编码问题的解决方法
Mar 20 Javascript
JS命名空间的另一种实现
Aug 09 Javascript
使用jQuery mobile库检测url绝对地址和相对地址的方法
Dec 04 Javascript
js实现文字闪烁特效的方法
Dec 17 Javascript
javascript中加var和不加var的区别 你真的懂吗
Jan 06 Javascript
Node.js与Sails redis组件的使用教程
Feb 14 Javascript
vue和react等项目中更简单的实现展开收起更多等效果示例
Feb 22 Javascript
vue使用$emit时,父组件无法监听到子组件的事件实例
Feb 26 Javascript
浅谈vue-cli 3.0.x 初体验
Apr 11 Javascript
JS 数组基本用法入门示例解析
Jan 16 Javascript
JavaScript用document.write()输出换行的示例代码
Nov 26 Javascript
vue打包时去掉所有的console.log
Apr 10 Vue.js
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
一些花式咖啡的配方
2021/03/03 冲泡冲煮
PHP+Apache+Mysql环境搭建教程
2016/08/01 PHP
PHP 500报错的快速解决方法
2016/12/14 PHP
php mysql_real_escape_string addslashes及mysql绑定参数防SQL注入攻击
2016/12/23 PHP
thinkphp5 加载静态资源路径与常量的方法
2017/12/24 PHP
JavaScript 页面编码与浏览器类型判断代码
2010/06/03 Javascript
JS性能优化笔记搜索整理
2013/08/21 Javascript
Nodejs Post请求报socket hang up错误的解决办法
2014/09/25 NodeJs
jQuery mobile类库使用时加载导航历史的方法简介
2015/12/04 Javascript
jQuery Html控件基本操作(日常收集整理)
2016/03/11 Javascript
使用JS实现图片展示瀑布流效果的实例代码
2016/09/12 Javascript
详解js中Number()、parseInt()和parseFloat()的区别
2016/12/20 Javascript
Vue2.0 UI框架ElementUI使用方法详解
2017/04/14 Javascript
详解Angular路由之路由守卫
2018/05/10 Javascript
详解Vue-cli中的静态资源管理(src/assets和static/的区别)
2018/06/19 Javascript
详解vue中使用vue-quill-editor富文本小结(图片上传)
2019/04/24 Javascript
详解微信小程序实现跑马灯效果(附完整代码)
2019/04/29 Javascript
vue路由分文件拆分管理详解
2020/08/13 Javascript
vue二选一tab栏切换新做法实现
2021/01/19 Vue.js
[01:09:13]DOTA2-DPC中国联赛 正赛 CDEC vs XG BO3 第三场 1月19日
2021/03/11 DOTA
Python实现删除当前目录下除当前脚本以外的文件和文件夹实例
2015/07/27 Python
python字符类型的一些方法小结
2016/05/16 Python
在python中以相同顺序shuffle两个list的方法
2018/12/13 Python
使用python serial 获取所有的串口名称的实例
2019/07/02 Python
如何在 Django 模板中输出 &quot;{{&quot;
2020/01/24 Python
Python如何实现在字符串里嵌入双引号或者单引号
2020/03/02 Python
tensorflow使用freeze_graph.py将ckpt转为pb文件的方法
2020/04/22 Python
Python调用shell命令常用方法(4种)
2020/05/11 Python
CSS3感应鼠标的背景闪烁和图片缩放动画效果
2014/05/14 HTML / CSS
世界上最受欢迎的钓鱼诱饵:Rapala
2019/05/02 全球购物
Skyscanner新西兰:全球领先的旅游搜索网站
2019/08/26 全球购物
土木工程应届生自荐信
2013/09/24 职场文书
升旗仪式演讲稿
2014/05/08 职场文书
学习党的群众路线剖析材料
2014/10/09 职场文书
端午节将至,用Python爬取粽子数据并可视化,看看网友喜欢哪种粽子吧!
2021/06/11 Python
8个JS的reduce使用实例和reduce操作方式
2021/10/05 Javascript