资讯专栏INFORMATION COLUMN

javascript作用域的有序性

1fe1se / 2148人阅读

摘要:如果是嵌套的作用域的话,这些嵌套作用域会通过作用域链把嵌套作用域联系在一起。全局没有则报错但是上级作用域没法通过作用域链访问下级作用域。通过作用域链能让引擎对执行环境里所有有权访问的变量和函数进行有序访问。

一 为什么要有作用域

我们知道,变量对于程序来说是至关重要的,如果没有变量存储和访问值,整个程序会受到限制。那么问题来了,既然程序这么需要变量,那么它到底是怎么样去存储变量和使用变量的呢?存储变量这里暂且不提,到时候会有专门一篇博客来说明这个问题。我们这次说的主要就是如何去使用变量。这就要牵扯到我们今天的主题作用域上面了。
概括的来说,作用域就是一套能让你有序访问变量的规则。(注意有序很重要)javascript中只有函数能封闭作用域(let函数也能绑定一个块级作用域,这里先不做讨论).

二 作用域的有序性

来看下面一个例子

function foo (a) {
  var b = a * 2
  function bar (c) {
    console.log(a, b, c)
  }
  bar(b * 3)
  console.log(c)
}
foo(2)

(1)foo函数内部会形成一个作用域
(2)bar函数内部会形成一个作用域
(3)有一个全局的作用域
我们前面说过,作用域是一套能让你有序访问变量的规则,那么上述代码运行的时候,作用域是怎么样访问变量的呢?来看看下面的示意图。

,一个是函数bar的作用域,一个是函数foo的作用域,一个是全局的作用域。并且这三个作用域是嵌套的。
(1)bar作用域中有一个变量c
(2)foo作用域中有三个变量a,b,bar
(3)全局作用域中有一个变量foo
我们来看看上面代码的运行过程,首先执行最外层的foo(2),foo在调用栈调用bar,bar执行。但是注意bar内部的执行语句为
console.log(a,b,c)
我们前面已经说过,bar作用域中只有变量c,那么上述语句是否会出现错误呢,答案是不会。上述代码会正常输出。那么为什么会这样呢?答案就是代码在运行的过程中有一个作用域链能作用域给串起来。如下图

内部的作用域可以访问外部作用域的变量。所以bar函数在执行console.log(a,b,c)时,在当前作用域中如果没有找到a,b变量,它会顺着作用域链往上找,在上层作用域foo中找到了a,b变量,它就会使用上层作用域a,b的值。如果上层作用域还是没有a,b的话,它会顺着作用域继续查找,直到全局变量。如果全局变量仍然没有,程序就会报错。那么既然内部作用域能沿着作用域链访问到外部作用域,那么外部作用域能不能顺着作用域链访问内部作用域呢?不急,继续看下面代码。
执行完bar函数后,bar函数从执行栈中弹出,继续执行foo函数剩余的语句,console.log(c)
由于当前作用域中不存在变量c,但是其子作用域内有变量c的定义,那么程序会不会输出子级作用域的变量c呢?答案是不会。
上级作用域不能通过作用链进入下级作用域。只有下级作用域能通过作用链进入上级作用域。只就是作用域的有序性。有序的访问所有能访问的变量和函数。

三 总结

作用域就像一个一个封闭的空间,不同作用域内的变量是不会相互影响的。但是作用域之间又会有联系。如果是嵌套的作用域的话,这些嵌套作用域会通过作用域链把嵌套作用域联系在一起。内部作用域能通过作用域链访问到上级作用域的变量。即如果当前作用域中没有某个变量,引擎会通过作用域链查找上级作用域看看有没有定义该变量。直到全局作用域。(全局没有则报错)
但是上级作用域没法通过作用域链访问下级作用域。这就是作用域的有序性。通过作用域链能让引擎对执行环境里所有有权访问的变量和函数进行有序访问。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84441.html

相关文章

  • 谈谈javascript语法里一些难点问题(二)

    摘要:讲作用域链首先要从作用域讲起,下面是百度百科里对作用域的定义作用域在许多程序设计语言中非常重要。原文出处谈谈语法里一些难点问题二 3) 作用域链相关的问题 作用域链是javascript语言里非常红的概念,很多学习和使用javascript语言的程序员都知道作用域链是理解javascript里很重要的一些概念的关键,这些概念包括this指针,闭包等等,它非常红的另一个重要原因就...

    Enlightenment 评论0 收藏0
  • javascript中执行环境及作用域的理解

    摘要:作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。这样,一直延续到全局执行环境全局执行环境的变量对象始终都是作用域链中的最后一个对象。标识符解析是沿着作用域链一级一级地搜索标识符的过程。 执行环境(execution context,为简单起见,有时也成为环境)是javascript中最为重要的一个概念。执行环境定义了变量或函数有权访问的其他数据,决定了它们各自...

    BearyChat 评论0 收藏0
  • JavaScript闭包(三)

    摘要:目录执行环境与作用域链立即执行函数闭包知识点什么是闭包使用闭包的意义与注意点闭包的具体应用小结这是基本语法的函数部分的第篇文章,主要讲述了中比较重要的知识点闭包在讲闭包之前,在上一篇函数二的基础上,进一步深化执行环境和作用域链的知识点,并补 目录 1.执行环境与作用域链 2. 立即执行函数 3. 闭包知识点 3.1 什么是闭包 3.2 使用闭包的意义与注意点 3.3 闭包的具体应用 4...

    Anonymous1 评论0 收藏0
  • javascript的执行环境和作用域的理解1

    摘要:执行环境又称作执行上下文,其作用就是规定了对环境内的变量还有函数的操作权利,主要分为全局的执行环境和局部的执行环境。创建作用域链的作用主要是让每个嵌套关联的执行环境中的变量和函数有序的调用和操作。 1 执行环境(exeution context)又称作执行上下文,其作用就是规定了对环境内的变量还有函数的操作权利,主要分为全局的执行环境和局部的执行环境。 2 当一段代码进行运行的时候...

    Raaabbit 评论0 收藏0
  • javascript作用域,作用域链,[[scope]]属性

    摘要:正式由于作用域链的这种关系,我们就不难理解,为什么和不能通过作用域链向上搜索,因为对和的搜索在当前执行函数的活动对象就停止了。 对于Javascript程序员来说,闭包总会让你觉得既熟悉又陌生,然而它对于开发人员来说却非常重要,javascript里的许多设计模式中都用到了闭包,此处以函数作用域为例。 //示例代码 var a=1; function foo(){ ...

    pkhope 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<