Javascript变量的作用域和作用域链详解


Posted in Javascript onApril 02, 2015

工作这几年,js学的不是很好,正好周末有些闲时间,索性买本《js权威指南》,大名鼎鼎的犀牛书,好好的把js深入的看一看。买过这本书的第一印象就是贼厚,不过后面有一半部分都是参考手册。

一:作用域

说起变量第一个要说到的肯定就是作用域,正是因为不熟悉JS的作用域,往往就会把面向对象的作用域张冠李戴,毕竟有些东西总是习惯性的这样,但是并不是每次照搬都是可以的,那么下一个问题就来了,js到底是什么作用域,当然是函数作用域了,我们的浏览器就是一个被实例化的window对象,如果在window下定义一个name字段,那么name字段就具有window这个函数作用域,也就是在window下都是可以访问的,如果在window下定义一个function ctrip,然后里面再定义一个name,那么这个新定义的name只能在ctrip函数下通用,而老的name继续在window下通用,举个例子。

Javascript变量的作用域和作用域链详解

从图中可以看出两点:

1: 在window下定义了一个name,居然还可以在function下定义一个重名的name,这个在C#里面是不可想象的。

2:在JS下就可以做到眼瞎,它只认自己的作用域,所以就出现了第一个"second",你可能觉得这个没有什么稀奇的地方,这是因为可能你还没有真正理解什么是函数作用域,解析器在执行ctrip的时候,第一件事情就是寻找ctrip下的所有局部变量,然后再执行后续语句,既然是先寻找,那么var name="second"这条语句定义在ctrip中任何位置都是可以的,下面我们把语句调换过来。

Javascript变量的作用域和作用域链详解

可以看到在ctrip函数下,第一个console.log输出的是undefined,这个结果可以证实,确实做了第一件事情是收集到了name这个局部变量,可能有人说为什么没有变成”second“,那是因为初始化操作必须是逐语句执行,所以在ctrip函数中执行console.log(name)时,此时解析器只知道有一个未赋值的变量name,所以就console的时候就是undefined了。

二:作用域链

从上面的这个例子中我们也很清楚的知道了,在function中定义的变量只具有function范围内的作用域,同时我们也看到上面这个例子只是一层嵌套,window是个大的function,里面是一个ctrip的function,同样的道理也可以延伸到多层嵌套,比如三层,四层。。。。N层,这些层就形成了一个链式结构。

Javascript变量的作用域和作用域链详解

从图中可以看到,我在ctrip下再定义了一个plane函数,这样的话就有三层了,输出的结果也是我们希望看到的,每层的name只在自己的作用域范围

内生效,但是下面有一个问题来了,有一天我傻逼了,在定义plane的函数时,把 var name="third" 中的var忘记写了,那么这个时候,plane中的

name到底是什么值呢? 是first还是second呢?

var name="first";

function ctrip(){

  var name="second";

  function plane(){

     name="third";

     console.log(name);

  }

  plane();

  console.log(name);

}

ctrip();

console.log(name);

现在就是考验你是否真的懂了作用域链,仔细想想会发现,当代码执行到plane函数中的name=”third“时,发现plane函数中并没有name这个局部变量,恰好代码又在ctrip这个大函数中,所以解析器就会回溯到ctrip函数中寻找name,发现果然有name,这个时候就把ctrip的name修改成了”third“。

Javascript变量的作用域和作用域链详解

又有一天,我喝多了酒又傻逼了一回,在定义plane函数的时候,把name="third" 错写成了 nam="third"; 丢了一个e,你可以说是酒精的问题,

又不是我代码的问题。那么这个时候解析器该怎么处理呢?同样的道理,在回溯时,发现ctrip没有,再回溯到顶层的window下,发现还是没有,

这个时候解析器做了这样的处理,既然整个链中都没有,你又赋值了,我总不能给你报错,那多尴尬呀,就索性给你在window下隐式的定义一个

nam变量,这个时候nam其实就是全局变量了。我们可以在window顶层console一下nam看看。

Javascript变量的作用域和作用域链详解

好了,关于变量的东西也就这么多了,没什么稀奇的,理解了就没什么意思了。

