JavaScript 权威指南第七版(GPT 重译)(一)(2)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: JavaScript 权威指南第七版(GPT 重译)(一)

JavaScript 权威指南第七版(GPT 重译)(一)(1)https://developer.aliyun.com/article/1485286

本示例使用了许多高级 JavaScript 特性,旨在演示真实世界的 JavaScript 程序可能是什么样子。您不应该期望立即理解所有代码,但请放心,所有内容将在接下来的章节中解释。

示例 1-1. 使用 JavaScript 计算字符频率直方图
/**
 * This Node program reads text from standard input, computes the frequency
 * of each letter in that text, and displays a histogram of the most
 * frequently used characters. It requires Node 12 or higher to run.
 *
 * In a Unix-type environment you can invoke the program like this:
 *    node charfreq.js < corpus.txt
 */
// This class extends Map so that the get() method returns the specified
// value instead of null when the key is not in the map
class DefaultMap extends Map {
    constructor(defaultValue) {
        super();                          // Invoke superclass constructor
        this.defaultValue = defaultValue; // Remember the default value
    }
    get(key) {
        if (this.has(key)) {              // If the key is already in the map
            return super.get(key);        // return its value from superclass.
        }
        else {
            return this.defaultValue;     // Otherwise return the default value
        }
    }
}
// This class computes and displays letter frequency histograms
class Histogram {
    constructor() {
        this.letterCounts = new DefaultMap(0);  // Map from letters to counts
        this.totalLetters = 0;                  // How many letters in all
    }
    // This function updates the histogram with the letters of text.
    add(text) {
        // Remove whitespace from the text, and convert to upper case
        text = text.replace(/\s/g, "").toUpperCase();
        // Now loop through the characters of the text
        for(let character of text) {
            let count = this.letterCounts.get(character); // Get old count
            this.letterCounts.set(character, count+1);    // Increment it
            this.totalLetters++;
        }
    }
    // Convert the histogram to a string that displays an ASCII graphic
    toString() {
        // Convert the Map to an array of [key,value] arrays
        let entries = [...this.letterCounts];
        // Sort the array by count, then alphabetically
        entries.sort((a,b) => {              // A function to define sort order.
            if (a[1] === b[1]) {             // If the counts are the same
                return a[0] < b[0] ? -1 : 1; // sort alphabetically.
            } else {                         // If the counts differ
                return b[1] - a[1];          // sort by largest count.
            }
        });
        // Convert the counts to percentages
        for(let entry of entries) {
            entry[1] = entry[1] / this.totalLetters*100;
        }
        // Drop any entries less than 1%
        entries = entries.filter(entry => entry[1] >= 1);
        // Now convert each entry to a line of text
        let lines = entries.map(
            ([l,n]) => `${l}: ${"#".repeat(Math.round(n))} ${n.toFixed(2)}%`
        );
        // And return the concatenated lines, separated by newline characters.
        return lines.join("\n");
    }
}
// This async (Promise-returning) function creates a Histogram object,
// asynchronously reads chunks of text from standard input, and adds those chunks to
// the histogram. When it reaches the end of the stream, it returns this histogram
async function histogramFromStdin() {
    process.stdin.setEncoding("utf-8"); // Read Unicode strings, not bytes
    let histogram = new Histogram();
    for await (let chunk of process.stdin) {
        histogram.add(chunk);
    }
    return histogram;
}
// This one final line of code is the main body of the program.
// It makes a Histogram object from standard input, then prints the histogram.
histogramFromStdin().then(histogram => { console.log(histogram.toString()); });

1.5 总结

本书从底层向上解释 JavaScript。这意味着我们从注释、标识符、变量和类型等低级细节开始;然后构建表达式、语句、对象和函数;然后涵盖类和模块等高级语言抽象。我认真对待本书标题中的“权威”一词,接下来的章节将以可能一开始感觉令人望而却步的细节水平解释语言。然而,真正掌握 JavaScript 需要理解这些细节,我希望您能抽出时间从头到尾阅读本书。但请不要觉得您需要在第一次阅读时就这样做。如果发现自己在某一部分感到困惑,请直接跳到下一部分。一旦对整个语言有了工作知识,您可以回来掌握细节。

第二章:词法结构

