JavaScript中的变量作用域介绍


Posted in Javascript onDecember 31, 2014

对于变量的作用域(scope),C、Java等语言采取的是“block scope”的方式。与之不同,JavaScript所采取的是“function scope”的方式 — 变量的作用域仅由所处的function决定,与if、for等逻辑块无关。比如,以下这个例子展示了JavaScript中与C、Java等语言不一样的行为:

function(){

  var s = 42;//s is visible throughout function

  if (s > 3) {

    var x = "test";//x is visible throughout function

    for(var i=0; i<10; i++){

      console.log(i);

    }

    console.log(i);//i is visible throughout function

  }

  console.log(i);

  console.log(x);

}

在C、Java等“block scope”的语言中,if语句、for语句等逻辑块结束后,在这些逻辑块内部定义的变量将会被销毁。JavaScript与之不同,只要一个变量定义在某function内,那么整个function内的所有代码均可访问到该变量,即使这些代码在变量定义之前:

function(){

  console.log(a);//undefined

  var a = "test";

  console.log(a);//test

}

在上述例子中,如果function中a从未被定义,那么console.log(a)将抛出ReferenceError。当function中对a进行定义后,即使这个定义在a变量调用语句之后,对a的调用也属于合法操作(如果对a变量的定义发生在调用语句之后,那么调用语句中a变量的值为undefined)。事实上,在function内用var关键词进行定义的所有变量,其定义操作都会被提至function的开头(赋值操作依然留在var定义的那一行),这在JavaScript中称之为hoisting。比如,上述代码就等价于:

function(){

  var a;

  console.log(a);//undefined

  a = "test";

  console.log(a);//test

}

变量的作用域链

联系JavaScript中变量的储存,可以很好的理解JS中的“function scope”与hoisting。由于变量是储存在全局对象或者函数调用对象上的,因此当在function中定义变量时,无论这个变量定义在function的什么地方,这次function调用所使用的函数调用对象中必然会出现一个与此变量同名的属性。如此一来,function中的任何地方都可以访问到该变量。

涉及到函数调用,JavaScript中还有一个更有趣的概念:变量的作用域链 — 由于变量是储存在全局对象或者函数调用对象上的,因此在访问变量时,可以从多个对象上获取值。以下面的代码为例:

var x = "test";

function(){

  //level-1 function

  var x = "temp";

  function(){

    //level-2 function

    var x = "real";

    //try to access x here. x will be "real".

  }

}

在上述代码中2级函数(level-2 function)的内部,当试图访问x变量时,程序可以从3个对象上搜索相应的属性值:调用2级函数所使用的函数调用对象、调用1级函数所使用的函数调用对象、全局对象 — 根据函数定义的嵌套关系,JavaScript将生成一个由全局对象和函数调用对象所组成的对象链。访问变量时,程序将从离访问语句最近的那个对象开始搜索,如果没有搜索到,则在对象链中上一级的对象中继续进行搜索,直至全局对象。

由于这个对象链与变量的作用域有关,因此也叫做“作用域链”。

如果需要临时改变作用域链,将某个对象插入到作用域链的最前端(作为最先访问到的那个函数对象),可以使用with语句:

with(o){

  //code use properties of object o.

}

不过,在JavaScript严格模式下,with语句是被禁用的;即使在非严格模式下,也不推荐使用with语句。

Javascript 相关文章推荐
js 分页全选或反选标识实现代码
Aug 09 Javascript
根据选择不同的下拉值出现相对应的文本输入框
Aug 01 Javascript
html5的自定义data-*属性和jquery的data()方法的使用示例
Aug 21 Javascript
快速解决jQuery与其他库冲突的方法介绍
Jan 02 Javascript
JS获取计算机mac地址以及IP的实现方法
Jan 08 Javascript
javascript结合fileReader 实现上传图片
Jan 30 Javascript
js实现YouKu的漂亮搜索框效果
Aug 19 Javascript
JS获取文件大小方法小结
Dec 08 Javascript
使用JavaScript判断用户输入的是否为正整数(两种方法)
Feb 05 Javascript
JavaScript数据结构之广义表的定义与表示方法详解
Apr 12 Javascript
js判断输入框不能为空格或null值的实现方法
Mar 02 Javascript
微信小程序仿朋友圈发布动态功能
Jul 15 Javascript
JavaScript中的变量定义与储存介绍
Dec 31 #Javascript
JavaScript中的操作符==与===介绍
Dec 31 #Javascript
jQuery中[attribute]选择器用法实例
Dec 31 #Javascript
JavaScript中的比较操作符&gt;、=、
Dec 31 #Javascript
javascript 操作符(~、&amp;、|、^、)使用案例
Dec 31 #Javascript
JavaScript中的逻辑判断符&amp;&amp;、||与!介绍
Dec 31 #Javascript
JavaScript中的eval()函数使用介绍
Dec 31 #Javascript
You might like
PHP里的中文变量说明
2011/07/23 PHP
jquery validator 插件增加日期比较方法
2010/02/21 Javascript
jquery获取input的value问题说明
2010/08/19 Javascript
jQuery选择器的工作原理和优化分析
2011/07/25 Javascript
javascript中的数字与字符串相加实例分析
2011/08/14 Javascript
JS特权方法定义作用以及与公有方法的区别
2013/03/18 Javascript
Nodejs学习笔记之Global Objects全局对象
2015/01/13 NodeJs
Js制作点击输入框时默认文字消失的效果
2015/09/05 Javascript
基于jquery编写的放大镜插件
2016/03/23 Javascript
Summernote实现图片上传功能的简单方法
2016/07/11 Javascript
快速解决js中window.location.href不工作的问题
2016/11/02 Javascript
jQuery实现弹幕效果
2017/02/17 Javascript
基于axios封装fetch方法及调用实例
2018/02/05 Javascript
详解mpvue开发微信小程序基础知识
2019/09/23 Javascript
基于javascript的无缝滚动动画1
2020/08/07 Javascript
[02:42]DOTA2城市挑战赛收官在即 四强之争风起云涌
2018/06/05 DOTA
python实现JAVA源代码从ANSI到UTF-8的批量转换方法
2015/08/10 Python
通过5个知识点轻松搞定Python的作用域
2016/09/09 Python
浅析python的优势和不足之处
2018/11/20 Python
基于Python解密仿射密码
2019/10/21 Python
Python MySQLdb 执行sql语句时的参数传递方式
2020/03/04 Python
python实现126邮箱发送邮件
2020/05/20 Python
Python 列表中的修改、添加和删除元素的实现
2020/06/11 Python
Pandas对DataFrame单列/多列进行运算(map, apply, transform, agg)
2020/06/14 Python
python删除指定列或多列单个或多个内容实例
2020/06/28 Python
CSS实现的一闪而过的图片闪光效果
2014/04/23 HTML / CSS
html5触摸事件判断滑动方向的实现
2018/06/05 HTML / CSS
海淘母婴商城:国际妈咪
2016/07/23 全球购物
世界上最好的儿童品牌:AlexandAlexa
2018/01/27 全球购物
酒店执行总经理岗位职责
2013/12/15 职场文书
幼儿教师工作感言
2014/02/14 职场文书
大学运动会入场词
2014/02/22 职场文书
放假通知
2015/04/14 职场文书
2016拓展训练心得体会范文
2016/01/12 职场文书
解读MySQL的客户端和服务端协议
2021/05/10 MySQL
MySQL常见优化方案汇总
2022/01/18 MySQL