JavaScript进阶(二)词法作用域与作用域链实例分析

yizhihongxing

我来为你详细讲解“JavaScript进阶(二)词法作用域与作用域链实例分析”的完整攻略。

什么是词法作用域

词法作用域(Lexical Scope)是指变量在程序中的作用域是由它在代码中声明的位置所决定的。也就是说,变量的作用域在定义时就已经确定了,不会受到函数内部的影响。

词法作用域 vs 动态作用域

JavaScript 采用的是词法作用域,而不是动态作用域。动态作用域是指变量的作用域取决于它在运行时所处的上下文环境,而不是在定义时确定。这种作用域的语言包括 bash、Perl、Lua 等等。

我们看一个示例:

var x = 'global';

function test () {
  console.log(x);
}

function foo () {
  var x = 'function';
  test();
}

foo(); // 输出: global

在这个例子中,test 函数里的 console.log(x) 输出的是全局变量 x,而不是函数 foo 中定义的局部变量 x,这就体现了词法作用域的特性。

作用域链

所谓作用域链(Scope Chain),就是在 JavaScript 的函数执行过程中,JavaScript 引擎会按照函数嵌套的层次查找变量的过程。

作用域链的查找顺序是由内而外、由下往上,最先查找当前函数的变量,如果找不到就往上一层函数中查找,直到找到全局作用域,如果还没有找到,则认为变量在当前作用域不存在。

我们来看一个作用域链的示例:

var x = 'global';

function outer () {
  var y = 'outer';

  function inner () {
    var z = 'inner';
    console.log(x, y, z);
  }
  inner();
}

outer();

在这个例子中,inner 函数中查找变量的过程是这样的:首先查找自身作用域中是否有 z,有的话直接使用;如果没有,则查找父级作用域,也就是 outer 函数中是否有 y,如果有,则使用;如果 outer 函数中也没有,则继续查找全局作用域中是否有 x,如果有,则使用。

示例:

接下来,我们来看两个示例:

示例一

我们先来看一个不使用 var 声明变量的示例,这是一个非常典型的 JavaScript 陷阱:

function foo () {
  x = 10;
}

foo();

console.log(x); // 输出: 10

在这个例子中,我们没有使用 var 声明变量 x,而是直接在函数内对它进行赋值。此时,JavaScript 引擎会默认将其当作全局变量,并把它添加到全局对象(window)中。

因此,当我们在函数外部调用变量 x 的时候,会直接从全局作用域中查找,从而输出 10。

示例二

接下来我们看一个更复杂的示例:

var x = 'global';

function outer () {
  var y = 'outer';

  function inner () {
    var z = 'inner';
    console.log(x, y, z);
  }
  inner();
}

function foo () {
  var x = 'function';
  outer();
}

foo();

在这个例子中,我们定义了全局变量 x,在函数 foo 中定义了局部变量 x,然后调用了函数 outerouter 内部定义了变量 yinner 内部定义了变量 z

当我们调用 foo 函数后,控制台输出的结果是:global outer inner

这是因为在 inner 函数中,先查找自身作用域中是否有 z,直接找到后输出;如果没有,则查找父级作用域,也就是 outer 函数中是否有 y,找到后输出;如果 outer 函数中也没有,则继续查找全局作用域中是否有 x,找到后输出。

注意,这里的 x 指的是全局变量 x,而不是函数 foo 中定义的局部变量 x,这就是词法作用域的特性。

总结一下:

词法作用域指变量在程序中的作用域是由它在代码中声明的位置所决定的,而不会受到函数内部的影响。

作用域链是在 JavaScript 的函数执行过程中,JavaScript 引擎会按照函数嵌套的层次查找变量的过程,并把查找的结果形成链式结构。