Javascript 相关文章推荐
广告代码静态化js通用函数
May 09 Javascript
js调用flash的效果代码
Apr 26 Javascript
javascript学习笔记(十五) js间歇调用和超时调用
Jun 20 Javascript
仿新浪微博登陆邮箱提示效果的js代码
Aug 02 Javascript
JS代码判断IE6,IE7,IE8,IE9的函数代码
Aug 02 Javascript
用JavaScript计算在UTF-8下存储字符串占用字节数
Aug 08 Javascript
window.open()详解及浏览器兼容性问题示例探讨
May 29 Javascript
JavaScript检测鼠标移动方向的方法
May 22 Javascript
vue的全局提示框组件实例代码
Feb 26 Javascript
jQuery 筛选器简单操作示例
Oct 02 jQuery
关于element-ui表单中限制输入纯数字的解决方式
Sep 08 Javascript
JS页面动态绘图工具SVG,Canvas,VML介简介
Oct 16 Javascript
JavaScript中连接操作Oracle数据库实例
Apr 02 #Javascript
JavaScript中操作Mysql数据库实例
Apr 02 #Javascript
JavaScript使用ActiveXObject访问Access和SQL Server数据库
Apr 02 #Javascript
JavaScript实现重置表单(reset)的方法
Apr 02 #Javascript
javascript实现百度地图鼠标滑动事件显示、隐藏
Apr 02 #Javascript
jquery实现的省市区三级联动
Apr 02 #Javascript
JavaScript实现的链表数据结构实例
Apr 02 #Javascript
You might like
Discuz! Passport 通行证整合
2008/03/27 PHP
真正根据utf8编码的规律来进行截取字符串的函数(utf8版sub_str )
2012/10/24 PHP
thinkPHP引入类的方法详解
2016/12/08 PHP
告诉大家什么是JSON
2008/06/10 Javascript
javawscript 三级菜单的实现原理
2009/07/01 Javascript
jquery.validate使用攻略 第五步 正则验证
2010/07/01 Javascript
javascript预览上传图片发现的问题的解决方法
2010/11/25 Javascript
JQuery中$之选择器用法介绍
2011/04/05 Javascript
js鼠标滑轮滚动事件绑定的简单实例(兼容主流浏览器)
2014/01/14 Javascript
javascript作用域和闭包使用详解
2014/04/25 Javascript
node.js中的fs.ftruncate方法使用说明
2014/12/15 Javascript
JavaScript和HTML DOM的区别与联系及Javascript和DOM的关系
2015/11/15 Javascript
jQuery Dialog 取消右上角删除按钮事件
2016/09/07 Javascript
JavaScript实现经典排序算法之选择排序
2016/12/28 Javascript
一句jQuery代码实现返回顶部效果(简单实用)
2016/12/28 Javascript
angular和BootStrap3实现购物车功能
2017/01/25 Javascript
基于Bootstrap漂亮简洁的CSS3价格表(附源码下载)
2017/02/28 Javascript
Spring shiro + bootstrap + jquery.validate 实现登录、注册功能
2017/06/02 jQuery
vue-cli3.X快速创建项目的方法步骤
2019/11/14 Javascript
vue项目使用高德地图的定位及关键字搜索功能的实例代码(踩坑经验)
2020/03/07 Javascript
Ant Design的Table组件去除
2020/10/24 Javascript
[52:57]2014 DOTA2国际邀请赛中国区预选赛 LGD-CDEC VS HGT
2014/05/21 DOTA
Python实现输出某区间范围内全部素数的方法
2018/05/02 Python
打包python 加icon 去掉cmd黑窗口方法
2019/06/24 Python
python selenium登录豆瓣网过程解析
2019/08/10 Python
Python批量将图片灰度化的实现代码
2020/04/11 Python
keras 多gpu并行运行案例
2020/06/10 Python
屈臣氏官方旗舰店:亚洲享负盛名的保健及美妆零售商
2019/03/15 全球购物
初三新学期计划书
2014/05/03 职场文书
企业宣传标语
2014/06/09 职场文书
运动会加油稿20字
2014/11/15 职场文书
2014年团队工作总结
2014/11/24 职场文书
党员承诺书范文2015
2015/04/27 职场文书
员工工作表扬信
2015/05/05 职场文书
班委竞选稿范文
2015/11/21 职场文书
2016年社区“我们的节日·中秋节”活动总结
2016/04/05 职场文书