编程语言的词法结构是指定如何在该语言中编写程序的基本规则集。它是语言的最低级语法:它指定变量名的外观,注释的分隔符字符,以及如何将一个程序语句与下一个分隔开,例如。本短章记录了 JavaScript 的词法结构。它涵盖了:

  • 区分大小写、空格和换行
  • 注释
  • 文字
  • 标识符和保留字
  • Unicode
  • 可选分号

2.1 JavaScript 程序的文本

JavaScript 是区分大小写的语言。这意味着语言关键字、变量、函数名和其他标识符必须始终以一致的字母大小写输入。例如,while关键字必须输入为while,而不是“While”或“WHILE”。同样,onlineOnlineOnLineONLINE是四个不同的变量名。

JavaScript 会忽略程序中标记之间出现的空格。在大多数情况下,JavaScript 也会忽略换行(但请参见§2.6 中的一个例外)。由于您可以在程序中自由使用空格和换行,因此可以以整洁一致的方式格式化和缩进程序,使代码易于阅读和理解。

除了常规空格字符(\u0020)外,JavaScript 还识别制表符、各种 ASCII 控制字符和各种 Unicode 空格字符作为空白。JavaScript 将换行符、回车符和回车符/换行符序列识别为行终止符。

2.2 注释

JavaScript 支持两种注释风格。任何位于//和行尾之间的文本都被视为注释,JavaScript 会忽略它。位于/**/之间的文本也被视为注释;这些注释可以跨越多行,但不能嵌套。以下代码行都是合法的 JavaScript 注释:

// This is a single-line comment.
/* This is also a comment */  // and here is another comment.
/*
 * This is a multi-line comment. The extra * characters at the start of
 * each line are not a required part of the syntax; they just look cool!
 */

2.3 文字

文字 是直接出现在程序中的数据值。以下都是文字:

12               // The number twelve
1.2              // The number one point two
"hello world"    // A string of text
'Hi'             // Another string
true             // A Boolean value
false            // The other Boolean value
null             // Absence of an object

数字和字符串文字的完整详细信息请参见第三章。

2.4 标识符和保留字

标识符 就是一个名字。在 JavaScript 中,标识符用于命名常量、变量、属性、函数和类,并为 JavaScript 代码中某些循环提供标签。JavaScript 标识符必须以字母、下划线(_)或美元符号($)开头。后续字符可以是字母、数字、下划线或美元符号。(不允许数字作为第一个字符,以便 JavaScript 可以轻松区分标识符和数字。)以下都是合法的标识符:

i
my_variable_name
v13
_dummy
$str

与任何语言一样,JavaScript 为语言本身保留了某些标识符。这些“保留字”不能用作常规标识符。它们在下一节中列出。

2.4.1 保留字

以下单词是 JavaScript 语言的一部分。其中许多(如ifwhilefor)是必须避免用作常量、变量、函数或类名称的保留关键字(尽管它们都可以用作对象内的属性名称)。其他一些单词(如fromofgetset)在有限的上下文中使用时没有语法歧义,作为标识符是完全合法的。还有其他关键字(如let)为了保持与旧程序的向后兼容性而不能完全保留,因此有复杂的规则规定何时可以将其用作标识符,何时不行。(例如,如果在类外部用var声明,let可以用作变量名,但如果在类内部或用const声明,则不行。)最简单的方法是避免将这些单词用作标识符,除了fromsettarget,它们是安全的并且已经被广泛使用。

as      const      export     get         null     target   void
async   continue   extends    if          of       this     while
await   debugger   false      import      return   throw    with
break   default    finally    in          set      true     yield
case    delete     for        instanceof  static   try
catch   do         from       let         super    typeof
class   else       function   new         switch   var

JavaScript 还保留或限制了某些关键字的使用,这些关键字目前尚未被语言使用,但可能在未来版本中使用:

enum  implements  interface  package  private  protected  public

由于历史原因,在某些情况下不允许将argumentseval用作标识符,并且最好完全避免使用它们。

2.5 Unicode

JavaScript 程序使用 Unicode 字符集编写,您可以在字符串和注释中使用任何 Unicode 字符。为了便于移植和编辑,通常在标识符中仅使用 ASCII 字母和数字。但这只是一种编程约定,语言允许在标识符中使用 Unicode 字母、数字和表意文字(但不允许使用表情符号)。这意味着程序员可以使用数学符号和非英语语言中的单词作为常量和变量:

const π = 3.14;
const sí = true;

