深入解析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 解析后的xml对象的读取方法细解
Jul 25 Javascript
javascript的回调函数应用示例
Feb 20 Javascript
浅谈jQuery中Ajax事件beforesend及各参数含义
Dec 03 Javascript
angular双向绑定模拟探索
Dec 26 Javascript
利用js的闭包原理做对象封装及调用方法
Apr 07 Javascript
Node.js 使用命令行工具检查更新
Jun 08 Javascript
JS实现静态页面搜索并高亮显示功能完整示例
Sep 19 Javascript
详解Angular2学习笔记之Html属性绑定
Jan 03 Javascript
对angularjs框架下controller间的传值方法详解
Oct 08 Javascript
vue中node_modules中第三方模块的修改使用详解
May 31 Javascript
5个你不知道的JavaScript字符串处理库(小结)
Jun 01 Javascript
在vue中实现禁止屏幕滚动,禁止屏幕滑动
Jul 22 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代码简化
2010/02/08 PHP
PHP取整数函数常用的四种方法小结
2012/07/05 PHP
php定义数组和使用示例(php数组的定义方法)
2014/03/29 PHP
destoon利用Rewrite规则设置网站安全
2014/06/21 PHP
php封装的单文件(图片)上传类完整实例
2016/10/18 PHP
用JQuery 实现的自定义对话框
2007/03/24 Javascript
开发跨浏览器javascript常见注意事项
2009/01/01 Javascript
xcode中获取js文件的路径方法(推荐)
2016/11/05 Javascript
BootStrap树状图显示功能
2016/11/24 Javascript
微信小程序去哪里找 小程序到底如何使用(附小程序名单)
2017/01/09 Javascript
令按钮悬浮在(手机)页面底部的实现方法
2017/05/02 Javascript
简单实现js鼠标跟随效果
2020/08/02 Javascript
基于JS递归函数细化认识及实用实例(推荐)
2017/08/07 Javascript
jQuery 开发之EasyUI 添加数据的实例
2017/09/26 jQuery
JS随机排序数组实现方法分析
2017/10/11 Javascript
vue-cli3.0 特性解读
2018/04/22 Javascript
深入理解Promise.all
2018/08/08 Javascript
JS+HTML5 canvas绘制验证码示例
2018/12/05 Javascript
vue组件创建的三种方式小结
2020/02/03 Javascript
python学习之第三方包安装方法(两种方法)
2015/07/30 Python
Python 装饰器深入理解
2017/03/16 Python
python正则表达式re之compile函数解析
2017/10/25 Python
Pandas探索之高性能函数eval和query解析
2017/10/28 Python
python实现在一个画布上画多个子图
2020/01/19 Python
Python如何批量获取文件夹的大小并保存
2020/03/31 Python
python多进程下的生产者和消费者模型
2020/05/07 Python
python3.6.8 + pycharm + PyQt5 环境搭建的图文教程
2020/06/11 Python
基于Django集成CAS实现流程详解
2020/11/28 Python
详解pandas中利用DataFrame对象的.loc[]、.iloc[]方法抽取数据
2020/12/13 Python
时尚设计师手表:The Watch Cabin
2018/10/06 全球购物
Carolina Lemke Berlin澳大利亚官网:时尚太阳镜品牌
2019/09/17 全球购物
门前三包责任书
2014/04/15 职场文书
2015年度电厂个人工作总结
2015/05/13 职场文书
phpQuery解析HTML乱码问题(补充官网未列出的乱码解决方案)
2021/04/01 PHP
OpenCV-Python实现图像平滑处理操作
2021/06/08 Python
Python os和os.path模块详情
2022/04/02 Python