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 相关文章推荐
让回调函数 showResponse 也带上参数的代码
Aug 13 Javascript
js中typeof的用法汇总
Dec 12 Javascript
seaJs的模块定义和模块加载浅析
Jun 06 Javascript
AngularJS的表单使用详解
Jun 17 Javascript
简单模拟node.js中require的加载机制
Oct 27 Javascript
js中apply和Math.max()函数的问题及区别介绍
Mar 27 Javascript
JS关于刷新页面的相关总结
May 09 Javascript
JS实现图片旋转动画效果封装与使用示例
Jul 09 Javascript
如何检查一个对象是否为空
Apr 11 Javascript
Windows下安装 node 的版本控制工具 nvm
Feb 06 Javascript
JS实现简单打字测试
Jun 24 Javascript
微信小程序实现购物车小功能
Dec 30 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
人工智能开始玩《星际争霸2》 你的操作跟得上吗?
2017/08/11 星际争霸
PHP 中dirname(_file_)讲解
2007/03/18 PHP
php中经典方法实现判断多维数组是否为空
2011/10/23 PHP
PHP实现的一致性Hash算法详解【分布式算法】
2018/03/31 PHP
PHP+mysql实现的三级联动菜单功能示例
2019/02/15 PHP
ext jquery 简单比较
2010/04/07 Javascript
JAVASCRIPT车架号识别/验证函数代码 汽车车架号验证程序
2012/01/08 Javascript
Javascript 面向对象(一)(共有方法,私有方法,特权方法)
2012/05/23 Javascript
Textbox控件注册回车事件及触发按钮提交事件具体实现
2013/03/04 Javascript
php析构函数的具体用法小结
2014/03/11 Javascript
Javascript调用函数方法的几种方式介绍
2015/03/20 Javascript
基于Jquery实现万圣节快乐特效
2015/11/01 Javascript
详解JavaScript对象和数组
2015/12/03 Javascript
Bootstrap实现响应式导航栏效果
2015/12/28 Javascript
详解Vue.js 2.0 如何使用axios
2017/04/21 Javascript
JavaScript简介_动力节点Java学院整理
2017/06/26 Javascript
JS实现非首屏图片延迟加载的示例
2018/01/06 Javascript
利用js实现前后台传送Json的示例代码
2018/03/29 Javascript
vue 1.0 结合animate.css定义动画效果
2018/07/11 Javascript
Angular异步变同步处理方法
2018/08/13 Javascript
NodeJS搭建HTTP服务器的实现步骤
2018/10/12 NodeJs
React 使用Hooks简化受控组件的状态绑定
2019/03/18 Javascript
Vue项目中使用better-scroll实现菜单映射功能方法
2019/09/11 Javascript
Vue SSR 即时编译技术的实现
2020/05/06 Javascript
js实现弹窗效果
2020/08/09 Javascript
[01:10:24]DOTA2-DPC中国联赛 正赛 VG vs Aster BO3 第一场 2月28日
2021/03/11 DOTA
使用Python操作MySQL的一些基本方法
2015/08/16 Python
浅谈numpy中linspace的用法 (等差数列创建函数)
2017/06/07 Python
python 读取txt中每行数据,并且保存到excel中的实例
2018/04/29 Python
基于Python List的赋值方法
2018/06/23 Python
详解Python odoo中嵌入html简单的分页功能
2019/05/29 Python
Python对称的二叉树多种思路实现方法
2020/02/28 Python
tensorflow从ckpt和从.pb文件读取变量的值方式
2020/05/26 Python
校本教研工作制度
2014/01/22 职场文书
楼面经理岗位职责范本
2014/02/18 职场文书
群众路线查摆问题整改措施
2014/10/10 职场文书