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 相关文章推荐
JavaScript Cookie的读取和写入函数
Dec 08 Javascript
Jquery AutoComplete自动完成 的使用方法实例
Mar 19 Javascript
JQuery 弹出框定位实现方法
Dec 02 Javascript
js函数获取html中className所在的内容并去除标签
Sep 08 Javascript
js插件设置innerHTML时在IE8下提示“未知运行时错误”解决方法
Apr 25 Javascript
jQuery实现下拉框左右移动(全部移动,已选移动)
Apr 15 Javascript
vue-cli单页应用改成多页应用配置详解
Jul 14 Javascript
在vue项目中使用element-ui的Upload上传组件的示例
Feb 08 Javascript
vue如何将v-for中的表格导出来
May 07 Javascript
angularJS实现不同视图同步刷新详解
Oct 09 Javascript
微信小程序基于高德地图查找位置并显示文字
Oct 30 Javascript
JavaScript隐式类型转换代码实例
May 29 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
php生成验证码,缩略图及水印图的类分享
2016/04/07 PHP
PHP实现在windows下配置sendmail并通过mail()函数发送邮件的方法
2017/06/20 PHP
PHP代码重构方法漫谈
2018/04/17 PHP
数组Array进行原型prototype扩展后带来的for in遍历问题
2010/02/07 Javascript
js parentElement和offsetParent之间的区别
2010/03/23 Javascript
js 连接数据库如何操作数据库中的数据
2012/11/23 Javascript
jsPDF导出pdf示例
2014/05/02 Javascript
深入理解javascript中的立即执行函数(function(){…})()
2014/06/12 Javascript
JS数组排序技巧汇总(冒泡、sort、快速、希尔等排序)
2015/11/24 Javascript
JQuery中解决重复动画的方法
2016/10/17 Javascript
浅谈在vue中用webpack打包之后运行文件的问题以及相关配置方法
2018/02/21 Javascript
jQuery的Ajax接收java返回数据方法
2018/08/11 jQuery
JS实现随机生成10个手机号的方法示例
2018/12/07 Javascript
vue v-for 使用问题整理小结
2019/08/04 Javascript
Vue动态加载图片在跨域时无法显示的问题及解决方法
2020/03/10 Javascript
[02:45]DOTA2英雄敌法师基础教程
2013/11/25 DOTA
[53:10]Secret vs Pain 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
python中datetime模块中strftime/strptime函数的使用
2018/07/03 Python
解决nohup执行python程序log文件写入不及时的问题
2019/01/14 Python
Python一个简单的通信程序(客户端 服务器)
2019/03/06 Python
python画图——实现在图上标注上具体数值的方法
2019/07/08 Python
感知器基础原理及python实现过程详解
2019/09/30 Python
Python使用扩展库pywin32实现批量文档打印实例
2020/04/09 Python
python实现马丁策略回测3000只股票的实例代码
2021/01/22 Python
css3教程之倾斜页面
2014/01/27 HTML / CSS
css3设置box-pack和box-align让div里面的元素垂直居中
2014/09/01 HTML / CSS
AMAVII眼镜官网:时尚和设计师太阳镜
2019/05/05 全球购物
澳大利亚儿童精品仓库:Goo & Co.
2019/06/20 全球购物
荷兰天然和有机产品网上商城:BigGreenSmile.nl
2020/07/26 全球购物
Yahoo-PHP面试题2
2014/12/06 面试题
四风问题个人剖析材料
2014/10/07 职场文书
民事代理词范文
2015/05/25 职场文书
新闻稿件写作范文
2015/07/18 职场文书
运动会广播稿20字
2015/08/19 职场文书
《草虫的村落》教学反思
2016/02/20 职场文书
爱心捐款倡议书:点燃希望,传递温暖
2019/11/04 职场文书