数字和日期

本章介绍了在 JavaScript 中使用数字和日期进行处理和执行计算的概念、对象和函数。这包括使用以十进制、二进制和十六进制等各种基数编写的数字,以及使用全局 Math 对象对数字执行各种数学运算。

¥This chapter introduces the concepts, objects and functions used to work with and perform calculations using numbers and dates in JavaScript. This includes using numbers written in various bases including decimal, binary, and hexadecimal, as well as the use of the global Math object to perform a wide variety of mathematical operations on numbers.

数字

¥Numbers

在 JavaScript 中,数字以 双精度 64 位二进制格式 IEEE 754 实现(即 ±2^−1022 和 ±2^+1023 之间的数字,或大约 ±10^−308 到 ±10^+308,数字精度为 53 位)。可以精确表示 ±2^53 − 1 以内的整数值。

¥In JavaScript, numbers are implemented in double-precision 64-bit binary format IEEE 754 (i.e., a number between ±2^−1022 and ±2^+1023, or about ±10^−308 to ±10^+308, with a numeric precision of 53 bits). Integer values up to ±2^53 − 1 can be represented exactly.

除了能够表示浮点数之外,数字类型还具有三个符号值:+ {jsxref("Infinity")} }、-InfinityNaN(非数字)。

¥In addition to being able to represent floating-point numbers, the number type has three symbolic values: +Infinity, -Infinity, and NaN (not-a-number).

另请参阅 JavaScript 数据类型和结构 了解 JavaScript 中其他基本类型的上下文。

¥See also JavaScript data types and structures for context with other primitive types in JavaScript.

你可以使用四种类型的数字文字:十进制、二进制、八进制和十六进制。

¥You can use four types of number literals: decimal, binary, octal, and hexadecimal.

小数

¥Decimal numbers

js
1234567890
42

十进制文字可以以零 (0) 开头,后跟另一个十进制数字,但如果前导 0 之后的所有数字都小于 8,则该数字将被解释为八进制数。这被认为是旧语法,以 0 为前缀的数字文字,无论解释为八进制还是十进制,都会导致 严格模式 出现语法错误 - 因此,请改用 0o 前缀。

¥Decimal literals can start with a zero (0) followed by another decimal digit, but if all digits after the leading 0 are smaller than 8, the number is interpreted as an octal number. This is considered a legacy syntax, and number literals prefixed with 0, whether interpreted as octal or decimal, cause a syntax error in strict mode — so, use the 0o prefix instead.

js
0888 // 888 parsed as decimal
0777 // parsed as octal, 511 in decimal

二进制数

¥Binary numbers

二进制数语法使用前导零,后跟小写或大写拉丁字母 "B"(0b0B)。如果 0b 后面的数字不是 0 或 1,则抛出以下 SyntaxError:"0b 后缺少二进制数字"。

¥Binary number syntax uses a leading zero followed by a lowercase or uppercase Latin letter "B" (0b or 0B). If the digits after the 0b are not 0 or 1, the following SyntaxError is thrown: "Missing binary digits after 0b".

js
0b10000000000000000000000000000000 // 2147483648
0b01111111100000000000000000000000 // 2139095040
0B00000000011111111111111111111111 // 8388607

八进制数

¥Octal numbers

八进制数的标准语法是在它们前面加上 0o 前缀。例如:

¥The standard syntax for octal numbers is to prefix them with 0o. For example:

js
0O755 // 493
0o644 // 420

还有一种八进制数的旧语法 - 在八进制数前面加上零:0644 === 420"\045" === "%"。如果 0 之后的数字超出 0 到 7 的范围,则该数字将被解释为十进制数。

¥There's also a legacy syntax for octal numbers — by prefixing the octal number with a zero: 0644 === 420 and "\045" === "%". If the digits after the 0 are outside the range 0 through 7, the number will be interpreted as a decimal number.

js
const n = 0755; // 493
const m = 0644; // 420

严格模式 禁止这种八进制语法。

¥Strict mode forbids this octal syntax.

十六进制数

¥Hexadecimal numbers

