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 相关文章推荐
推荐dojo学习笔记
Mar 24 Javascript
JavaScript数组和循环详解
Apr 27 Javascript
jQuery中extend()和fn.extend()方法详解
Jun 03 Javascript
jQuery实现的文字hover颜色渐变效果实例
Feb 20 Javascript
EasyUI创建对话框的两种方式
Aug 23 Javascript
Angular中使用$watch监听object属性值的变化(详解)
Apr 24 Javascript
使用react-router4.0实现重定向和404功能的方法
Aug 28 Javascript
JavaScript数据结构之双向链表和双向循环链表的实现
Nov 28 Javascript
微信小程序form表单组件示例代码
Jul 15 Javascript
layui获取选中行数据的实例讲解
Aug 19 Javascript
jQuery实现的简单日历组件定义与用法示例
Dec 24 jQuery
JavaScript实现网页留言板功能
Nov 23 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
德劲1103的维修打理经验
2021/03/02 无线电
php异常处理技术,顶级异常处理器
2012/06/13 PHP
destoon后台网站设置变成空白的解决方法
2014/06/21 PHP
php socket通信(tcp/udp)实例分析
2016/02/14 PHP
关于Curl在Swoole协程中的解决方案详析
2019/09/12 PHP
javascript学习笔记(十二) RegExp类型介绍
2012/06/20 Javascript
JavaScript高级程序设计阅读笔记(十六) javascript检测浏览器和操作系统-detect.js
2012/08/14 Javascript
使用jQuery的attr方法来修改onclick值
2014/07/07 Javascript
通过js为元素添加多项样式,浏览器全兼容写法
2014/08/30 Javascript
nodejs中简单实现Javascript Promise机制的实例
2014/12/06 NodeJs
javascript实时显示北京时间的方法
2015/03/12 Javascript
Nodejs学习item【入门手上】
2016/05/05 NodeJs
js css实现垂直方向自适应的三角提示菜单
2016/06/26 Javascript
Bootstrap实现弹性搜索框
2016/07/11 Javascript
微信小程序 地图map详解及简单实例
2017/01/10 Javascript
浅谈Javascript事件对象
2017/02/05 Javascript
Vue实现百度下拉提示搜索功能
2017/06/21 Javascript
jQuery.Form实现Ajax上传文件同时设置headers的方法
2017/06/26 jQuery
jQuery实现导航样式布局操作示例【可自定义样式布局】
2018/07/24 jQuery
[01:15:29]DOTA2上海特级锦标赛主赛事日 - 3 胜者组第二轮#2Secret VS EG第三局
2016/03/04 DOTA
PyChar学习教程之自定义文件与代码模板详解
2017/07/17 Python
解决pandas 作图无法显示中文的问题
2018/05/24 Python
Python内置类型性能分析过程实例
2020/01/29 Python
浅谈pytorch中torch.max和F.softmax函数的维度解释
2020/06/28 Python
python3跳出一个循环的实例操作
2020/08/18 Python
python闭包与引用以及需要注意的陷阱
2020/09/18 Python
利用Python pandas对Excel进行合并的方法示例
2020/11/04 Python
Python高阶函数与装饰器函数的深入讲解
2020/11/10 Python
css3实现一款模仿iphone样式的注册表单
2013/03/20 HTML / CSS
百丽国际旗下购物网站:优购
2017/02/28 全球购物
Vita Fede官网:在意大利手工制作,在纽约市设计
2019/10/25 全球购物
大学毕业生通用自我评价
2014/01/05 职场文书
2014年学校法制宣传日活动总结
2014/11/01 职场文书
幼儿教师年度个人总结
2015/02/05 职场文书
五星红旗迎风飘扬观后感
2015/06/17 职场文书
Mybatis-plus配置分页插件返回统一结果集
2022/06/21 Java/Android