深入解析JavaScript中的变量作用域


Posted in Javascript onDecember 06, 2013

在学习JavaScript的变量作用域之前,我们应当明确几点:

•JavaScript的变量作用域是基于其特有的作用域链的。

•JavaScript没有块级作用域。

•函数中声明的变量在整个函数中都有定义。

1、JavaScript的作用域链
首先看下下面这段代码:

<script type="text/javascript"> var rain = 1; function rainman(){ var man = 2; function inner(){ var innerVar = 4; alert(rain); } inner(); //调用inner函数 } rainman(); //调用rainman函数</script>

观察alert(rain);这句代码。JavaScript首先在inner函数中查找是否定义了变量rain,如果定义了则使用inner函数中的rain变量;如果inner函数中没有定义rain变量,JavaScript则会继续在rainman函数中查找是否定义了rain变量,在这段代码中rainman函数体内没有定义rain变量,则JavaScript引擎会继续向上(全局对象)查找是否定义了rain;在全局对象中我们定义了rain = 1,因此最终结果会弹出'1'。

作用域链:JavaScript需要查询一个变量x时,首先会查找作用域链的第一个对象,如果以第一个对象没有定义x变量,JavaScript会继续查找有没有定义x变量,如果第二个对象没有定义则会继续查找,以此类推。

上面的代码涉及到了三个作用域链对象,依次是:inner、rainman、window。

2、函数体内部,局部变量的优先级比同名的全局变量高。

<script type="text/javascript"> var rain = 1; //定义全局变量 rain function check(){ var rain = 100; //定义局部变量rain alert( rain ); //这里会弹出 100 } check(); alert( rain ); //这里会弹出1</script>

3、JavaScript没有块级作用域。

这一点也是JavaScript相比其它语言较灵活的部分。

仔细观察下面的代码,你会发现变量i、j、k作用域是相同的,他们在整个rain函数体内都是全局的。

<script type="text/javascript"> function rainman(){ // rainman函数体内存在三个局部变量 i j k var i = 0; if ( 1 ) { var j = 0; for(var k = 0; k < 3; k++) { alert( k ); //分别弹出 0 1 2 } alert( k ); //弹出3 } alert( j ); //弹出0 }</script>

4、函数中声明的变量在整个函数中都有定义。

首先观察这段代码:

<script type="text/javascript"> function rain(){ var x = 1; function man(){ x = 100; } man(); //调用man alert( x ); //这里会弹出 100 } rain(); //调用rain</script>

上面得代码说明了,变量x在整个rain函数体内都可以使用,并可以重新赋值。由于这条规则,会产生“匪夷所思”的结果,观察下面的代码。
<script type="text/javascript"> var x = 1; function rain(){ alert( x ); //弹出 'undefined',而不是1 var x = 'rain-man'; alert( x ); //弹出 'rain-man' } rain();</script>

是由于在函数rain内局部变量x在整个函数体内都有定义( var x= 'rain-man',进行了声明),所以在整个rain函数体内隐藏了同名的全局变量x。这里之所以会弹出'undefined'是因为,第一个执行alert(x)时,局部变量x仍未被初始化。

所以上面的rain函数等同于下面的函数:

function rain(){ var x; alert( x ); x = 'rain-man'; alert( x );}

5、未使用var关键字定义的变量都是全局变量。
<script type="text/javascript"> function rain(){ x = 100; //声明了全局变量x并进行赋值 } rain(); alert( x ); //会弹出100 </script>

这也是JavaScript新手常见的错误,无意之中留下的许多全局变量。

6、全局变量都是window对象的属性

<script type="text/javascript"> var x = 100 ; alert( window.x );//弹出100 alert(x);</script>

等同于下面的代码
<script type="text/javascript"> window.x = 100; alert( window.x ); alert(x)</script>
Javascript 相关文章推荐
JavaScript高级程序设计(第3版)学习笔记7 js函数(上)
Oct 11 Javascript
提高jQuery性能的十个诀窍
Nov 14 Javascript
jQuery中获取checkbox选中项等操作及注意事项
Nov 24 Javascript
JavaScript的String字符串对象常用操作总结
May 26 Javascript
js事件驱动机制 浏览器兼容处理方法
Jul 23 Javascript
Javascript typeof与instanceof的区别
Oct 18 Javascript
jquery动态赋值id与动态取id方法示例
Aug 21 jQuery
angular.js实现购物车功能
Oct 23 Javascript
vue.js中引入vuex储存接口数据及调用的详细流程
Dec 14 Javascript
webpack热模块替换(HMR)/热更新的方法
Apr 05 Javascript
微信小程序基于canvas渐变实现的彩虹效果示例
May 03 Javascript
vue本地打开build后生成的dist文件夹index.html问题
Sep 04 Javascript
关于Javascript作用域链的八点总结
Dec 06 #Javascript
Javascript变量作用域详解
Dec 06 #Javascript
JavaScript1.6数组新特性介绍以及JQuery的几个工具方法
Dec 06 #Javascript
Javascript中克隆一个数组的实现代码
Dec 06 #Javascript
浅析JavaScript中的同名标识符优先级
Dec 06 #Javascript
如何判断元素是否为HTMLElement元素
Dec 06 #Javascript
随鼠标上下滚动的jquery代码
Dec 05 #Javascript
You might like
深入解读php中关于抽象(abstract)类和抽象方法的问题分析
2014/01/03 PHP
php使用递归计算文件夹大小
2014/12/24 PHP
Laravel框架控制器,视图及模型操作图文详解
2019/12/04 PHP
php使用gearman进行任务分发操作实例详解
2020/02/26 PHP
javascritp实现input输入框相关限制用法
2007/06/29 Javascript
js 获取坐标 通过JS得到当前焦点(鼠标)的坐标属性
2013/01/04 Javascript
用JQuery实现全选与取消的两种简单方法
2014/02/22 Javascript
JS使用for循环遍历Table的所有单元格内容
2014/08/21 Javascript
jQuery实现左右切换焦点图
2015/04/03 Javascript
详解Document.Cookie
2015/12/25 Javascript
React.js入门学习第一篇
2016/03/30 Javascript
基于jQuery实现多标签页切换的效果(web前端开发)
2016/07/24 Javascript
js仿手机页面文件下拉刷新效果
2016/10/14 Javascript
Bootstrap基本样式学习笔记之表格(2)
2016/12/07 Javascript
理解javascript中的闭包
2017/01/11 Javascript
JS百度地图搜索悬浮窗功能
2017/01/12 Javascript
ES6新特性一: let和const命令详解
2017/04/20 Javascript
浅谈vue-router2路由参数注意的问题
2017/11/08 Javascript
jQuery模拟12306城市选择框功能简单实现方法示例
2018/08/13 jQuery
详解Vue3 Composition API中的提取和重用逻辑
2020/04/29 Javascript
vue实现路由懒加载的3种方法示例
2020/09/01 Javascript
[05:36]DOTA2 2015国际邀请赛中国区预选赛第四日TOP10
2015/05/29 DOTA
[01:02:34]TFT vs VGJ.T Supermajor 败者组 BO3 第二场 6.5
2018/06/06 DOTA
[57:47]Fnatic vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python和JavaScript间代码转换的4个工具
2016/02/22 Python
用Python登录好友QQ空间点赞的示例代码
2017/11/04 Python
python random从集合中随机选择元素的方法
2019/01/23 Python
Python简易计算器制作方法代码详解
2019/10/31 Python
Python读写操作csv和excle文件代码实例
2020/03/16 Python
python使用建议技巧分享(三)
2020/08/18 Python
详解HTML5常用的语义化标签
2019/09/27 HTML / CSS
Clarks英国官方网站:全球领军鞋履品牌
2016/11/26 全球购物
德国最大的婴儿用品网上商店:Kidsroom.de(支持中文)
2020/09/02 全球购物
Linux管理员面试经常问道的相关命令
2014/12/12 面试题
婚礼新郎父母答谢词
2014/01/16 职场文书
新学期家长寄语2016
2015/12/03 职场文书