JavaScript的变量作用域深入理解


Posted in Javascript onOctober 25, 2009

在学习JavaScript的变量作用域之前,我们应当明确几点:
a、JavaScript的变量作用域是基于其特有的作用域链的。
b、JavaScript没有块级作用域。
c、函数中声明的变量在整个函数中都有定义。

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

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

上面得代码说明了,变量x在整个rain函数体内都可以使用,并可以重新赋值。由于这条规则,会产生“匪夷所思”的结果,观察下面的代码。
这是由于在函数rain内局部变量x在整个函数体内都有定义( var x= 'rain-man',进行了声明),所以在整个rain函数体内隐藏了同名的全局变量x。这里之所以会弹出'undefined'是因为,第一个执行alert(x)时,局部变量x仍未被初始化。
<script type="text/javascript" language="javascript"> 
var x = 1; 
function rain(){ 
alert( x ); //弹出 'undefined',而不是1 
var x = 'rain-man'; 
alert( x ); //弹出 'rain-man' 
} 
rain() 
</script>

所以上面的rain函数等同于下面的函数。
function rain(){ 
var x; 
alert( x ); 
x = 'rain-man'; 
alert( x ); 
}

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

这也是JavaScript新手常见的错误,无意之中留下的许多全局变量。
6、全局变量都是window对象的属性
<script type="text/javascript" language="javascript"> 
var x = 100 ; 
alert( window.x );//弹出100 
alert(x); 
</script>

等同于下面的代码
<script type="text/javascript" language="javascript"> 
window.x = 100; 
alert( window.x ); 
alert(x) 
</script>
Javascript 相关文章推荐
JavaScript DOM 学习第五章 表单简介
Feb 19 Javascript
使用jquery中height()方法获取各种高度大全
Apr 02 Javascript
JavaScript获取客户端IP的方法(新方法)
Mar 11 Javascript
JavaScript中的操作符类型转换示例总结
May 30 Javascript
js实现交通灯效果
Jan 13 Javascript
使用AngularJS对表单提交内容进行验证的操作方法
Jul 12 Javascript
angular1.x ui-route传参的三种写法小结
Aug 31 Javascript
vue 基于element-ui 分页组件封装的实例代码
Dec 10 Javascript
JQuery判断radio单选框是否选中并获取值的方法
Jan 17 jQuery
Vue实现商品详情页的评价列表功能
Sep 04 Javascript
VUE注册全局组件和局部组件过程解析
Oct 10 Javascript
vue组件暴露和.js文件暴露接口操作
Aug 11 Javascript
理解JavaScript变量作用域更轻松
Oct 25 #Javascript
理解 JavaScript 预解析
Oct 25 #Javascript
WEB页子窗口(showModalDialog和showModelessDialog)使用说明
Oct 25 #Javascript
JavaScript弹簧振子超简洁版 完全符合能量守恒,胡克定理
Oct 25 #Javascript
javascript window对象属性整理
Oct 24 #Javascript
Javascript 模式实例 观察者模式
Oct 24 #Javascript
Jquery 弹出层插件实现代码
Oct 24 #Javascript
You might like
php引用地址改变变量值的问题
2012/03/23 PHP
php预定义变量使用帮助(带实例)
2013/10/30 PHP
CI(CodeIgniter)框架介绍
2014/06/09 PHP
PHP实现在线阅读PDF文件的方法
2015/06/17 PHP
JavaScript 申明函数的三种方法 每个函数就是一个对象(一)
2009/12/04 Javascript
javascript面向对象编程(一) 实例代码
2010/06/25 Javascript
nodejs的require模块(文件模块/核心模块)及路径介绍
2013/01/14 NodeJs
Javascript 浮点运算的问题分析与解决方法
2013/08/27 Javascript
JQuery选择器、过滤器大整理
2015/05/26 Javascript
jquery可定制的在线UEditor编辑器
2015/11/17 Javascript
JS实现单击输入框弹出选择框效果完整实例
2015/12/14 Javascript
Node.js + Redis Sorted Set实现任务队列
2016/09/19 Javascript
Bootstrap实现的经典栅格布局效果实例【附demo源码】
2017/03/30 Javascript
关于vue v-for 循环问题(一行显示四个,每一行的最右边那个计算属性)
2018/09/04 Javascript
JS匿名函数内部this指向问题详析
2019/05/10 Javascript
Vue移动端右滑屏幕返回上一页附源码下载
2019/06/26 Javascript
Vue项目环境搭建详细总结
2019/09/26 Javascript
基于Vue CSR的微前端实现方案实践
2020/05/27 Javascript
python查找第k小元素代码分享
2013/12/18 Python
python网络编程之UDP通信实例(含服务器端、客户端、UDP广播例子)
2014/04/25 Python
Python决策树和随机森林算法实例详解
2018/01/30 Python
Linux-ubuntu16.04 Python3.5配置OpenCV3.2的方法
2018/04/02 Python
详解如何将python3.6软件的py文件打包成exe程序
2018/10/09 Python
Python语法垃圾回收机制原理解析
2020/03/25 Python
CSS3动画之流彩文字效果+图片模糊效果+边框伸展效果实现代码合集
2017/08/18 HTML / CSS
纯css3实现照片墙效果
2014/12/26 HTML / CSS
three.js模拟实现太阳系行星体系功能
2019/09/03 HTML / CSS
家长会学生家长演讲稿
2013/12/29 职场文书
趣味体育活动方案
2014/02/08 职场文书
投资协议书范本
2014/04/21 职场文书
班级学习雷锋活动总结
2014/07/04 职场文书
新闻发布会活动策划方案
2014/09/15 职场文书
2015年度优秀员工获奖感言
2015/07/31 职场文书
导游词之扬州大明寺
2019/10/09 职场文书
Memcached介绍及php-memcache扩展安装
2021/04/01 PHP
MySQL 数据恢复的多种方法汇总
2021/06/21 MySQL