深入解析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 相关文章推荐
28个JS验证函数收集
Mar 02 Javascript
select标记美化--JS式插件、后期加载
Apr 01 Javascript
Js 导出table内容到Excel的简单实例
Nov 19 Javascript
解决extjs grid 不随窗口大小自适应的改变问题
Jan 26 Javascript
基于JQuery的$.ajax方法进行异步请求导致页面闪烁的解决办法
May 10 Javascript
简单的分页代码js实现
May 17 Javascript
利用jquery实现实时更新歌词的方法
Jan 06 Javascript
再谈Angular4 脏值检测(性能优化)
Apr 23 Javascript
vue二级菜单导航点击选中事件的方法
Sep 12 Javascript
微信小程序开发之map地图组件定位并手动修改位置偏差
Aug 17 Javascript
JavaScript This指向问题详解
Nov 25 Javascript
Vue项目利用axios请求接口下载excel
Nov 17 Vue.js
关于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堆排序(heapsort)练习
2013/11/13 PHP
ThinkPHP3.1新特性之对Ajax的支持更加完善
2014/06/19 PHP
php生成zip文件类实例
2015/04/07 PHP
php 问卷调查结果统计
2015/10/08 PHP
php 猴子摘桃的算法
2017/06/20 PHP
js判断浏览器的比较全的代码
2007/02/13 Javascript
几行代码轻松搞定jquery实现flash8类似的连接效果
2007/05/03 Javascript
动态加载脚本提升javascript性能
2014/02/24 Javascript
js实现横向百叶窗效果网页切换动画效果的方法
2015/03/02 Javascript
使用canvas实现仿新浪微博头像截取上传功能
2015/09/02 Javascript
javascript设计模式--策略模式之输入验证
2015/11/27 Javascript
理解JS事件循环
2016/01/07 Javascript
bootstrap fileinput 上传插件的基础使用
2017/02/17 Javascript
Javascript es7中比较实用的两个方法示例
2017/07/21 Javascript
详解vue-cli 接口代理配置
2017/12/13 Javascript
JS设计模式之状态模式概念与用法分析
2018/02/05 Javascript
iview同时验证多个表单问题总结
2018/09/29 Javascript
JS使用Dijkstra算法求解最短路径
2019/01/17 Javascript
微信小程序实现吸顶效果
2020/01/08 Javascript
Websocket 向指定用户发消息的方法
2020/01/09 Javascript
node.JS二进制操作模块buffer对象使用方法详解
2020/02/06 Javascript
Vuex的热更替如何实现
2020/06/05 Javascript
查找Vue中下标的操作(some和findindex)
2020/08/12 Javascript
Python map和reduce函数用法示例
2015/02/26 Python
python远程连接服务器MySQL数据库
2018/07/02 Python
使用Python Pandas处理亿级数据的方法
2019/06/24 Python
Python中格式化字符串的四种实现
2020/05/26 Python
Python爬虫设置ip代理过程解析
2020/07/20 Python
库存图片、照片、矢量图、视频和音乐:Shutterstock
2021/02/12 全球购物
Bloomingdale’s阿联酋:选购奢华时尚、美容及更多
2020/09/22 全球购物
常务副县长“三严三实”对照检查材料思想汇报
2014/10/05 职场文书
给老婆道歉的话
2015/01/20 职场文书
2015年社区环境卫生工作总结
2015/04/21 职场文书
格列夫游记读书笔记
2015/07/01 职场文书
导游词之秦皇岛燕塞湖
2020/01/03 职场文书
写好Python代码的几条重要技巧
2021/05/21 Python