实例详解JavaScript静态作用域和动态作用域

 更新时间:2021年10月25日 09:54:08   作者:战场小包  
作用域是指程序源代码中定义变量的区域,作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限,这篇文章主要给大家介绍了关于JavaScript静态作用域和动态作用域的相关资料,需要的朋友可以参考下

前言

在文章最开始,先学习几个概念:

  • 作用域:《你不知道的js》中指出,作用域是一套规则,这套规则用来管理引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称进行变量查找。简单来说,作用域规定了如何查找变量。
  • 静态作用域:又称词法作用域,函数的作用域在函数定义的时候就决定了,通俗点说就是你在写代码时将变量和块作用域写在哪里决定的。
  • 动态作用域:函数的作用域在函数调用时才决定的。

静态作用域与动态作用域

JavaScript采用的是静态作用域,函数定义的位置就决定了函数的作用域。

具体看一个例子,理解一下什么是静态作用域与动态作用域的区别

var val = 1;
function test() {
    console.log(val);
}
function bar() {
    var val = 2;
    test();
}

bar();
// 结果是???

上面代码中:

  • 我们首先定义全局变量 val,赋值为 1
  • 声明一个函数 text,函数的功能是打印 val 这个变量的值
  • 声明一个函数 bar,函数内部定义局部变量 val,赋值为 2;并且函数内部执行 test() 函数
  • 执行 bar() 函数

静态作用域执行过程

当执行 test 函数时,先从 test 函数内部查找是否有变量 val,如果没有,就沿定义函数的位置,查找上一层的代码,查找到全局变量 val ,其值为 1。

作用域查找始终从运行时所处的最内层作用域开始查找,逐级向外查找,直到遇见第一个匹配的标识符为止。

无论函数在哪里被调用,无论如何被调用,它的作用域只由函数定义所处的位置决定。

动态作用域执行过程

执行 test 函数,首先从函数内部查询 val 变量,如果没有,就从调用函数的作用域,即 bar 函数的作用域内部查找变量 val,所以打印结果 2

习题

我们来看三个习题,好好消化理解一下静态作用域: 函数定义位置就决定了作用域。

习题一

var a = 1
function fn1(){
    function fn3(){
        var a = 4
        fn2()
    }
    var a = 2
    return fn3
}
function fn2(){
    console.log(a)
}
var fn = fn1()
fn()

上面代码中:

  • 我们首先定义全局变量 a,赋值为 1
  • 声明一个函数 fn1,函数的内部分别声明了函数 fn3,定义局部变量 a,赋值为 2,返回值为 fn3 函数
  • fn3 函数内部定义局部变量 a,赋值为 4,执行 fn2()
  • 声明函数 fn2, 函数的功能是,打印 a 的值
  • fn 赋值为 fn1() 的返回值
  • 执行 fn() (相当于执行 fn3 函数)

做题之前,一定要理解 静态作用域 的概念。该题 fn2 定义在全局上,当 fn2 中找不到变量 a 时,它会去全局中寻找,与 fn1 和 fn3 毫无关系,打印 1.

习题二

var a = 1
function fn1(){
    function fn2(){
        console.log(a)
    }
    function fn3(){
        var a = 4
        fn2()
    }
    var a = 2
    return fn3
}
var fn = fn1()
fn()

fn2 是定义在函数 fn1 内部,因此当 fn2 内部没有变量 a 时,它会去 fn1 中寻找,跟函数 fn3 毫无关系,如果 fn1 中寻找不到,会到 fn1 定义的位置的上一层(全局)寻找,直至寻找到第一个匹配的标识符。本题可以在 fn1 中找到变量 a,打印 2

习题三

var a = 1;
function fn1(){
    function fn3(){
        function fn2(){
            console.log(a)
        }
        var a;
        fn2()
        a = 4
    }
    var a = 2
    return fn3
}
var fn = fn1()
fn()

该题 fn2 定义在函数 fn3 中,当 fn2 中找不到变量 a 时,会首先去 fn3 中查找,如果还查找不到,会到 fn1 中查找。本题可以在 fn3 中找到变量 a,但由于 fn2() 执行时,a 未赋值,打印 undefined。

总结

关于JavaScript 的静态作用域,我们只需要记住一句话:函数定义的位置就决定了函数的作用域,遇到题目时不要被别的代码干扰到。

到此这篇关于JavaScript静态作用域和动态作用域的文章就介绍到这了,更多相关JS静态作用域和动态作用域内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 文件预览PDF.js使用技巧示例总结

    文件预览PDF.js使用技巧示例总结

    这篇文章主要为大家介绍了文件预览PDF.js使用技巧示例总结,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • 小程序实现轮播图

    小程序实现轮播图

    这篇文章主要为大家详细介绍了小程序实现轮播图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • JavaScript实现添加及删除事件的方法小结

    JavaScript实现添加及删除事件的方法小结

    这篇文章主要介绍了JavaScript实现添加及删除事件的方法,实例总结了javascript对事件的添加及删除的技巧,涉及javascript事件绑定的方法及浏览器兼容的相关注意事项,需要的朋友可以参考下
    2015-08-08
  • 用cookies实现的可记忆的样式切换效果代码下载

    用cookies实现的可记忆的样式切换效果代码下载

    比较不错的用cookies实现的可记忆的样式切换效果,这个思路也在一定程序,方便客户的长期使用。
    2007-12-12
  • 深入浅析JavaScript系列(13):This? Yes,this!

    深入浅析JavaScript系列(13):This? Yes,this!

    在这篇文章里,我们将讨论跟执行上下文直接相关的更多细节。讨论的主题就是this关键字。实践证明,这个主题很难,在不同执行上下文中this的确定经常会发生问题
    2016-01-01
  • js代码实现的加入收藏效果并兼容主流浏览器

    js代码实现的加入收藏效果并兼容主流浏览器

    这篇文章主要介绍了js代码实现的加入收藏效果并兼容主流浏览器,需要的朋友可以参考下
    2014-06-06
  • javascript实现显示和隐藏div方法汇总

    javascript实现显示和隐藏div方法汇总

    本文章通过几个简单的实例告诉你如何来实例关于隐藏与显示div层及关闭层与隐藏的区别分析哦,有需要的同学可以参考一下本文章。
    2015-08-08
  • JS删除数组指定值常用方法详解

    JS删除数组指定值常用方法详解

    这篇文章主要介绍了JS删除数组指定值常用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • JavaScript 应用技巧集合[推荐]

    JavaScript 应用技巧集合[推荐]

    前段时间我曾经对JavaScript中的应用技巧进行了收集和总结这里我将会对这些应用技巧进行集中描述,如果你觉得遗漏了一些好用的应用技巧,也请在留言中提出,我会及时更新到这篇文章中的。
    2009-08-08
  • 原生js添加一个或多个类名的方法分析

    原生js添加一个或多个类名的方法分析

    这篇文章主要介绍了原生js添加一个或多个类名的方法,结合实例形式分析了javascript针对页面元素属性动态操作相关实现技巧,需要的朋友可以参考下
    2019-07-07

最新评论