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 相关文章推荐
utf-8编码引起js输出中文乱码的解决办法
Jun 23 Javascript
js css后面所带参数含义介绍
Aug 18 Javascript
javascript页面加载完执行事件代码
Feb 11 Javascript
使用jQuery.wechat构建微信WEB应用
Oct 09 Javascript
jQuery使用CSS()方法给指定元素同时设置多个样式
Mar 26 Javascript
基于javascript实现九宫格大转盘效果
May 28 Javascript
JS实现仿UC浏览器前进后退效果的实例代码
Jul 17 Javascript
微信小程序实现星星评价效果
Nov 02 Javascript
Vue 后台管理类项目兼容IE9+的方法示例
Feb 20 Javascript
Angular实现svg和png图片下载实现
May 05 Javascript
layUI实现三级导航菜单效果
Jul 26 Javascript
vue 函数调用加括号与不加括号的区别
Oct 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正则
2006/07/07 PHP
Windows下的PHP5.0安装配制详解
2006/09/05 PHP
一步一步学习PHP(4) php 函数 补充2
2010/02/15 PHP
smarty 缓存控制前的页面静态化原理
2013/03/15 PHP
javascript动画效果类封装代码
2007/08/28 Javascript
JavaScript实现网页截图功能
2014/10/16 Javascript
jQuery的css() 方法使用指南
2015/05/03 Javascript
js判断文件格式及大小的简单实例(必看)
2016/10/11 Javascript
MUI 实现侧滑菜单及其主体部分上下滑动的方法
2018/01/25 Javascript
微信小程序之swiper轮播图中的图片自适应高度的方法
2018/04/23 Javascript
解决vue 引入子组件报错的问题
2018/09/06 Javascript
node中的cookie的具体使用
2018/09/13 Javascript
微信小程序实现底部导航
2018/11/05 Javascript
vue单页面在微信下只能分享落地页的解决方案
2019/04/15 Javascript
vue瀑布流组件实现上拉加载更多
2020/03/10 Javascript
jQuery实现鼠标放置名字上显示详细内容气泡提示框效果的方法分析
2020/04/04 jQuery
python实现批量下载新浪博客的方法
2015/06/15 Python
python从入门到精通(DAY 1)
2015/12/20 Python
Ubuntu16.04/树莓派Python3+opencv配置教程(分享)
2018/04/02 Python
对pandas中两种数据类型Series和DataFrame的区别详解
2018/11/12 Python
Python读取excel指定列生成指定sql脚本的方法
2018/11/28 Python
在Python中调用Ping命令,批量IP的方法
2019/01/26 Python
python实现中文文本分句的例子
2019/07/15 Python
基于python实现学生信息管理系统
2019/11/22 Python
Python使用docx模块实现刷题功能代码
2020/02/13 Python
Python脚本实现监听服务器的思路代码详解
2020/05/28 Python
css3 box-shadow阴影(外阴影与外发光)图示讲解
2017/08/11 HTML / CSS
CSS3 border-radius圆角的实现方法及用法详解
2020/09/14 HTML / CSS
HTML5 移动页面自适应手机屏幕四类方法总结
2017/08/17 HTML / CSS
前台接待岗位职责
2013/12/03 职场文书
毕业自我鉴定总结
2014/03/24 职场文书
《音乐之都维也纳》教学反思
2014/04/16 职场文书
2014年药店工作总结
2014/11/20 职场文书
骨干教师事迹材料
2014/12/17 职场文书
个人求职信格式范文
2015/03/20 职场文书
2015军训通讯稿大全
2015/07/18 职场文书