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 相关文章推荐
jQuery判断元素是否是隐藏的代码
Apr 24 Javascript
javascript获取设置div的高度和宽度兼容任何浏览器
Sep 22 Javascript
javascript中call和apply的用法示例分析
Apr 02 Javascript
jQuery实现购物车表单自动结算效果实例
Aug 10 Javascript
学习jQuey中的return false
Dec 18 Javascript
js一维数组、多维数组和对象的混合使用方法
Apr 03 Javascript
JS日期对象简单操作(获取当前年份、星期、时间)
Oct 26 Javascript
Angular.JS去掉访问路径URL中的#号详解
Mar 30 Javascript
jQuery基于cookie实现换肤功能实例
Oct 14 jQuery
详解vue.js数据传递以及数据分发slot
Jan 20 Javascript
微信小程序网络请求封装示例
Jul 24 Javascript
Vue resource三种请求格式和万能测试地址
Sep 26 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
SONY ICF-SW7600的电路分析
2021/03/02 无线电
献给php初学者(入门学习经验谈)
2010/10/12 PHP
php 文件上传类代码
2011/08/06 PHP
php实现用户在线时间统计详解
2011/10/08 PHP
PHP-Java-Bridge使用笔记
2014/09/22 PHP
php简单获取文件扩展名的方法
2015/03/24 PHP
利用php输出不同的心形图案
2016/04/22 PHP
CI框架支持$_GET的两种实现方法
2016/05/18 PHP
use jscript Create a SQL Server database
2007/06/16 Javascript
键盘 keycode的值 javascript时触发事件时很有用的要素
2009/11/02 Javascript
javascript得到当前页的来路即前一页地址的方法
2014/02/18 Javascript
Angular中的Promise对象($q介绍)
2015/03/03 Javascript
vue2.0多条件搜索组件使用详解
2020/03/26 Javascript
微信小程序 监听手势滑动切换页面实例详解
2017/06/15 Javascript
使用Bootstrap + Vue.js实现表格的动态展示、新增和删除功能
2017/11/27 Javascript
微信小程序wx.getImageInfo()如何获取图片信息
2018/01/26 Javascript
vue ssr 指南详读
2018/06/29 Javascript
js canvas实现二维码和图片合成的海报
2020/11/19 Javascript
d3绘制基本的柱形图的实现代码
2018/12/12 Javascript
layui加载表格,绑定新增,编辑删除,查看按钮事件的例子
2019/09/06 Javascript
纯js实现无缝滚动功能代码实例
2020/02/21 Javascript
在Python中使用第三方模块的教程
2015/04/27 Python
Python中字典映射类型的学习教程
2015/08/20 Python
深入源码解析Python中的对象与类型
2015/12/11 Python
Python实现字符串格式化输出的方法详解
2017/09/20 Python
使用python编写udp协议的ping程序方法
2018/04/22 Python
Python实现将数据写入netCDF4中的方法示例
2018/08/30 Python
python 安装教程之Pycharm安装及配置字体主题,换行,自动更新
2020/03/13 Python
HTML5实现音频和视频嵌入的方法
2018/08/22 HTML / CSS
三年级评语大全
2014/04/23 职场文书
信电学院毕业生自荐书
2014/05/24 职场文书
电子信息工程专业自荐书
2014/06/24 职场文书
法人代表证明书格式
2014/10/01 职场文书
毕业实习证明(4篇)
2014/10/28 职场文书
离婚案件被告代理词
2015/05/23 职场文书
浅谈哪个Python库才最适合做数据可视化
2021/06/28 Python