2.5.1 Unicode 转义序列

一些计算机硬件和软件无法显示、输入或正确处理完整的 Unicode 字符集。为了支持使用较旧技术的程序员和系统,JavaScript 定义了转义序列,允许我们仅使用 ASCII 字符编写 Unicode 字符。这些 Unicode 转义以字符\u开头,后面要么跟着恰好四个十六进制数字(使用大写或小写字母 A-F),要么是由一个到六个十六进制数字括在花括号内。这些 Unicode 转义可能出现在 JavaScript 字符串文字、正则表达式文字和标识符中(但不出现在语言关键字中)。例如,字符“é”的 Unicode 转义是\u00E9;以下是三种包含此字符的变量名的不同写法:

let café = 1; // Define a variable using a Unicode character
caf\u00e9     // => 1; access the variable using an escape sequence
caf\u{E9}     // => 1; another form of the same escape sequence

早期版本的 JavaScript 仅支持四位数转义序列。带有花括号的版本是在 ES6 中引入的,以更好地支持需要超过 16 位的 Unicode 代码点,例如表情符号:

console.log("\u{1F600}");  // Prints a smiley face emoji

Unicode 转义也可能出现在注释中,但由于注释被忽略,因此在该上下文中它们仅被视为 ASCII 字符,而不被解释为 Unicode。

2.5.2 Unicode 规范化

如果您在 JavaScript 程序中使用非 ASCII 字符,您必须意识到 Unicode 允许以多种方式对相同字符进行编码。例如,字符串“é”可以编码为单个 Unicode 字符\u00E9,也可以编码为常规 ASCII 的“e”后跟重音符组合标记\u0301。这两种编码在文本编辑器中显示时通常看起来完全相同,但它们具有不同的二进制编码,这意味着 JavaScript 认为它们是不同的,这可能导致非常令人困惑的程序:

const café = 1;  // This constant is named "caf\u{e9}"
const café = 2;  // This constant is different: "cafe\u{301}"
café  // => 1: this constant has one value
café  // => 2: this indistinguishable constant has a different value

Unicode 标准定义了所有字符的首选编码,并指定了一种规范化过程,将文本转换为适合比较的规范形式。JavaScript 假定它正在解释的源代码已经被规范化,并且会自行进行任何规范化。如果您计划在 JavaScript 程序中使用 Unicode 字符,您应确保您的编辑器或其他工具对源代码执行 Unicode 规范化,以防止您最终得到不同但在视觉上无法区分的标识符。

2.6 可选分号

像许多编程语言一样,JavaScript 使用分号(;)来分隔语句(参见第五章)。这对于使代码的含义清晰很重要:没有分隔符,一个语句的结尾可能看起来是下一个语句的开头,反之亦然。在 JavaScript 中,如果两个语句写在不同行上,通常可以省略这两个语句之间的分号。(如果程序的下一个标记是闭合大括号},也可以省略分号。)许多 JavaScript 程序员(以及本书中的代码)使用分号明确标记语句的结尾,即使不需要也是如此。另一种风格是尽可能省略分号,只在需要时使用。无论你选择哪种风格,都应该了解 JavaScript 中可选分号的一些细节。

考虑以下代码。由于两个语句出现在不同行上,第一个分号可以省略:

a = 3;
b = 4;

然而,按照以下方式书写,第一个分号是必需的:

a = 3; b = 4;

请注意,JavaScript 并不会将每个换行符都视为分号:通常只有在无法解析代码而需要添加隐式分号时,才会将换行符视为分号。更正式地说(稍后描述的三个例外情况),如果下一个非空格字符无法被解释为当前语句的延续,JavaScript 将换行符视为分号。考虑以下代码:

let a
a
=
3
console.log(a)

JavaScript 解释这段代码如下:

let a; a = 3; console.log(a);

JavaScript 将第一个换行符视为分号,因为它无法解析不带分号的代码let a a。第二个a可以作为语句a;独立存在,但 JavaScript 不会将第二个换行符视为分号,因为它可以继续解析较长的语句a = 3;

这些语句终止规则会导致一些令人惊讶的情况。这段代码看起来像是两个用换行符分隔的独立语句:

let y = x + f
(a+b).toString()

但是代码的第二行括号可以被解释为从第一行调用f的函数调用,JavaScript 会这样解释代码:

let y = x + f(a+b).toString();