十六进制数字语法使用前导零,后跟小写或大写拉丁字母 "X"(0x0X)。如果 0x 后面的数字超出范围 (0123456789ABCDEF),则会抛出以下 SyntaxError:"标识符紧随数字文字之后开始"。

¥Hexadecimal number syntax uses a leading zero followed by a lowercase or uppercase Latin letter "X" (0x or 0X). If the digits after 0x are outside the range (0123456789ABCDEF), the following SyntaxError is thrown: "Identifier starts immediately after numeric literal".

js
0xFFFFFFFFFFFFFFFFF // 295147905179352830000
0x123456789ABCDEF   // 81985529216486900
0XA                 // 10

求幂

¥Exponentiation

js
0e-5   // 0
0e+5   // 0
5e1    // 50
175e-2 // 1.75
1e3    // 1000
1e-3   // 0.001
1E3    // 1000

数字对象

¥Number object

内置 Number 对象具有数值常量的属性,例如最大值、非数字和无穷大。你无法更改这些属性的值,并且可以按如下方式使用它们:

¥The built-in Number object has properties for numerical constants, such as maximum value, not-a-number, and infinity. You cannot change the values of these properties and you use them as follows:

js
const biggestNum = Number.MAX_VALUE;
const smallestNum = Number.MIN_VALUE;
const infiniteNum = Number.POSITIVE_INFINITY;
const negInfiniteNum = Number.NEGATIVE_INFINITY;
const notANum = Number.NaN;

你始终引用如上所示的预定义 Number 对象的属性,而不是你自己创建的 Number 对象的属性。

¥You always refer to a property of the predefined Number object as shown above, and not as a property of a Number object you create yourself.

下表总结了 Number 对象的属性。

¥The following table summarizes the Number object's properties.

