目录
Date
ECMAScript的Date类型将日期保存为UTC时间,1970年1月1日午夜(零时)至今所经过的毫秒数。使用这种存储格式,Date类型可以精确表示1970年1月1日之前及之后285616年的日期。
要创建日期对象,就使用new操作符来调用Date构造函数:
let now = new Date();
在不给Date构造函数传参数的情况下,创建的对象将保存当前日期和时间。要基于其他日期和时间创建日期对象,必须传入其毫秒表示。ECMAScript为此提供了两个辅助方法:Date.parse()和Date.UTC()。
Date.parse()方法接收一个表示日期的字符串参数,尝试将这个字符串转换为表示该日期的毫秒数。ECMA-262第五版定义了Date.parse()应该支持的日期格式。所有实现都必须支持下列日期格式:
- “月/日/年”,如“5/23/2019”;
- “月名 日/年”,如May 23, 2019”;
- “周几 月名 日 年 时:分:秒 时区”,如“Tue May 23 2019 00:00:00 GMT-0700”;
比如,要创建一个表示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()的参数是年、0起点月数、日、时、分、秒和毫秒。这些参数中只有前两个是必须的,如果不提供日,那么默认为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));
与Date.parse()一样,Date.UTC()也会被Date构造函数隐式调用,但有一个区别:这种情况下创建的是本地日期,不是GMT日期。不过Date构造参数跟Date.UTC()接收的参数是一样的。
继承的方法
与其他类型一样,Date类型重写了toLocaleString()、toString()和valueOf()方法,但与其他类型不同,重写后这些方法的返回值不一样。Date类型的toLocaleString()方法返回与浏览器运行的本地环境一致的日期和时间。toString()方法通常返回带时区信息的日期和时间,而时间也是以24小时制表示的。
Date类型的valueOf()方法根本就不返回字符串,这个方法被重写后返回的是日期的毫秒表示。
Date类型有几个专门用于格式化日期的方法,它们都会返回字符串:
- toDateString()显示日期中的周几、月、日、年(格式特定于实现);
- toTimeString()显示日期中的时分秒和时区(格式特定于实现);
- toLocaleDateString()显示日期中的周几、月日年(格式特定于实现和地区);
- toLocaleTimeString()显示日期中的时分秒(格式特定于实现和地区);
- toUTCString()显示完整的UTC日期(格式特定于实现);
RegExp
ECMAScript通过RegExp类型支持正则表达式。正则表达式使用类似Perl的简洁语法来创建:
let expression = /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 pattern = /.at/gi;
与其他语言中的正则表达式类似,所有元字符在模式中也必须转义,包括:
( [ { \ ^ $ | } ] } ? * + .
元字符在正则表达式中都有一种或多种特殊功能,所以要匹配上面这些字符本身,就必须使用反斜杠来转义。
RegExp实例属性
每个RegExp实例都有下列属性,提供有关模式的各方面信息。
- global:布尔值,表示是否设置了g标记。
- ignoreCase:布尔值,表示是否设置了i标记。
- Unicode:布尔值,表示是否设置了u标记。
- sticky:布尔值,表示是否设置了y标记。
- lastIndex:整数,表示在源字符串中下一次搜索开始的位置,始终从0开始。
- multiLine:布尔值,表示是否设置了m标记。
- dotAll:布尔值,表示是否设置了s标记。
- source:正则表达式的自面量字符串(不是传给构造函数的模式字符串),没有开头和结尾的斜杠。
- flags:正则表达式的标记字符串。始终以字面量而非传入构造函数的字符串模式形式返回(没有前后斜杠)。
RegExp实例方法
RegExp实例的主要方法是exec(),主要用于配合捕获组使用。这个方法只接收一个参数,即要应用模式的字符串。如果找到了匹配项,则返回包含第一个匹配信息的数组;如果没有找到匹配项,则返回null。返回的数组虽然是Array的实例,但包含两个额外的属性:index和input。index是字符串中匹配模式的起始位置,input是要查找的字符串。这个数组的第一个元素是匹配整个模式的字符串,其他元素是与表达式中的捕获组匹配的字符串。如果模式中没有捕获组,则数组只包含一个元素。来看下面的例子:
let text = "mom and dad and baby";
let pattern = /mom( and dad( and baby)?)?/gi;
let matches = pattern.exec(text);
console.log(matches.index); //0
console.log(matches.input); //"mom and dad and baby"
console.log(matches[0]); //"mom and dad and baby"
console.log(matches[1]); //" and dad and baby"
console.log(matches[2]); //" and baby"
在这个例子中,模式包含两个捕获组:最内部的匹配项“and baby”,以及外部的匹配项“and dad” 或“and dad and baby”。调用exec()后找到了一个匹配项。因为整个字符串匹配模式,所以matchs数组的index属性就是0。数组的第一个元素是匹配的整个字符串,第二个元素是匹配第一个捕获组的字符串,第三个元素是匹配第二个捕获组的字符串。
如果模式设置了全局标记,则每次调用exec()方法会返回一个匹配的信息。如果没有设置全局标记,则无论对同一个字符串调用多少次,exec()也只会返回第一个匹配的信息。
如果模式设置了粘附标记y,则每次调用exec()就只会在lastIndex的位置上寻找匹配项。粘附标记覆盖全局标记。
正则表达式的另一个方法是test(),接收一个字符串参数。如果输入的文本与模式匹配,则参数返回true,否则返回false。这个方法适用于只想测试模式是否匹配,而不需要实际匹配内容的情况。test()经常用在if语句中:
let text = "000-00-0000";
let pattern = /\d{3}-\d{2}-\d{4}/;
if(pattern.test(text)){
console.log("The pattern was matched.")
}
在这个例子中,正则表达式用于测试特定的数值序列。如果输入的文本与模式匹配,则显示匹配成功的消息。这个用法常用于验证用户输入,此时我们只在乎输入是否有效,不关心为什么无效。
无论正则表达式是怎么创建的,继承的方法toLocalString()和toString()都返回正则表达式的自面量表示。
RegExp构造函数属性
RegExp构造函数本身也有几个属性。这些属性适用于作用域中的所有正则表达式,而且会根据最后执行的正则表达式操作而变化。这些属性还有一个特点,就是可以通过两种不同的方式访问它们。换句话说,每个属性都有一个全名和一个简写。下表列出了RegExp构造函数的属性。
全名 | 简写 | 说明 |
---|---|---|
input | $_ | 最后搜索的字符串 |
lastMatch | $& | 最后匹配的文本 |
lastParen | $+ | 最后匹配的捕获组 |
leftContext | $` | input字符串中出现在lastMatch前面的文本 |
rightContext | $' | input字符串中出现在lastMatch后面的文本 |
通过这些属性可以提取出与exec()和test()执行的相关操作的信息。
Boolean
Boolean是对应布尔值的引用类型。要创建一个Boolean对象,就使用Boolean构造函数,并传入true或false。
Boolean的实例会重写valueOf()方法,返回一个原始值true或false。toString()方法被调用时也会被覆盖,返回字符串“true”或“false”。不过Boolean对象在ECMAScript中用的很少。不仅如此,它们还容易引起误会,尤其是在布尔表达式中使用对象时:
let falseObject = new Boolean(false);
let result = falseObject&&true;
console.log(result) //true
let falseValue = false;
result = falseValue&&true;
console.log(result) //false
因为所有对象在布尔表达式中都会自动转换为true,因此falseObject在这个表达式里实际上表示一个true值,所以结果当然是true。
理解原始布尔值和Boolean对象之间的区别非常重要,强烈建议永远不要使用后者。