很可能这并不是代码作者打算的解释。为了作为两个独立语句工作,这种情况下需要一个显式分号。

一般来说,如果语句以([/+-开头,那么它可能被解释为前一个语句的延续。以/+-开头的语句在实践中相当罕见,但以([开头的语句在某些 JavaScript 编程风格中并不罕见。一些程序员喜欢在这类语句的开头放置一个防御性分号,以便即使修改了其前面的语句并删除了先前的分号,它仍将正确工作:

let x = 0                         // Semicolon omitted here
;[x,x+1,x+2].forEach(console.log) // Defensive ; keeps this statement separate

有三个例外情况不符合 JavaScript 将换行符解释为分号的一般规则,即当它无法将第二行解析为第一行语句的延续时。第一个例外涉及returnthrowyieldbreakcontinue语句(参见第五章)。这些语句通常是独立的,但有时会跟随标识符或表达式。如果这些单词之后(在任何其他标记之前)出现换行符,JavaScript 将始终将该换行符解释为分号。例如,如果你写:

return
true;

JavaScript 假设你的意思是:

return; true;

然而,你可能的意思是:

return true;

这意味着你不能在returnbreakcontinue与后面的表达式之间插入换行符。如果插入换行符,你的代码很可能会以难以调试的非明显方式失败。

第二个例外涉及++−−运算符(§4.8)。这些运算符可以是前缀运算符,出现在表达式之前,也可以是后缀运算符,出现在表达式之后。如果要将这些运算符之一用作后缀运算符,它们必须出现在应用于的表达式的同一行上。第三个例外涉及使用简洁的“箭头”语法定义的函数:=>箭头本身必须出现在参数列表的同一行上。

2.7 总结

本章展示了 JavaScript 程序是如何在最低级别编写的。下一章将带我们迈向更高一级,并介绍作为 JavaScript 程序计算的基本单位的原始类型和值(数字、字符串等)。

第三章:类型、值和变量

计算机程序通过操作值来工作,例如数字 3.14 或文本“Hello World”。在编程语言中可以表示和操作的值的种类称为类型,编程语言的最基本特征之一是它支持的类型集合。当程序需要保留一个值以供将来使用时,它将该值分配给(或“存储”在)一个变量中。变量有名称,并且允许在我们的程序中使用这些名称来引用值。变量的工作方式是任何编程语言的另一个基本特征。本章解释了 JavaScript 中的类型、值和变量。它从概述和一些定义开始。

3.1 概述和定义

JavaScript 类型可以分为两类:原始类型对象类型。JavaScript 的原始类型包括数字、文本字符串(称为字符串)和布尔真值(称为布尔值)。本章的重要部分详细解释了 JavaScript 中的数字(§3.2)和字符串(§3.3)类型。布尔值在§3.4 中介绍。

特殊的 JavaScript 值 nullundefined 是原始值,但它们不是数字、字符串或布尔值。每个值通常被认为是其自己特殊类型的唯一成员。关于 nullundefined 的更多内容请参见§3.5。ES6 添加了一种新的特殊类型,称为 Symbol,它可以在不影响向后兼容性的情况下定义语言扩展。Symbols 在§3.6 中简要介绍。

任何不是数字、字符串、布尔值、符号、nullundefined 的 JavaScript 值都是对象。对象(即类型 object 的成员)是一个属性集合,其中每个属性都有一个名称和一个值(可以是原始值或另一个对象)。一个非常特殊的对象,全局对象,在§3.7 中介绍,但是一般和更详细的对象覆盖在第六章中。

一个普通的 JavaScript 对象是一个无序的命名值集合。该语言还定义了一种特殊类型的对象,称为数组,表示一个有序的编号值集合。JavaScript 语言包括特殊的语法用于处理数组,并且数组具有一些特殊的行为,使它们与普通对象有所区别。数组是第七章的主题。

除了基本对象和数组之外,JavaScript 还定义了许多其他有用的对象类型。Set 对象表示一组值。Map 对象表示从键到值的映射。各种“类型化数组”类型便于对字节数组和其他二进制数据进行操作。RegExp 类型表示文本模式,并支持对字符串进行复杂的匹配、搜索和替换操作。Date 类型表示日期和时间,并支持基本的日期算术。Error 及其子类型表示执行 JavaScript 代码时可能出现的错误。所有这些类型在第十一章中介绍。

JavaScript 与更静态的语言不同之处在于函数和类不仅仅是语言语法的一部分:它们本身是 JavaScript 程序可以操作的值。与任何不是原始值的 JavaScript 值一样,函数和类是一种特殊类型的对象。它们在第八章和第九章中详细介绍。

JavaScript 解释器执行自动垃圾回收以进行内存管理。这意味着 JavaScript 程序员通常不需要担心对象或其他值的销毁或释放。当一个值不再可达时——当程序不再有任何方式引用它时——解释器知道它永远不会再被使用,并自动回收它占用的内存。(JavaScript 程序员有时需要小心确保值不会意外地保持可达——因此不可回收——时间比必要长。)

JavaScript 支持面向对象的编程风格。宽松地说,这意味着与其在全局定义函数来操作各种类型的值,类型本身定义了用于处理值的方法。例如,要对数组a的元素进行排序,我们不会将a传递给sort()函数。相反,我们调用asort()方法:

a.sort();       // The object-oriented version of sort(a).

方法定义在第九章中介绍。技术上,只有 JavaScript 对象有方法。但是数字、字符串、布尔值和符号值的行为就好像它们有方法一样。在 JavaScript 中,只有nullundefined是不能调用方法的值。

JavaScript 的对象类型是可变的,而其原始类型是不可变的。可变类型的值可以改变:JavaScript 程序可以更改对象属性和数组元素的值。数字、布尔值、符号、nullundefined是不可变的——例如,谈论更改数字的值甚至没有意义。字符串可以被视为字符数组,你可能期望它们是可变的。然而,在 JavaScript 中,字符串是不可变的:你可以访问字符串的任何索引处的文本,但 JavaScript 没有提供一种方法来更改现有字符串的文本。可变和不可变值之间的差异在§3.8 中进一步探讨。

JavaScript 自由地将一个类型的值转换为另一个类型。例如,如果一个程序期望一个字符串,而你给了它一个数字,它会自动为你将数字转换为字符串。如果你在期望布尔值的地方使用了非布尔值,JavaScript 会相应地进行转换。值转换的规则在§3.9 中解释。JavaScript 自由的值转换规则影响了它对相等性的定义,==相等运算符执行如§3.9.1 中描述的类型转换。(然而,在实践中,==相等运算符已被弃用,而是使用严格相等运算符===,它不进行类型转换。有关这两个运算符的更多信息,请参见§4.9.1。)

常量和变量允许您在程序中使用名称引用值。常量使用const声明,变量使用let声明(或在旧的 JavaScript 代码中使用var)。JavaScript 的常量和变量是无类型的:声明不指定将分配什么类型的值。变量声明和赋值在§3.10 中介绍。

从这个长篇介绍中可以看出,这是一个涵盖广泛的章节,解释了 JavaScript 中数据如何表示和操作的许多基本细节。我们将从直接深入讨论 JavaScript 数字和文本的细节开始。

3.2 数字

JavaScript 的主要数值类型 Number 用于表示整数和近似实数。JavaScript 使用 IEEE 754 标准定义的 64 位浮点格式表示数字,¹这意味着它可以表示大约±1.7976931348623157 × 10³⁰⁸和小约±5 × 10^(−324)的数字。

JavaScript 数字格式允许您精确表示介于−9,007,199,254,740,992(−2⁵³)和 9,007,199,254,740,992(2⁵³)之间的所有整数,包括这两个数。如果使用大于此值的整数值,可能会失去尾数的精度。但请注意,JavaScript 中的某些操作(如数组索引和第四章中描述的位运算符)是使用 32 位整数执行的。如果需要精确表示更大的整数,请参阅§3.2.5。

当一个数字直接出现在 JavaScript 程序中时,它被称为数字文字。JavaScript 支持几种格式的数字文字,如下面的部分所述。请注意,任何数字文字都可以在前面加上减号(-)以使数字为负数。

3.2.1 整数文字

在 JavaScript 程序中,十进制整数被写为数字序列。例如:

0
3
10000000

除了十进制整数文字,JavaScript 还识别十六进制(基数 16)值。十六进制文字以0x0X开头,后跟一串十六进制数字。十六进制数字是数字 0 到 9 或字母 a(或 A)到 f(或 F)中的一个,表示值 10 到 15。以下是十六进制整数文字的示例:

0xff       // => 255: (15*16 + 15)
0xBADCAFE  // => 195939070

在 ES6 及更高版本中,你还可以使用前缀0b0o(或0B0O)来表示二进制(基数 2)或八进制(基数 8)中的整数,而不是0x

0b10101  // => 21:  (1*16 + 0*8 + 1*4 + 0*2 + 1*1)
0o377    // => 255: (3*64 + 7*8 + 7*1)

3.2.2 浮点数文字

浮点文字可以有小数点;它们使用实数的传统语法。一个实数由数字的整数部分表示,后跟一个小数点和数字的小数部分。

浮点文字也可以使用指数表示法表示:一个实数后跟字母 e(或 E),后跟一个可选的加号或减号,后跟一个整数指数。这种表示法表示实数乘以 10 的指数次幂。

更简洁地说,语法是:

[*`digits`*][.*`digits`*][(E|e)[(+|-)]*`digits`*]

例如:

3.14
2345.6789
.333333333333333333
6.02e23        // 6.02 × 10²³
1.4738223E-32  // 1.4738223 × 10⁻³²

3.2.3 JavaScript 中的算术

JavaScript 程序使用语言提供的算术运算符与数字一起工作。这些包括+用于加法,-用于减法,*用于乘法,/用于除法,%用于取模(除法后的余数)。ES2016 添加了**用于指数运算。关于这些和其他运算符的详细信息可以在第四章中找到。

除了这些基本算术运算符外,JavaScript 通过一组函数和常量定义为Math对象的属性支持更复杂的数学运算:

Math.pow(2,53)           // => 9007199254740992: 2 to the power 53
Math.round(.6)           // => 1.0: round to the nearest integer
Math.ceil(.6)            // => 1.0: round up to an integer
Math.floor(.6)           // => 0.0: round down to an integer
Math.abs(-5)             // => 5: absolute value
Math.max(x,y,z)          // Return the largest argument
Math.min(x,y,z)          // Return the smallest argument
Math.random()            // Pseudo-random number x where 0 <= x < 1.0
Math.PI                  // π: circumference of a circle / diameter
Math.E                   // e: The base of the natural logarithm
Math.sqrt(3)             // => 3**0.5: the square root of 3
Math.pow(3, 1/3)         // => 3**(1/3): the cube root of 3
Math.sin(0)              // Trigonometry: also Math.cos, Math.atan, etc.
Math.log(10)             // Natural logarithm of 10
Math.log(100)/Math.LN10  // Base 10 logarithm of 100
Math.log(512)/Math.LN2   // Base 2 logarithm of 512
Math.exp(3)              // Math.E cubed

ES6 在Math对象上定义了更多函数:

Math.cbrt(27)    // => 3: cube root
Math.hypot(3, 4) // => 5: square root of sum of squares of all arguments
Math.log10(100)  // => 2: Base-10 logarithm
Math.log2(1024)  // => 10: Base-2 logarithm
Math.log1p(x)    // Natural log of (1+x); accurate for very small x
Math.expm1(x)    // Math.exp(x)-1; the inverse of Math.log1p()
Math.sign(x)     // -1, 0, or 1 for arguments <, ==, or > 0
Math.imul(2,3)   // => 6: optimized multiplication of 32-bit integers
Math.clz32(0xf)  // => 28: number of leading zero bits in a 32-bit integer
Math.trunc(3.9)  // => 3: convert to an integer by truncating fractional part
Math.fround(x)   // Round to nearest 32-bit float number
Math.sinh(x)     // Hyperbolic sine. Also Math.cosh(), Math.tanh()
Math.asinh(x)    // Hyperbolic arcsine. Also Math.acosh(), Math.atanh()

JavaScript 中的算术运算不会在溢出、下溢或除以零的情况下引发错误。当数值运算的结果大于最大可表示的数(溢出)时,结果是一个特殊的无穷大值,Infinity。同样,当负值的绝对值变得大于最大可表示的负数的绝对值时,结果是负无穷大,-Infinity。无穷大值的行为如你所期望的那样:将它们相加、相减、相乘或相除的结果是一个无穷大值(可能带有相反的符号)。

下溢发生在数值运算的结果接近零而不是最小可表示数时。在这种情况下,JavaScript 返回 0。如果下溢发生在负数中,JavaScript 返回一个称为“负零”的特殊值。这个值几乎与普通零完全无法区分,JavaScript 程序员很少需要检测它。

在 JavaScript 中,除以零不会导致错误:它只是返回正无穷大或负无穷大。然而,有一个例外:零除以零没有明确定义的值,这个操作的结果是特殊的非数字值 NaN。如果尝试将无穷大除以无穷大、对负数取平方根或使用无法转换为数字的非数字操作数进行算术运算,也会产生 NaN

JavaScript 预定义全局常量 InfinityNaN 分别表示正无穷大和非数字值,并且这些值也作为 Number 对象的属性可用:

Infinity                    // A positive number too big to represent
Number.POSITIVE_INFINITY    // Same value
1/0                         // => Infinity
Number.MAX_VALUE * 2        // => Infinity; overflow
-Infinity                   // A negative number too big to represent
Number.NEGATIVE_INFINITY    // The same value
-1/0                        // => -Infinity
-Number.MAX_VALUE * 2       // => -Infinity
NaN                         // The not-a-number value
Number.NaN                  // The same value, written another way
0/0                         // => NaN
Infinity/Infinity           // => NaN
Number.MIN_VALUE/2          // => 0: underflow
-Number.MIN_VALUE/2         // => -0: negative zero
-1/Infinity                 // -> -0: also negative 0
-0
// The following Number properties are defined in ES6
Number.parseInt()       // Same as the global parseInt() function
Number.parseFloat()     // Same as the global parseFloat() function
Number.isNaN(x)         // Is x the NaN value?
Number.isFinite(x)      // Is x a number and finite?
Number.isInteger(x)     // Is x an integer?
Number.isSafeInteger(x) // Is x an integer -(2**53) < x < 2**53?
Number.MIN_SAFE_INTEGER // => -(2**53 - 1)
Number.MAX_SAFE_INTEGER // => 2**53 - 1
Number.EPSILON          // => 2**-52: smallest difference between numbers

JavaScript 权威指南第七版(GPT 重译)(一)(3)https://developer.aliyun.com/article/1485288

相关文章
|
4月前
|
存储 SQL 数据库
Python 金融编程第二版(GPT 重译)(四)(4)
Python 金融编程第二版(GPT 重译)(四)
50 3
|
4月前
|
存储 NoSQL 索引
Python 金融编程第二版(GPT 重译)(一)(4)
Python 金融编程第二版(GPT 重译)(一)
61 2
|
4月前
|
索引 Python
Python 金融编程第二版(GPT 重译)(二)(4)
Python 金融编程第二版(GPT 重译)(二)
31 0
|
4月前
|
存储 SQL 数据可视化
Python 金融编程第二版(GPT 重译)(二)(3)
Python 金融编程第二版(GPT 重译)(二)
44 0
|
4月前
|
JavaScript 前端开发 程序员
《JavaScript权威指南第7版》中文PDF+英文PDF+源代码 +JavaScript权威指南(第6版)(附源码)PDF下载阅读分享推荐
JavaScript是Web标准语言,广泛应用于各类浏览器,造就了其最广泛部署的地位。Node.js的兴起扩展了JavaScript的使用场景,使其成为开发者首选语言。无论新手还是经验丰富的程序员,都能受益于学习JavaScript。[《JavaScript权威指南第7版》资源链接](https://zhangfeidezhu.com/?p=224)
273 5
《JavaScript权威指南第7版》中文PDF+英文PDF+源代码 +JavaScript权威指南(第6版)(附源码)PDF下载阅读分享推荐
|
4月前
|
存储 机器学习/深度学习 关系型数据库
Python 金融编程第二版(GPT 重译)(四)(5)
Python 金融编程第二版(GPT 重译)(四)
35 2
|
4月前
|
存储 SQL 数据可视化
Python 金融编程第二版(GPT 重译)(四)(1)
Python 金融编程第二版(GPT 重译)(四)
47 2
|
4月前
|
数据可视化 Python
Python 金融编程第二版(GPT 重译)(三)(4)
Python 金融编程第二版(GPT 重译)(三)
27 2
|
4月前
|
存储 算法 数据可视化
Python 金融编程第二版(GPT 重译)(一)(1)
Python 金融编程第二版(GPT 重译)(一)
89 1
|
4月前
|
SQL 存储 数据库
Python 金融编程第二版(GPT 重译)(四)(3)
Python 金融编程第二版(GPT 重译)(四)
41 1