前文有讲过,引用值是某个特定引用类型的实例。引用类型虽然有点像类,但跟类并不是一个概念。
对象被认为是某个特定引用类型的实例。新对象通过使用 new 操作符后跟一个构造函数来创建。
ECMAScript 的 Date 类参考了 Java 的实现方式。使用 UTC 时间,从 1970-01-01 开始至今经过的毫秒数。
创建日期对象:let now = new Date()
在不传参的情况下,创建的对象将保存当前日期和时间。
要基于特定日期和时间创建日期对象,则需要传入其毫秒数表示。
ECMAScript 提供了两个辅助方法:Date.parse() 和 Date.UTC()。
Date.parse() 接受一个表示日期的字符串,尝试将这个字符串转换为表示该日期的毫秒数。
直接使用字符串传给 Date 构造函数,那么 Date 会在后台调用 Date.parse()
以上两种方式得到的日期对象相同。
Date.UTC() 方法也返回日期的毫秒数表示,但接收的参数是 年、零起点约束、日、时、分、秒、毫秒。其中,年、月是必须的。
Date.UTC() 隐式调用时,创建的是本地日期,不是GMT日期。
Date.now() 返回执行时日期和时间的毫秒数。
Date 类型重写了 toLocaleString()、toString()、valueOf() 方法。
toLocaleString() 方法返回与浏览器运行的本地环境一致的日期和时间。包含时间的 AM 或 PM,但不包含时区信息。
toString() 方法通常返回带时区信息的日期和时间,24小时制。
valueOf() 方法根本就不返回字符串,返回的是日期的毫秒数表示。因此可以直接使用它返回的值。
Date 类型有几个专门用于格式化日期的方法,都返回字符串
:
方法 | 说明 |
---|---|
getTime() | 返回日期的毫秒数表示,与 valueOf() 相同 |
getFullYear() | 返回4位数年 |
getMonth() | 返回日期的月 |
getDate() | 返回日期中的日 |
getDay() | 返回周几的数值 |
getHours() | 返回日期中的时 |
getMinutes() | 返回日期中的分 |
getSeconds() | 返回日期中的秒 |
getMilliseconds() | 返回日期中的毫秒 |
getTimezoneOffset() | 返回以分钟计的 UTC 与本地时区的偏移量。 |
ECMAScript 通过 RegExp 类型支持正则表达式。
pattern - 模式,可以是任何简单或复杂的正则表达式,包括字符类、限定符、分组、向前查找和反向引用。
flags - 标记,用于控制正则表达式的行为。
主要方法:exec(),主要用于配合捕获组使用。
exec():接受一个参数,即要应用模式的字符串。返回包含第一个匹配信息的数组 或 null。返回的数组信息虽然是 Array 的实例,但包含两个额外属性:index 和 input。
index 是字符串中匹配模式的起始位置,input 是要查找的字符串。
非全局模式下,lastIndex 始终不变。全局模式下,每次调用 exec() 都会在字符串中向前搜索下一个匹配项,直到搜索到字符串末尾。全局匹配模式下,每次调用 exec() 都会更新 lastIndex 值,以反映上次匹配的最后一个字符的索引。
如果设置了粘附标记 y,则每次调用 exec() 就只会在 lastIndex 的位置上寻找匹配项。粘附标记会覆盖全局标记。
test() 方法,接受一个字符串参数,如果输入的文本与模式匹配,则参数返回 true,否则返回 false。这个方法适用于只想测试模式是否匹配,不需要实际匹配内容得情况。
继承的方法 toLocaleString() 和 toString() 返回的都是其字面量的形式。valueOf() 返回正则表达式本身。
RegExp 构造函数本身具有几个属性。
全名 | 简写 | 说明 |
---|---|---|
input | $_ | 最后搜索的字符串 |
lastMatch | $& | 最后匹配的文本 |
lastParen | $+ | 最后匹配的捕获组 |
leftContext | $` | input 字符串中出现 lastMatch 前面的文本 |
rightContext | $' | input 字符串出现在 lastMatch 后面的文本 |
RegExp 构造函数的属性不要在生产环境中使用。
ECMAScript 提供了三种特殊的应用类型:Boolean、Number和String。
每当调用原始值的方法或属性时,后台都会创建一个相应原始包装类型的对象,从而暴露出操作原始值的各种方法。
第二行访问 s1 时,是以读模式访问的,以读模式访问字符串值的任何时候,后台都会执行如下3步:
即,第二行代码可以想象的执行了如下三行 ECMAScript 代码:
对于布尔值和数值而言,以上3步也会发生在后台,不过使用的分别是 Boolean 和 Number 包装类型而已。
引用类型和原始值包装类型的主要区别在于生命周期。通过 new 实例化引用类型后,得到的实例会在离开作用域时被销毁,而主动创建的原始值包装类型则只存在于访问它的那行代码执行期间。所以不能给原始值包装类型添加属性和方法。因为它会在执行添加后,自动销毁。
原始值包装类型调用 typeof 会返回 ‘object’。
Object 构造函数作为一个工厂方法,能够根据传入值的类型返回相应原始值包装类型的实例。
注意,使用 new 调用原始值包装类型的构造函数,与调用同名的转型函数并不一样。
Boolean 是对应布尔值的引用类型。要创建一个 Boolean 对象,就是用 Boolean 构造函数并传入 true 或 false。
Boolean 实例会重写 valueOf() 方法,返回一个原始值 true 或 false。toString() 方法被调用时也会被覆盖,返回字符串 “true” 或 “false”。
Boolean 对象 在 ECMAScript 中使用时,容易引起误会。
原因,所有的对象在布尔表达式中都表示为 true 值。
理解原始布尔值和Boolean对象之间的区别,强烈建议永远不要使用后者。
Number 类型重写了 valueOf()、toLocaleString()、toString() 方法。
valueOf() 返回Number对象表示的原始数值,另外两个方法返回字符串。
toString() 还可以接受一个可选的参数,表示基数,并返回相应基数形式的数值字符串。
toFixed() 返回包含指定小数点位数的数值字符串。通常支持0~20个小数位。
toExponential() 返回科学计数法。接受一个参数,表示结果中小数的位数。
toPrecision() 根据情况返回最合理的输出结果。接受一个参数,表示结果中数字的总位数。通常支持1~21个小数位。
isinteger() 方法,用于辨别一个数值是否保存为整数。
IEEE 754 数据格式 有一个特殊的数值范围,在这个范围内二进制值可以表示一个整数值。Number.MIN_SAFE_INTEGER($\ce{-2^53 + 1}$)到 Number.MAX_SAFE_INTEGER($\ce{2^53 - 1}$)范围内的数据,可以使用 Number.isSafeInteger() 方法鉴别。
String 是对应字符串的引用类型。集成的三个方法 valueOf()、toLocaleString()、toString() 都返回对象的原始字符串值。
length 属性,表示字符串中字符的数量。
JavaScript 字符串是由 16 位码元组成。对多数字符来说,每 16 位码元对应一个字符。换句话说,length 属性表示字符串包含多少16位码元。
charAt() 方法返回给定索引位置的字符,由传给方法的整数参数指定。具体来说,查找指定索引位置的 16 位码元,并返回该码元对应的字符。
JavaScript 字符串使用了两种 Unicode 编码混合的策略: UCS-2 和 UTF-16。
charCodeAt() 方法可以查看指定码元的字符编码。返回指定索引位置的码元值,索引以整数指定。
fromCharCode() 方法根据给定的 UTF-16 码元创建字符串中的字符。接受任意多个数值,并返回所有数值对应的字符拼接起来的字符串。
对于 U+0000~U+FFFF 范围内的字符,length、charAt()、charCodeAt()、fromCharCode() 返回的结果都是跟预期一样的。但是在扩展到 Unicode 增补字符平面时就不成立了。16位只能表示 65536 个字符,为了表示更多字符,Unicode 采用了一个策略,即每个字符使用另外16位去选择一个增补平面。这种每个字符使用两个16位码元的策略称为代理对。
涉及增补平面的字符时,之前讨论的方法就会出现问题。
为正确解析既包含单码元字符又包含代理对字符的字符串,可以使用 codePointAt() 来代替 charCodeAt()。
可以使用遍历的方式,来迭代字符串,识别对应的码点。
可以使用 fromCodePoint() 来代替 fromCharCode()。
某些 Unicode 字符有多种编码方式。有的字符可以通过一个 BMP 字符表示,也可以使用一个代理对表示。但是比较操作符会认为他们各不相等。
为了解决这个问题,Unicode 提供了4种规范化形式:
可以使用 normalize() 方法对字符串应用上述规范化形式,使用时需要传入表示哪种形式的字符串:“NFD”、“NFC”、“NFKD”、”NFDC“。
选择同一种规范化形式可以让比较操作符返回正确的结果: