摘要:我们已经知道,在 JavaScript 中,函数也是一个值。 而 JavaScript 中的每个值都有一种类型,那么函数是什么类型呢? 在 JavaScript 中,函数的类型是对象。 一个容易理解的方式是把函数想象成可被调用的“行为对象(action object)”。我们不仅可以调用它们,还能把
阅读全文
摘要:全局对象提供可在任何地方使用的变量和函数。默认情况下,这些全局变量内建于语言或环境中。 在浏览器中,它的名字是 “window”,对 Node.js 而言,它的名字是 “global”,其它环境可能用的是别的名字。 最近,globalThis 被作为全局对象的标准名称加入到了 JavaScript
阅读全文
摘要:❗️ 本文用于帮助理解旧脚本 本文所讲的内容对于帮助理解旧脚本很有用。 但这不是我们编写新代码的方式。 在本教程最开始那部分的 “变量” 这章中,我们提到了变量声明的三种方式: let const var var 声明与 let 相似。大部分情况下,我们可以用 let 代替 var 或者 var 代
阅读全文
摘要:JavaScript 是一种非常面向函数的语言。它给了我们很大的自由度。在 JavaScript 中,我们可以随时创建函数,可以将函数作为参数传递给另一个函数,并在完全不同的代码位置进行调用。 我们已经知道函数可以访问其外部的变量。 但是,如果在函数被创建之后,外部变量发生了变化会怎样?函数会获得新
阅读全文
摘要:在 JavaScript 中,很多内建函数都支持传入任意数量的参数。 例如: Math.max(arg1, arg2, ..., argN) —— 返回参数中的最大值。 Object.assign(dest, src1, ..., srcN) —— 依次将属性从 src1..N 复制到 dest。
阅读全文
摘要:让我们回到函数,进行更深入的研究。 我们的第一个主题是 递归(recursion)。 如果你不是刚接触编程,那么你可能已经很熟悉它了,那么你可以跳过这一章。 递归是一种编程模式,在一个任务可以自然地拆分成多个相同类型但更简单的任务的情况下非常有用。或者,在一个任务可以简化为一个简单的行为加上该任务的
阅读全文
摘要:假设我们有一个复杂的对象,我们希望将其转换为字符串,以通过网络发送,或者只是为了在日志中输出它。 当然,这样的字符串应该包含所有重要的属性。 我们可以像这样实现转换: let user = { name: "John", age: 30, toString() { return `{name: "$
阅读全文
摘要:让我们来学习一个新的内建对象:日期(Date)。该对象存储日期和时间,并提供了日期/时间的管理方法。 我们可以使用它来存储创建/修改时间,测量时间,或者仅用来打印当前时间。 创建 调用 new Date() 来创建一个新的 Date 对象。在调用时可以带有一些参数,如下所示: new Date()
阅读全文
摘要:JavaScript 中最常用的两种数据结构是 Object 和 Array。 对象是一种根据键存储数据的实体。 数组是一种直接存储数据的有序列表。 但是,当我们把它们传递给函数时,函数可能不需要整个对象/数组,而只需要其中一部分。 解构赋值 是一种特殊的语法,它使我们可以将数组或对象“拆包”至一系
阅读全文
摘要:对各个数据结构的学习至此告一段落,下面让我们讨论一下如何迭代它们。 在前面的章节中,我们认识了 map.keys(),map.values() 和 map.entries() 方法。 这些方法是通用的,有一个共同的约定来将它们用于各种数据结构。如果我们创建一个我们自己的数据结构,我们也应该实现这些方
阅读全文
摘要:我们从前面的 垃圾回收 章节中知道,JavaScript 引擎在值“可达”和可能被使用时会将其保持在内存中。 例如: let john = { name: "John" }; // 该对象能被访问,john 是它的引用 // 覆盖引用 john = null; // 该对象将会被从内存中清除 通常,
阅读全文
摘要:学到现在,我们已经了解了以下复杂的数据结构: 对象,存储带有键的数据的集合。 数组,存储有序集合。 但这还不足以应对现实情况。这就是为什么存在 Map 和 Set。 Map Map 是一个带键的数据项的集合,就像一个 Object 一样。 但是它们最大的差别是 Map 允许任何类型的键(key)。
阅读全文
摘要:可迭代(Iterable) 对象是数组的泛化。这个概念是说任何对象都可以被定制为可在 for..of 循环中使用的对象。 数组是可迭代的。但不仅仅是数组。很多其他内建对象也都是可迭代的。例如字符串也是可迭代的。 如果从技术上讲,对象不是数组,而是表示某物的集合(列表,集合),for..of 是一个能
阅读全文
摘要:添加/移除数组元素 我们已经学了从数组的首端或尾端添加和删除元素的方法: arr.push(...items) —— 从尾端添加元素, arr.pop() —— 从尾端提取元素, arr.shift() —— 从首端提取元素, arr.unshift(...items) —— 从首端添加元素。 这里
阅读全文
摘要:对象允许存储键值集合,这很好。 但很多时候我们发现还需要 有序集合,里面的元素都是按顺序排列的。例如,我们可能需要存储一些列表,比如用户、商品以及 HTML 元素等。 这里使用对象就不是很方便了,因为对象不能提供能够管理元素顺序的方法。我们不能在已有的元素“之间”插入一个新的属性。这种场景下对象就不
阅读全文
摘要:在 JavaScript 中,文本数据被以字符串形式存储,单个字符没有单独的类型。 字符串的内部格式始终是 UTF-16,它不依赖于页面编码。 引号(Quotes) 让我们回忆一下引号的种类。 字符串可以包含在单引号、双引号或反引号中: let single = 'single-quoted'; l
阅读全文
摘要:在现代 JavaScript 中,数字(number)有两种类型: JavaScript 中的常规数字以 64 位的格式 IEEE-754 存储,也被称为“双精度浮点数”。这是我们大多数时候所使用的数字,我们将在本章中学习它们。 BigInt 用于表示任意长度的整数。有时会需要它们,因为正如我们在前
阅读全文
摘要:JavaScript 允许我们像使用对象一样使用原始类型(字符串,数字等)。JavaScript 还提供了这样的调用方法。我们很快就会学习它们,但是首先我们将了解它的工作原理,毕竟原始类型不是对象(在这里我们会分析地更加清楚)。 我们来看看原始类型和对象之间的关键区别。 一个原始值: 是原始类型中的
阅读全文
摘要:当对象相加 obj1 + obj2,相减 obj1 - obj2,或者使用 alert(obj) 打印时会发生什么? JavaScript 不允许自定义运算符对对象的处理方式。与其他一些编程语言(Ruby,C++)不同,我们无法实现特殊的对象处理方法来处理加法(或其他运算)。 在此类运算的情况下,对
阅读全文
摘要:根据规范,只有两种原始类型可以用作对象属性键: 字符串类型 symbol 类型 否则,如果使用另一种类型,例如数字,它会被自动转换为字符串。所以 obj[1] 与 obj["1"] 相同,而 obj[true] 与 obj["true"] 相同。 到目前为止,我们一直只使用字符串。 现在我们来看看
阅读全文