
2024-12-18 日报 Day39

今日的鸡汤
在哪里付出,就在哪里得到;在哪里打磨,就在哪里闪耀。
今日学习内容
1、JS红皮书P103-108 第五章:基本引用类型
今日笔记
1、对象被认为是某个特定引用类型的实例。新对象通过使用 new 操作符后跟一个构造函数(constructor)来创建。构造函数就是用来创建新对象的函数,比如下面这行代码:let now = new Date();函数也是一种引用类型。
2、Date 类型将日期保存为自协调世界时(UTC,Universal Time Coordinated)时间 1970 年 1 月 1 日午夜(零时)至今所经过的毫秒数。要创建日期对象,就使用 new 操作符来调用 Date 构造函数:
let now = new Date();
Date.parse()方法接收一个表示日期的字符串参数,尝试将这个字符串转换为表示该日期的毫秒数。ECMA-262 第 5 版定义了 Date.parse()应该支持的日期格式,填充了第 3 版遗留的空白。所有实现都必须支持下列日期格式:
“月/日/年”,如”5/23/2019”;
“月名 日, 年”,如”May 23, 2019”;
“周几 月名 日 年 时:分:秒 时区”,如”Tue May 23 2019 00:00:00 GMT-0700”;
ISO 8601 扩展格式“YYYY-MM-DDTHH:mm:ss.sssZ”,如 2019-05-23T00:00:00(只适用于兼容 ES5 的实现)。
比如,要创建一个表示“2019 年 5 月 23 日”的日期对象,可以使用以下代码:
let someDate = new Date(Date.parse(“May 23, 2019”));
如果传给 Date.parse()的字符串并不表示日期,则该方法会返回 NaN。如果直接把表示日期的字符串传给 Date 构造函数,那么 Date 会在后台调用 Date.parse()。换句话说,下面这行代码跟前面那行代码是等价的:
let someDate = new Date(“May 23, 2019”);
这两行代码得到的日期对象相同。
Date.UTC()方法也返回日期的毫秒表示,但使用的是跟 Date.parse()不同的信息来生成这个值。传给 Date.UTC()的参数是年、零起点月数(1 月是 0,2 月是 1,以此类推)、日(131)、时(023)、分、秒和毫秒。这些参数中,只有前两个(年和月)是必需的。如果不提供日,那么默认为 1 日。其他参数的默认值都是 0。下面是使用 Date.UTC()的两个例子:
// GMT 时间 2000 年 1 月 1 日零点
let y2k = new Date(Date.UTC(2000, 0));
// GMT 时间 2005 年 5 月 5 日下午 5 点 55 分 55 秒
let allFives = new Date(Date.UTC(2005, 4, 5, 17, 55, 55));
ECMAScript 还提供了 Date.now()方法,返回表示方法执行时日期和时间的毫秒数。这个方法可以方便地用在代码分析中:
// 起始时间
let start = Date.now();
// 调用函数
doSomething();
// 结束时间
let stop = Date.now(),
result = stop - start;
3、继承的方式:Date 类型重写了 toLocaleString()、toString()和 valueOf()方法。Date 类型的 toLocaleString()方法返回与浏览器运行的本地环境一致的日期和时间。这通常意味着格式中包含针对时间的 AM(上午)或 PM(下午),但不包含时区信息(具体格式可能因浏览器而不同)。toString()方法通常返回带时区信息的日期和时间,而时间也是以 24 小时制(0~23)表示的。下面给出了 toLocaleString()和 toString()返回的2019 年 2 月 1 日零点的示例(地区为”en-US”的 PST,即 Pacific Standard Time,太平洋标准时间):
toLocaleString() - 2/1/2019 12:00:00 AM
toString() - Thu Feb 1 2019 00:00:00 GMT-0800 (Pacific Standard Time)
现代浏览器在这两个方法的输出上已经趋于一致。在比较老的浏览器上,每个方法返回的结果可能在每个浏览器上都是不同的。这些差异意味着 toLocaleString()和 toString()可能只对调试有用,不能用于显示。
Date 类型的 valueOf()方法根本就不返回字符串,这个方法被重写后返回的是日期的毫秒表示。因此,操作符(如小于号和大于号)可以直接使用它返回的值。比如下面的例子:
let date1 = new Date(2019, 0, 1); // 2019 年 1 月 1 日
let date2 = new Date(2019, 1, 1); // 2019 年 2 月 1 日
console.log(date1 < date2); // true
console.log(date1 > date2); // false
4、日期格式化方法:
Date 类型有几个专门用于格式化日期的方法,它们都会返回字符串:
toDateString()显示日期中的周几、月、日、年(格式特定于实现);
toTimeString()显示日期中的时、分、秒和时区(格式特定于实现);
toLocaleDateString()显示日期中的周几、月、日、年(格式特定于实现和地区);
toLocaleTimeString()显示日期中的时、分、秒(格式特定于实现和地区);
toUTCString()显示完整的 UTC 日期(格式特定于实现)。
5、日期/时间组件方法:Date 类型剩下的方法(见下表)直接涉及取得或设置日期值的特定部分。注意表中“UTC 日期”,指的是没有时区偏移(将日期转换为 GMT)时的日期。
方法 | 说明 |
---|---|
getTime() | 返回日期的毫秒表示;与 valueOf()相同 |
setTime(milliseconds) | 设置日期的毫秒表示,从而修改整个日期 |
getFullYear() | 返回 4 位数年(即 2019 而不是 19) |
getUTCFullYear() | 返回 UTC 日期的 4 位数年 |
setFullYear(year) | 设置日期的年(year 必须是 4 位数) |
setUTCFullYear(year) | 设置 UTC 日期的年(year 必须是 4 位数) |
getMonth() | 返回日期的月(0 表示 1 月,11 表示 12 月) |
getUTCMonth() | 返回 UTC 日期的月(0 表示 1 月) |
setMonth(month) | 设置日期的月(0 表示 1 月,11 表示 12 月) |
setUTCMonth(month) | 设置 UTC 日期的月(0 表示 1 月,11 表示 12 月) |
getDate() | 返回日期的日(月中的某一天) |
getUTCDate() | 返回 UTC 日期的日(月中的某一天) |
setDate(date) | 设置日期的日(月中的某一天) |
setUTCDate(date) | 设置 UTC 日期的日(月中的某一天) |
getDay() | 返回日期中的星期几(0 表示星期日,6 表示星期六) |
getUTCDay() | 返回 UTC 日期中的星期几(0 表示星期日,6 表示星期六) |
getHours() | 返回日期的小时(0~23) |
getUTCHours() | 返回 UTC 日期的小时(0~23) |
setHours(hours) | 设置日期的小时(0~23) |
setUTCHours(hours) | 设置 UTC 日期的小时(0~23) |
getMinutes() | 返回日期的分钟(0~59) |
getUTCMinutes() | 返回 UTC 日期的分钟(0~59) |
setMinutes(minutes) | 设置日期的分钟(0~59) |
setUTCMinutes(minutes) | 设置 UTC 日期的分钟(0~59) |
getSeconds() | 返回日期的秒(0~59) |
getUTCSeconds() | 返回 UTC 日期的秒(0~59) |
setSeconds(seconds) | 设置日期的秒(0~59) |
setUTCSeconds(seconds) | 设置 UTC 日期的秒(0~59) |
getMilliseconds() | 返回日期的毫秒(0~999) |
getUTCMilliseconds() | 返回 UTC 日期的毫秒(0~999) |
setMilliseconds(milliseconds) | 设置日期的毫秒(0~999) |
setUTCMilliseconds(milliseconds) | 设置 UTC 日期的毫秒(0~999) |
getTimezoneOffset() | 返回本地时间与 UTC 时间相差的分钟数 |
6、RegExp:ECMAScript 通过 RegExp 类型支持正则表达式。正则表达式使用类似 Perl 的简洁语法来创建: | |
let expression = /pattern/flags; | |
这个正则表达式的 pattern(模式)可以是任何简单或复杂的正则表达式,包括字符类、限定符、分组、向前查找和反向引用。每个正则表达式可以带零个或多个 flags(标记),用于控制正则表达式的行为。下面给出了表示匹配模式的标记。 | |
g:全局模式,表示查找字符串的全部内容,而不是找到第一个匹配的内容就结束。 | |
i:不区分大小写,表示在查找匹配时忽略 pattern 和字符串的大小写。 | |
m:多行模式,表示查找到一行文本末尾时会继续查找。 | |
y:粘附模式,表示只查找从 lastIndex 开始及之后的字符串。 | |
u:Unicode 模式,启用 Unicode 匹配。 | |
s:dotAll 模式,表示元字符.匹配任何字符(包括\n 或\r)。 | |
使用不同模式和标记可以创建出各种正则表达式,比如: | |
// 匹配字符串中的所有”at” | |
let pattern1 = /at/g; | |
// 匹配第一个”bat”或”cat”,忽略大小写 | |
let pattern2 = /[bc]at/i; | |
// 匹配所有以”at”结尾的三字符组合,忽略大小写 | |
let pattern3 = /.at/gi; | |
与其他语言中的正则表达式类似,所有元字符在模式中也必须转义,包括: | |
( [ { \ ^ $ | ) ] } ? * + . |
元字符在正则表达式中都有一种或多种特殊功能,所以要匹配上面这些字符本身,就必须使用反斜杠来转义。下面是几个例子: | |
// 匹配第一个”bat”或”cat”,忽略大小写 | |
let pattern1 = /[bc]at/i; | |
// 匹配第一个”[bc]at”,忽略大小写 | |
let pattern2 = /[bc]at/i; | |
// 匹配所有以”at”结尾的三字符组合,忽略大小写 | |
let pattern3 = /.at/gi; | |
// 匹配所有”.at”,忽略大小写 | |
let pattern4 = /.at/gi; | |
这里的 pattern1 匹配”bat”或”cat”,不区分大小写。要直接匹配”[bc]at”,左右中括号都必须像 pattern2 中那样使用反斜杠转义。在 pattern3 中,点号表示”at”前面的任意字符都可以匹配。如果想匹配”.at”,那么要像 pattern4 中那样对点号进行转义。 | |
前面例子中的正则表达式都是使用字面量形式定义的。正则表达式也可以使用 RegExp 构造函数来创建,它接收两个参数:模式字符串和(可选的)标记字符串。任何使用字面量定义的正则表达式也可以通过构造函数来创建,比如: | |
// 匹配第一个”bat”或”cat”,忽略大小写 | |
let pattern1 = /[bc]at/i; | |
// 跟 pattern1 一样,只不过是用构造函数创建的 | |
let pattern2 = new RegExp(“[bc]at”, “i”); | |
这里的 pattern1 和 pattern2 是等效的正则表达式。注意,RegExp 构造函数的两个参数都是字符串。因为 RegExp 的模式参数是字符串,所以在某些情况下需要二次转义。所有元字符都必须二次转义,包括转义字符序列,如\n(\转义后的字符串是\,在正则表达式字符串中则要写成\\)。下表展示了几个正则表达式的字面量形式,以及使用 RegExp 构造函数创建时对应的模式字符串。 | |
| 字面量模式 | 对应的字符串 | | |
| /[bc]at/ | “\[bc\]at” | | |
| /.at/ | “\.at” | | |
| /name/age/ | “name\/age” | | |
| /\d.\d{1,2}/ | “\d.\d{1,2}” | | |
| /\w\hello\123/ | “\w\\hello\\123” | | |
此外,使用 RegExp 也可以基于已有的正则表达式实例,并可选择性地修改它们的标记: | |
const re1 = /cat/g; | |
console.log(re1); // “/cat/g” | |
const re2 = new RegExp(re1); | |
console.log(re2); // “/cat/g” | |
const re3 = new RegExp(re1, “i”); | |
console.log(re3); // “/cat/i” |