关于JavaScript作用域你想知道的一切

关于JavaScript作用域你想知道的一切

什么是作用域?

在介绍作用域之前,我们先来看一下变量的定义。在JavaScript中,我们可以通过varletconst三个关键字来声明变量。

var a = 1; // 使用var声明的变量
let b = 2; // 使用let声明的变量
const c = 3; // 使用const声明的变量

那么,作用域是什么呢?

简单来说,作用域是指变量存在的环境,决定了变量的可见范围和生命周期。在JavaScript中,作用域分为全局作用域和局部作用域。

全局作用域和局部作用域

全局作用域指的是在函数外部声明的变量,它们的生命周期与页面的生命周期相同,直到页面关闭才会被销毁。

var a = 1; // 全局作用域
function test() {
  console.log(a); // 1
}
test(); // 输出 1

局部作用域指的是在函数内部声明的变量,它们的生命周期只存在于当前函数内部,在函数执行完毕后会被销毁。

function test() {
  var a = 1; // 局部作用域
  console.log(a); // 1
}
test(); // 输出 1
console.log(a); // 报错:ReferenceError: a is not defined

作用域链

当变量在当前作用域没有找到时,会沿着作用域链向上查找。作用域链的顶端是全局作用域,当全局作用域都没有找到时,会返回undefined

var a = 1;
function test() {
  console.log(a); // 在当前作用域找不到,向上查找,输出 1
}
test(); // 输出 1

块级作用域

在ES6之前,JavaScript中只有全局作用域和函数作用域。在函数内部使用var声明变量,它的作用域是整个函数,而不是函数内部的块级作用域。例如:

function test() {
  if (true) {
    var a = 1;
  }
  console.log(a); // 输出 1
}
test(); // 输出 1

在ES6中,新增了letconst关键字,它们声明的变量具有块级作用域,只能在当前块中访问。

function test() {
  if (true) {
    let a = 1;
    const b = 2;
  }
  console.log(a); // 报错:ReferenceError: a is not defined
  console.log(b); // 报错:ReferenceError: b is not defined
}
test();

示例一:闭包

闭包是函数和声明该函数的词法环境的组合。闭包包含了函数和其外部的作用域。通过闭包,我们可以访问外部函数中的变量,并且外部函数执行完后,变量不会被销毁。

function outer() {
  var a = 1;
  function inner() {
    console.log(a);
  }
  return inner;
}
var fn = outer();
fn(); // 输出 1

在这个例子中,inner函数可以访问outer函数中的a变量,因为outer函数的作用域被包含在inner函数的词法环境中,而且outer函数被执行完后,a变量并没有被销毁,因为它被inner函数的闭包所引用。

示例二:函数作为参数

在JavaScript中,函数也是一种数据类型,可以作为参数传递。

function add(x, y) {
  return x + y;
}
function handle(fn) {
  var x = 1;
  var y = 2;
  return fn(x, y);
}
console.log(handle(add)); // 输出 3

在这个例子中,函数add作为参数传递给了函数handle,并且在handle函数内部被执行。在执行add函数时,add函数的作用域被包含在handle函数的词法环境中,从而使得add函数能够访问handle函数内部的变量xy

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:关于JavaScript作用域你想知道的一切 - Python技术站

(0)
上一篇 2023年6月16日
下一篇 2023年6月16日

相关文章

  • JSP隐含对象response实现文件下载的两种方法

    以下是JSP中使用response实现文件下载的两种方法的详细攻略: 1. 使用response的setHeader()方法: 1.1 步骤: 在JSP页面中,需要一个超链接或者按钮,通过它来触发文件下载,比如: html <a href=”download.jsp?file=test.txt”>下载文件</a> 在download.…

    Java 2023年6月15日
    00
  • 解析在Tomcat中启用虚拟线程特性

    解析在Tomcat中启用虚拟线程特性的完整攻略 什么是虚拟线程? 虚拟线程是一种优化Java Web服务器性能的一种技术,虚拟线程的实现不完全依赖于物理线程,而是通过线程池去模拟实现,这样就可以比物理线程更灵活的、更充分的利用服务器的资源,提高性能。 启用Tomcat虚拟线程特性 要启用Tomcat的虚拟线程特性,需要遵循以下步骤: 步骤1:修改server…

    Java 2023年5月19日
    00
  • php使用json-schema模块实现json校验示例

    让我为您详细讲解一下PHP使用json-schema模块实现JSON校验的完整攻略。 什么是JSON Schema JSON Schema是用于描述JSON文档格式的规范。它允许定义一个JSON文档的结构、数据类型、值域限制等内容,并且可以通过一定的手段进行验证。因此,使用JSON Schema可以方便地校验JSON数据的完整性和正确性。 PHP中使用JSO…

    Java 2023年5月26日
    00
  • 解析关于java,php以及html的所有文件编码与乱码的处理方法汇总

    解析关于java,php以及html的所有文件编码与乱码的处理方法汇总 在开发web应用时,经常会遇到关于文件编码与乱码的问题。下面是关于Java、PHP和HTML文件编码与乱码的处理方法的汇总。 文件编码 文件编码是指在存储文件时所使用的编码格式。Web开发中,常用的编码格式有UTF-8编码和GB2312编码。 UTF-8编码 UTF-8编码是一种可变长度…

    Java 2023年5月20日
    00
  • SpringData JPA实现查询分页demo

    下面我会给出 Spring Data JPA 实现查询分页 Demo 的详细攻略。 1. 添加依赖 在项目的 pom.xml 文件中添加 Spring Data JPA 依赖: <dependency> <groupId>org.springframework.data</groupId> <artifactId&g…

    Java 2023年5月20日
    00
  • Springboot使用influxDB时序数据库的实现

    接下来我将详细讲解“Springboot使用influxDB时序数据库的实现”的完整攻略。首先需要明确的是,influxDB是一个高性能的时序数据库,专门用于处理时间序列数据。而Springboot是一个基于Spring框架的应用程序快速开发框架。 引入influxDB依赖 在Springboot项目的pom.xml文件中,添加以下依赖: <depen…

    Java 2023年5月20日
    00
  • 使用IDEA配置Tomcat和连接MySQL数据库(JDBC)详细步骤

    以下是使用IDEA配置Tomcat和连接MySQL数据库(JDBC)详细步骤: 配置Tomcat 步骤1:下载Tomcat 首先,我们需要下载Tomcat。可以在Tomcat官网下载。下载完成后,将Tomcat压缩包解压到本地合适的目录。 步骤2:在IDEA中添加Tomcat服务器 1.打开IDEA,进入File -> Settings -> B…

    Java 2023年5月20日
    00
  • Java遍历集合方法分析(实现原理、算法性能、适用场合)

    Java遍历集合是每个Java开发者都必须学会的一个技能。它是处理集合数据的重要步骤。本文将详细讲解Java遍历集合方法的实现原理、算法性能和适用场合。 什么是Java集合 Java集合是Java语言提供的一组数据结构,用于存储数据的容器。它们是一种实用工具,可用于处理复杂的数据结构,例如列表、队列、栈、哈希表等。Java集合框架是一组接口和类的集合,用于处…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部