JavaScript中的变量作用域介绍

 更新时间:2014年12月31日 09:28:34   投稿:junjie  
这篇文章主要介绍了JavaScript中的变量作用域介绍,本文同时讲解了一个新概念变量的作用域链,需要的朋友可以参考下

对于变量的作用域(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中如何快速获取数组最后一个值

    javascript中如何快速获取数组最后一个值

    这篇文章主要介绍了javascript中如何快速获取数组最后一个值问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • js实现时分秒倒计时

    js实现时分秒倒计时

    这篇文章主要为大家详细介绍了js实现时分秒倒计时,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • Javascript函数技巧学习

    Javascript函数技巧学习

    这篇文章主要介绍了Javascript函数技巧学习,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-07-07
  • 使用window.postMessage()方法在两个网页间传递数据

    使用window.postMessage()方法在两个网页间传递数据

    这篇文章介绍了使用window.postMessage()在两个网页间传递数据的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • Promise.all中对于reject的处理方法

    Promise.all中对于reject的处理方法

    这篇文章主要介绍了Promise.all中对于reject的处理方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-08-08
  • 微信小程序和百度的语音识别接口详解

    微信小程序和百度的语音识别接口详解

    这篇文章主要介绍了微信小程序和百度的语音识别接口详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • 一文带你深入理解JavaScript模板引擎

    一文带你深入理解JavaScript模板引擎

    在Web前端开发中,需要将数据动态渲染到页面上,随着应用程序的复杂度增加,数据渲染的逻辑也变得越来越复杂,这时候就需要使用模板引擎来帮助我们动态生成HTML标记,本文将深入介绍 JavaScript 模板引擎,帮助读者更好地理解和应用模板引擎
    2023-06-06
  • JavaScript面试必备之垃圾回收机制和内存泄漏详解

    JavaScript面试必备之垃圾回收机制和内存泄漏详解

    垃圾回收机制和内存泄漏是JavaScript面试时常常问到的问题,这篇文章就为大家详细整理了他们的相关知识,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-05-05
  • javascript面向对象程序设计实践常用知识点总结

    javascript面向对象程序设计实践常用知识点总结

    这篇文章主要介绍了javascript面向对象程序设计实践常用知识点,结合实例形式总结分析了javascript面向对象程序设计中原型引用类型、属性、方法相关操作技巧与注意事项,需要的朋友可以参考下
    2019-07-07
  • js数字转换为float,取N位小数

    js数字转换为float,取N位小数

    在javascript中不分单精度float和双精度double,凡事有小数的变量都认为是float,因此要取小数后的n位,要用方法toFixed(n)来得到
    2014-02-02

最新评论