最后,我们需要注意在 JavaScript 中避免出现不使用 var 声明变量的情况,因为这么做会破坏作用域链,导致代码出现意料之外的结果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript进阶(二)词法作用域与作用域链实例分析 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • JavaScript实现url参数转成json形式

    当我们使用JavaScript处理URL的参数时,有时候需要将URL的参数转换为JSON形式来进行处理。下面我将为您提供JavaScript实现URL参数转为JSON的完整攻略: 利用window.location.search获取URL参数部分; 将URL参数部分解析为键值对对象; 将对象转换为JSON格式。 下面是详细步骤的代码实现: 1. 利用wind…

    JavaScript 2023年5月27日
    00
  • 使用three.js 绘制三维带箭头线的详细过程

    使用three.js绘制三维带箭头线的过程涉及到以下步骤: 1. 引入three.js和箭头模型 在HTML文件中引入three.js的库文件,并下载arrow模型作为箭头的模型: <!– 引入three.js的库文件 –> <script src="https://cdn.bootcdn.net/ajax/libs/thre…

    JavaScript 2023年5月28日
    00
  • JS遍历Json字符串中键值对先转成JSON对象再遍历

    要在JavaScript中遍历JSON字符串中的键值对,首先需要将JSON字符串转换为JavaScript对象。以下是实现此任务的完整步骤: 使用 JSON.parse() 将JSON字符串转成JSON对象。JSON.parse() 使用两个参数:要解析的JSON字符串和一个可选的“reviver”函数,用于调整解析生成的结果。如果只想将JSON字符串转换成…

    JavaScript 2023年5月27日
    00
  • JavaScript 节流函数 Throttle 详解

    JavaScript 节流函数 Throttle 详解 什么是节流函数 函数节流是一种通过控制函数执行频率的技术,可以让我们控制一个函数在一段时间时间内执行多少次。它可以解决一些频繁触发事件的问题,例如页面滚动的触发事件。 为何需要使用节流函数 在一些需要频繁执行的L函数中,比如页面滑动事件,如果不做任何优化处理,就会导致多次重复计算、频繁造成 DOM 渲染…

    JavaScript 2023年5月27日
    00
  • 前端token中4个存储位置的优缺点说明

    前端Token是指存储在前端网页中的用来标识用户身份的令牌,一般用于用户登录、验证和权限控制等方面。前端Token可以存在多个存储位置中,通常有四种:Cookie、Web Storage、IndexedDB、Memory。 以下是关于这四个存储位置的优缺点说明: Cookie Cookie是HTTP协议中常用的一种存储方式,可以存放在客户端的浏览器中,也可以…

    JavaScript 2023年6月11日
    00
  • JS判断字符串长度的5个方法(区分中文和英文)

    这里是详细讲解“JS判断字符串长度的5个方法(区分中文和英文)”的完整攻略。 什么是字符串长度 在JavaScript编程中,字符串长度指的是字符串中包含的字符数。在英文环境中,一个字符通常只占用一个字节的空间,而在中文环境中,一个字符可能需要占用多个字节的空间。因此,在处理字符串时,需要特别注意字符长度的计算问题。 判断字符串长度的方法 下面介绍5种常用的…

    JavaScript 2023年5月19日
    00
  • JS实现的抛物线运动效果示例

    下面我将为你详细讲解“JS实现的抛物线运动效果示例”的完整攻略。具体内容如下: 抛物线运动效果实现的原理 在实现抛物线运动效果之前,我们需要先了解它的基本原理。通俗地说,抛物线运动是指一种自由落体运动,其加速度大小保持不变,但方向发生变化,运动轨迹呈现抛物线形状。在应用中,我们可以通过以下公式来计算抛物线运动的位置: x = vx * t + x0; y =…

    JavaScript 2023年5月28日
    00
  • eval有时候也可以用,而且有奇效

    eval,一个我曾经避之不及的函数,最近我对它产生了一点新的感触:eval有时候也可以用,有奇效。 一般在使用js进行开发时,是不建议使用eval这类函数的。在JavaScript中,eval可以计算传入的字符串,将其当作js代码来执行。因为它可执行js代码的特性,有可能被第三方利用,传入恶意js代码执行,因此这个函数存在安全风险。再加上eval执行的速度低…

    JavaScript 2023年4月18日
    00
合作推广
合作推广
分享本页
返回顶部