属性 描述
Number.MAX_VALUE 可表示的最大正数 (1.7976931348623157e+308)
Number.MIN_VALUE 可表示的最小正数 (5e-324)
Number.NaN 特殊 "不是一个数字" 值
Number.NEGATIVE_INFINITY 特殊负无穷值;溢出时返回
Number.POSITIVE_INFINITY 特别正无限值;溢出时返回
Number.EPSILON 1 与可表示为 Number (2.220446049250313e-16) 的大于 1 的最小值之间的差
Number.MIN_SAFE_INTEGER JavaScript 中的最小安全整数(−2^53 + 1,或 −9007199254740991
Number.MAX_SAFE_INTEGER JavaScript 中的最大安全整数(+2^53 − 1,或 +9007199254740991
方法 描述
Number.parseFloat() 解析字符串参数并返回浮点数。与全局 parseFloat() 功能相同。
Number.parseInt() 解析字符串参数并返回指定基数或基数的整数。与全局 parseInt() 功能相同。
Number.isFinite() 确定传递的值是否是有限数。
Number.isInteger() 确定传递的值是否为整数。
Number.isNaN() 判断传入的值是否为 NaN。原始全球 isNaN() 的更强大版本。
Number.isSafeInteger() 确定提供的值是否是安全整数。

Number 原型提供了从各种格式的 Number 对象中检索信息的方法。下表总结了 Number.prototype 的方法。

¥The Number prototype provides methods for retrieving information from Number objects in various formats. The following table summarizes the methods of Number.prototype.

方法 描述
toExponential() 返回以指数表示法表示数字的字符串。
toFixed() 返回以定点表示法表示数字的字符串。
toPrecision() 返回一个字符串,以定点表示法表示指定精度的数字。

数学对象

¥Math object

内置 Math 对象具有数学常量和函数的属性和方法。例如,Math 对象的 PI 属性的值为 pi (3.141…),你可以在应用中将其用作

¥The built-in Math object has properties and methods for mathematical constants and functions. For example, the Math object's PI property has the value of pi (3.141…), which you would use in an application as

js
Math.PI;

同样,标准数学函数是 Math 的方法。这些包括三角函数、对数函数、指数函数和其他函数。例如,如果你想使用三角函数正弦,你可以写

¥Similarly, standard mathematical functions are methods of Math. These include trigonometric, logarithmic, exponential, and other functions. For example, if you want to use the trigonometric function sine, you would write

js
Math.sin(1.56);

请注意,Math 的所有三角方法均采用弧度参数。

¥Note that all trigonometric methods of Math take arguments in radians.

下表总结了 Math 对象的方法。

¥The following table summarizes the Math object's methods.

Methods of Math
方法 描述
abs() 绝对值
sin(), cos(), tan() 标准三角函数;以弧度为单位的参数。
asin(), acos(), atan(), atan2() 反三角函数;返回以弧度为单位的值。
sinh(), cosh(), tanh() 双曲函数;双曲角论证。
asinh(), acosh(), atanh() 反双曲函数;返回双曲角值。

pow(), exp(), expm1(), log(), log10(), log1p(), log2()

指数和对数函数。
floor()ceil() 返回小于/大于或等于参数的最大/最小整数。
min()max() 返回以逗号分隔的数字列表的最小值或最大值作为参数。
random() 返回 0 到 1 之间的随机数。
round(), fround(), trunc(), 舍入和截断函数。
sqrt(), cbrt(), hypot() 平方根、立方根、平方参数之和的平方根。
sign() 数字的符号,指示该数字是正数、负数还是零。
clz32()
imul()
32 位二进制表示中前导零位数。
两个参数的类似 C 32 位乘法的结果。

与许多其他对象不同,你永远不会创建自己的 Math 对象。你始终使用内置 Math 对象。

¥Unlike many other objects, you never create a Math object of your own. You always use the built-in Math object.

BigInts

数值的一个缺点是它们只有 64 位。实际上,由于使用 IEEE 754 编码,它们无法准确表示任何大于 Number.MAX_SAFE_INTEGER(即 253 - 1)的整数。为了解决编码二进制数据的需要并与提供宽整数(例如 i64(64 位整数)和 i128(128 位整数))的其他语言进行互操作,JavaScript 还提供了另一种数据类型来表示任意大整数:BigInt

¥One shortcoming of number values is they only have 64 bits. In practice, due to using IEEE 754 encoding, they cannot represent any integer larger than Number.MAX_SAFE_INTEGER (which is 253 - 1) accurately. To solve the need of encoding binary data and to interoperate with other languages that offer wide integers like i64 (64-bit integers) and i128 (128-bit integers), JavaScript also offers another data type to represent arbitrarily large integers: BigInt.

BigInt 可以定义为以 n 为后缀的整数文字:

¥A BigInt can be defined as an integer literal suffixed by n:

js
const b1 = 123n;
// Can be arbitrarily large.
const b2 = -1234567890987654321n;

BigInt 还可以使用 BigInt 构造函数从数字值或字符串值构造。

¥BigInts can also be constructed from number values or string values using the BigInt constructor.

js
const b1 = BigInt(123);
// Using a string prevents loss of precision, since long number
// literals don't represent what they seem like.
const b2 = BigInt("-1234567890987654321");

从概念上讲,BigInt 只是编码整数的任意长的位序列。你可以安全地进行任何算术运算,而不会丢失精度或上溢/下溢。

¥Conceptually, a BigInt is just an arbitrarily long sequence of bits which encodes an integer. You can safely do any arithmetic operations without losing precision or over-/underflowing.

js
const integer = 12 ** 34; // 4.9222352429520264e+36; only has limited precision
const bigint = 12n ** 34n; // 4922235242952026704037113243122008064n

与数字相比,BigInt 值在表示大整数时具有更高的精度;但是,它们不能表示浮点数。例如,除法将舍入为零:

¥Compared to numbers, BigInt values yield higher precision when representing large integers; however, they cannot represent floating-point numbers. For example, division would round to zero:

js
const bigintDiv = 5n / 2n; // 2n, because there's no 2.5 in BigInt

Math 函数不能用于 BigInt 值。公开提案 可以重载某些 Math 函数,例如 Math.max() 以允许使用 BigInt 值。

¥Math functions cannot be used on BigInt values. There is an open proposal to overload certain Math functions like Math.max() to allow BigInt values.

在 BigInt 和 number 之间进行选择取决于你的用例和输入范围。数字的精度应该能够满足大多数日常任务,并且 BigInt 最适合处理二进制数据。

¥Choosing between BigInt and number depends on your use-case and your input's range. The precision of numbers should be able to accommodate most day-to-day tasks already, and BigInts are most suitable for handling binary data.

阅读 表达式和运算符 部分或 BigInt 参考 中有关可以使用 BigInt 值执行的操作的更多信息。

¥Read more about what you can do with BigInt values in the Expressions and Operators section, or the BigInt reference.

日期对象

¥Date object

JavaScript 没有日期数据类型。但是,你可以使用 Date 对象及其方法来处理应用中的日期和时间。Date 对象有大量用于设置、获取和操作日期的方法。它没有任何属性。

¥JavaScript does not have a date data type. However, you can use the Date object and its methods to work with dates and times in your applications. The Date object has a large number of methods for setting, getting, and manipulating dates. It does not have any properties.

JavaScript 处理日期的方式与 Java 类似。这两种语言具有许多相同的日期方法,并且两种语言都将日期存储为自 UTC 1970 年 1 月 1 日午夜开始以来的毫秒数,而 Unix 时间戳则表示自同一时刻以来的秒数。1970 年 1 月 1 日午夜时分,UTC 称为 epoch

¥JavaScript handles dates similarly to Java. The two languages have many of the same date methods, and both languages store dates as the number of milliseconds since midnight at the beginning of January 1, 1970, UTC, with a Unix Timestamp being the number of seconds since the same instant. The instant at the midnight at the beginning of January 1, 1970, UTC is called the epoch.

Date 对象范围是相对于纪元的 -100,000,000 天到 100,000,000 天。

¥The Date object range is -100,000,000 days to 100,000,000 days relative to the epoch.

要创建 Date 对象:

¥To create a Date object:

js
const dateObjectName = new Date([parameters]);

其中 dateObjectName 是正在创建的 Date 对象的名称;它可以是一个新对象或现有对象的属性。

¥where dateObjectName is the name of the Date object being created; it can be a new object or a property of an existing object.

不使用 new 关键字调用 Date 将返回表示当前日期和时间的字符串。

¥Calling Date without the new keyword returns a string representing the current date and time.

上述语法中的 parameters 可以是以下任意一种:

¥The parameters in the preceding syntax can be any of the following:

  • 没有什么:创建今天的日期和时间。例如,today = new Date();
  • 代表日期的字符串,有多种不同的形式。不同引擎支持的具体形式有所不同,但始终支持以下形式:YYYY-MM-DDTHH:mm:ss.sssZ。例如,xmas95 = new Date("1995-12-25")。如果省略小时、分钟或秒,该值将设置为零。
  • 年、月、日的一组整数值。例如,xmas95 = new Date(1995, 11, 25)
  • 年、月、日、小时、分钟和秒的一组整数值。例如,xmas95 = new Date(1995, 11, 25, 9, 30, 0);

Date 对象的方法

¥Methods of the Date object

用于处理日期和时间的 Date 对象方法分为以下几类:

¥The Date object methods for handling dates and times fall into these broad categories:

  • "set" 方法,用于在 Date 对象中设置日期和时间值。
  • "get" 方法,用于从 Date 对象获取日期和时间值。
  • "to" 方法,用于从 Date 对象返回字符串值。
  • parse 和 UTC 方法,用于解析 Date 字符串。

使用 "get" 和 "set" 方法,你可以分别获取和设置秒、分钟、小时、月份中的某一天、星期几、月份和年份。有一个 getDay 方法返回星期几,但没有相应的 setDay 方法,因为星期几是自动设置的。这些方法使用整数来表示这些值,如下所示:

¥With the "get" and "set" methods you can get and set seconds, minutes, hours, day of the month, day of the week, months, and years separately. There is a getDay method that returns the day of the week, but no corresponding setDay method, because the day of the week is set automatically. These methods use integers to represent these values as follows:

  • 秒和分钟:0 至 59
  • 小时:0 至 23
  • 天:0(星期日)至 6(星期六)
  • 日期:1 到 31(一个月中的某天)
  • 月份:0(一月)至 11(十二月)
  • 年:自 1900 年以来

例如,假设你定义以下日期:

¥For example, suppose you define the following date:

js
const xmas95 = new Date("1995-12-25");

然后 xmas95.getMonth() 返回 11,xmas95.getFullYear() 返回 1995。

¥Then xmas95.getMonth() returns 11, and xmas95.getFullYear() returns 1995.

getTimesetTime 方法对于比较日期很有用。getTime 方法返回 Date 对象自纪元以来的毫秒数。

¥The getTime and setTime methods are useful for comparing dates. The getTime method returns the number of milliseconds since the epoch for a Date object.

例如,以下代码显示当前年份剩余的天数:

¥For example, the following code displays the number of days left in the current year:

js
const today = new Date();
const endYear = new Date(1995, 11, 31, 23, 59, 59, 999); // Set day and month
endYear.setFullYear(today.getFullYear()); // Set year to this year
const msPerDay = 24 * 60 * 60 * 1000; // Number of milliseconds per day
let daysLeft = (endYear.getTime() - today.getTime()) / msPerDay;
daysLeft = Math.round(daysLeft); // Returns days left in the year

此示例创建一个名为 todayDate 对象,其中包含今天的日期。然后,它创建一个名为 endYearDate 对象,并将年份设置为当前年份。然后,使用每天的毫秒数,计算 todayendYear 之间的天数,使用 getTime 并四舍五入到整数天数。

¥This example creates a Date object named today that contains today's date. It then creates a Date object named endYear and sets the year to the current year. Then, using the number of milliseconds per day, it computes the number of days between today and endYear, using getTime and rounding to a whole number of days.

parse 方法对于将日期字符串中的值分配给现有 Date 对象非常有用。例如,以下代码使用 parsesetTime 将日期值分配给 ipoDate 对象:

¥The parse method is useful for assigning values from date strings to existing Date objects. For example, the following code uses parse and setTime to assign a date value to the ipoDate object:

js
const ipoDate = new Date();
ipoDate.setTime(Date.parse("Aug 9, 1995"));

示例

¥Example

在以下示例中,函数 JSClock() 以数字时钟的格式返回时间。

¥In the following example, the function JSClock() returns the time in the format of a digital clock.

js
function JSClock() {
  const time = new Date();
  const hour = time.getHours();
  const minute = time.getMinutes();
  const second = time.getSeconds();
  let temp = String(hour % 12);
  if (temp === "0") {
    temp = "12";
  }
  temp += (minute < 10 ? ":0" : ":") + minute;
  temp += (second < 10 ? ":0" : ":") + second;
  temp += hour >= 12 ? " P.M." : " A.M.";
  return temp;
}

JSClock 函数首先创建一个新的 Date 对象,名为 time;由于没有给出参数,因此时间是使用当前日期和时间创建的。然后调用 getHoursgetMinutesgetSeconds 方法将当前小时、分钟和秒的值分配给 hourminutesecond

¥The JSClock function first creates a new Date object called time; since no arguments are given, time is created with the current date and time. Then calls to the getHours, getMinutes, and getSeconds methods assign the value of the current hour, minute, and second to hour, minute, and second.

以下语句根据时间构建一个字符串值。第一条语句创建变量 temp。它的值为 hour % 12,在 12 小时制中是 hour。然后,如果小时为 0,则会重新分配给 12,以便午夜和中午显示为 12:00,而不是 0:00

¥The following statements build a string value based on the time. The first statement creates a variable temp. Its value is hour % 12, which is hour in the 12-hour system. Then, if the hour is 0, it gets re-assigned to 12, so that midnights and noons are displayed as 12:00 instead of 0:00.

下一条语句将 minute 值附加到 temp。如果 minute 的值小于 10,则条件表达式添加前面带有零的字符串;否则它会添加一个带有分界冒号的字符串。然后语句以相同的方式将秒值附加到 temp

¥The next statement appends a minute value to temp. If the value of minute is less than 10, the conditional expression adds a string with a preceding zero; otherwise it adds a string with a demarcating colon. Then a statement appends a seconds value to temp in the same way.

最后,如果 hour 为 12 或更大,则条件表达式将 "P.M." 附加到 temp;否则,它将 "A.M." 附加到 temp

¥Finally, a conditional expression appends "P.M." to temp if hour is 12 or greater; otherwise, it appends "A.M." to temp.