摘要:在编程中,我们经常会想获取并扩展一些东西。 例如,我们有一个 user 对象及其属性和方法,并希望将 admin 和 guest 作为基于 user 稍加修改的变体。我们想重用 user 中的内容,而不是复制/重新实现它的方法,而只是在其之上构建一个新的对象。 原型继承(Prototypal inh
阅读全文
摘要:有两种类型的对象属性。 第一种是 数据属性。我们已经知道如何使用它们了。到目前为止,我们使用过的所有属性都是数据属性。 第二种类型的属性是新东西。它是 访问器属性(accessor property)。它们本质上是用于获取和设置值的函数,但从外部代码来看就像常规属性。 getter 和 setter
阅读全文
摘要:我们知道,对象可以存储属性。 到目前为止,属性对我们来说只是一个简单的“键值”对。但对象属性实际上是更灵活且更强大的东西。 在本章中,我们将学习其他配置选项,在下一章中,我们将学习如何将它们无形地转换为 getter/setter 函数。 属性标志 对象属性(properties),除 value
阅读全文
摘要:让我们深入研究一下箭头函数。 箭头函数不仅仅是编写简洁代码的“捷径”。它还具有非常特殊且有用的特性。 JavaScript 充满了我们需要编写在其他地方执行的小函数的情况。 例如: arr.forEach(func) —— forEach 对每个数组元素都执行 func。 setTimeout(fu
阅读全文
摘要:当将对象方法作为回调进行传递,例如传递给 setTimeout,这儿会存在一个常见的问题:“丢失 this”。 在本章中,我们会学习如何去解决这个问题。 丢失 “this” 我们已经看到了丢失 this 的例子。一旦方法被传递到与对象分开的某个地方 —— this 就丢失。 下面是使用 setTim
阅读全文
摘要:JavaScript 在处理函数时提供了非凡的灵活性。它们可以被传递,用作对象,现在我们将看到如何在它们之间 转发(forward) 调用并 装饰(decorate) 它们。 透明缓存 假设我们有一个 CPU 重负载的函数 slow(x),但它的结果是稳定的。换句话说,对于相同的 x,它总是返回相同
阅读全文
摘要:有时我们并不想立即执行一个函数,而是等待特定一段时间之后再执行。这就是所谓的“计划调用(scheduling a call)”。 目前有两种方式可以实现: setTimeout 允许我们将函数推迟到一段时间间隔之后再执行。 setInterval 允许我们重复运行一个函数,从一段时间间隔之后开始运行
阅读全文
摘要:还有一种创建函数的方法。它很少被使用,但有些时候只能选择它。 语法 创建函数的语法: let func = new Function ([arg1, arg2, ...argN], functionBody); 该函数是通过使用参数 arg1...argN 和给定的 functionBody 创建的
阅读全文
摘要:我们已经知道,在 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)。
阅读全文