再读红宝书(第四版) 第五章 基本引用类型

2023-11-17

引用值(或者对象)是某个特定引用类型的实例。在 ECMAScript 中,引用类型是把数据和功能组织到一起的结构,经常被人错误地称作“类”。虽然从技术上讲 JavaScript 是一门面向对象语言,但ECMAScript 缺少传统的面向对象编程语言所具备的某些基本结构,包括类和接口。引用类型有时候也被称为对象定义,因为它们描述了自己的对象应有的属性和方法。

对象被认为是某个特定引用类型的实例。新对象通过使用 new 操作符后跟一个构造函数(constructor)来创建。构造函数就是用来创建新对象的函数,它负责创建一个只有默认属性和方法的简单对象。

date

ECMAScript 的 Date 类型参考了 Java 早期版本中的 java.util.Date。为此,Date 类型将日期保存为自协调世界时(UTC,Universal Time Coordinated)时间 1970 年 1 月 1 日午夜(零时)至今所经过的毫秒数。使用这种存储格式,Date 类型可以精确表示 1970 年 1 月 1 日之前及之后 285 616 年的日期。

在不给 Date 构造函数传参数的情况下,创建的对象将保存当前日期和时间。要基于其他日期和时间创建日期对象,必须传入其毫秒表示。如果传给 Date.parse()的字符串并不表示日期,则该方法会返回 NaN。如果直接把表示日期的字符串传给 Date 构造函数,那么 Date 会在后台调用 Date.parse()。

Date.parse() 方法接收一个表示日期的字符串参数,尝试将这个字符串转换为表示该日期的毫秒数。

“周几 月名 日 年 时:分:秒 时区”,如"Tue May 23 2019 00:00:00 GMT-0700"; 
ISO 8601 扩展格式“YYYY-MM-DDTHH:mm:ss.sssZ”,如 2019-05-23T00:00:00(只适用于兼容 ES5 的实现)。

Date.UTC() 方法也返回日期的毫秒表示,参数是年、零起点月数.如果不提供日,那么默认为 1 日。其他

参数的默认值都是 0。

Date.parse() 一样,Date.UTC()也会被 Date 构造函数隐式调用,但有一个区别:这种情况下创建的是本地日期,不是 GMT 日期。不过 Date 构造函数跟 Date.UTC()接收的参数是一样的。

Date.now()方法,返回表示方法执行时日期和时间的毫秒数。这个方法可以方便地用在代码分析中。

Date 类型重写了 toLocaleString()、toString()和 valueOf()方法。但与其他类型不同,重写后这些方法的返回值不一样。Date 类型的 toLocaleString()方法返回与浏览器运行的本地环境一致的日期和时间。这通常意味着格式中包含针对时间的 AM(上午)或 PM(下午),但不包含时区信息(具体格式可能因浏览器而不同)。toString()方法通常返回带时区信息的日期和时间,而时间也是以 24 小时制(0~23)表示的。PST,即 Pacific Standard Time,太平洋标准时间。toLocaleString()和 toString()可能只对调试有用,不能用于显示。

日期格式化方法

Date 类型有几个专门用于格式化日期的方法,它们都会返回字符串:

 toDateString()显示日期中的周几、月、日、年(格式特定于实现);

 toTimeString()显示日期中的时、分、秒和时区(格式特定于实现);

 toLocaleDateString()显示日期中的周几、月、日、年(格式特定于实现和地区);

 toLocaleTimeString()显示日期中的时、分、秒(格式特定于实现和地区);

 toUTCString()显示完整的 UTC 日期(格式特定于实现)。

这些方法的输出与 toLocaleString()和 toString()一样,会因浏览器而异。因此不能用于在用户界面上一致地显示日期。

注意 还有一个方法叫 toGMTString(),这个方法跟 toUTCString()是一样的,目的是为了向后兼容。不过,规范建议新代码使用 toUTCString()。

日期/时间组件方法

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 月,11 表示 12 月)

setMonth(month) 设置日期的月(month 为大于 0 的数值,大于 11 加年)

setUTCMonth(month) 设置 UTC 日期的月(month 为大于 0 的数值,大于 11 加年)

getDate() 返回日期中的日(1~31)

getUTCDate() 返回 UTC 日期中的日(1~31)

setDate(date) 设置日期中的日(如果 date 大于该月天数,则加月)

setUTCDate(date) 设置 UTC 日期中的日(如果 date 大于该月天数,则加月)

getDay() 返回日期中表示周几的数值(0 表示周日,6 表示周六)

getUTCDay() 返回 UTC 日期中表示周几的数值(0 表示周日,6 表示周六)

getHours() 返回日期中的时(0~23)

getUTCHours() 返回 UTC 日期中的时(0~23)

setHours(hours) 设置日期中的时(如果 hours 大于 23,则加日)

setUTCHours(hours) 设置 UTC 日期中的时(如果 hours 大于 23,则加日)

getMinutes() 返回日期中的分(0 ~ 59)

getUTCMinutes() 返回 UTC 日期中的分(0 ~ 59)

setMinutes(minutes) 设置日期中的分(如果 minutes 大于 59,则加时)

setUTCMinutes(minutes) 设置 UTC 日期中的分(如果 minutes 大于 59,则加时)

getSeconds() 返回日期中的秒(0~59)

getUTCSeconds() 返回 UTC 日期中的秒(0~59)

setSeconds(seconds) 设置日期中的秒(如果 seconds 大于 59,则加分)

setUTCSeconds(seconds) 设置 UTC 日期中的秒(如果 seconds 大于 59,则加分)

getMilliseconds() 返回日期中的毫秒

getUTCMilliseconds() 返回 UTC 日期中的毫秒

setMilliseconds(milliseconds) 设置日期中的毫秒

setUTCMilliseconds(milliseconds) 设置 UTC 日期中的毫秒

getTimezoneOffset() 返回以分钟计的 UTC 与本地时区的偏移量(如美国 EST 即“东部标准时间”

返回 300,进入夏令时的地区可能有所差异)

RegExp

ECMAScript 通过 RegExp 类型支持正则表达式。正则表达式使用类似 Perl 的简洁语法来创建:

let expression = /pattern/flags;

这个正则表达式的 pattern(模式)可以是任何简单或复杂的正则表达式,包括字符类、限定符、

分组、向前查找和反向引用。每个正则表达式可以带零个或多个 flags(标记),用于控制正则表达式

的行为。下面给出了表示匹配模式的标记。

 g:全局模式,表示查找字符串的全部内容,而不是找到第一个匹配的内容就结束。

 i:不区分大小写,表示在查找匹配时忽略 pattern 和字符串的大小写。

 m:多行模式,表示查找到一行文本末尾时会继续查找。

 y:粘附模式,表示只查找从 lastIndex 开始及之后的字符串。

 u:Unicode 模式,启用 Unicode 匹配。

 s:dotAll 模式,表示元字符.匹配任何字符(包括\n 或\r)

与其他语言中的正则表达式类似,所有元字符在模式中也必须转义,包括:( [ { \ ^ $ | ) ] } ? * + .

RegExp 实例属性

每个 RegExp 实例都有下列属性,提供有关模式的各方面信息。

 global:布尔值,表示是否设置了 g 标记。

 ignoreCase:布尔值,表示是否设置了 i 标记。

 unicode:布尔值,表示是否设置了 u 标记。

 sticky:布尔值,表示是否设置了 y 标记。

 lastIndex:整数,表示在源字符串中下一次搜索的开始位置,始终从 0 开始。

 multiline:布尔值,表示是否设置了 m 标记。

 dotAll:布尔值,表示是否设置了 s 标记。

 source:正则表达式的字面量字符串(不是传给构造函数的模式字符串),没有开头和结尾的斜杠。

 flags:正则表达式的标记字符串。始终以字面量而非传入构造函数的字符串模式形式返回(没

有前后斜杠)

source 和 flags 属性返回的是规范化之后可以在字面量中使用的形式

RegExp 实例的主要方法是 exec(),主要用于配合捕获组使用。这个方法只接收一个参数,即要应用模式的字符串。如果找到了匹配项,则返回包含第一个匹配信息的数组;如果没找到匹配项,则返回null。返回的数组虽然是 Array 的实例,但包含两个额外的属性:index 和 input。index 是字符串中匹配模式的起始位置,input 是要查找的字符串。这个数组的第一个元素是匹配整个模式的字符串,其他元素是与表达式中的捕获组匹配的字符串。如果模式中没有捕获组,则数组只包含一个元素。

如果模式设置了全局标记,则每次调用 exec()方法会返回一个匹配的信息。如果没有设置全局标记,则无论对同一个字符串调用多少次 exec(),也只会返回第一个匹配的信息。

正则表达式的另一个方法是 test(),接收一个字符串参数。如果输入的文本与模式匹配,则参数返回 true,否则返回 false。这个方法适用于只想测试模式是否匹配,而不需要实际匹配内容的情况。test()经常用在 if 语句中。

这里的模式是通过 RegExp 构造函数创建的,但 toLocaleString()和 toString()返回的都是其字面量的形式。注意 正则表达式的 valueOf()方法返回正则表达式本身。

RegExp 构造函数本身也有几个属性。(在其他语言中,这种属性被称为静态属性。)这些属性适用于作用域中的所有正则表达式,而且会根据最后执行的正则表达式操作而变化。每个属性都有一个全名和一个简写。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BgkOr73h-1614079246644)(C:%5CUsers%5C34557%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20210223164335122.png)]

以上代码创建了一个模式,用于搜索任何后跟"hort"的字符,并把第一个字符放在了捕获组中。不同属性包含的内容如下。

 input 属性中包含原始的字符串。

 leftConext 属性包含原始字符串中"short"之前的内容,rightContext 属性包含"short"之后的内容。

 lastMatch 属性包含匹配整个正则表达式的上一个字符串,即"short"。

 lastParen 属性包含捕获组的上一次匹配,即"s"。

模式包含两个捕获组。调用 test()搜索字符串之后,因为找到了匹配项所以返回true,而且可以打印出通过 RegExp 构造函数的$1 和$2 属性取得的两个捕获组匹配的内容。注意 RegExp 构造函数的所有属性都没有任何 Web 标准出处,因此不要在生产环境中使用它们。

模式局限

正则表达式但仍然缺少 Perl 语言中的一些高级特性。下列特性目前还没有得到 ECMAScript 的支持:

 \A 和\Z 锚(分别匹配字符串的开始和末尾)

 联合及交叉类

 原子组

 x(忽略空格)匹配模式

 条件式匹配

 正则表达式注释

原始值包装类型

ECMAScript 提供了 3 种特殊的引用类型:Boolean、Number 和 String。

这些类型具有本章介绍的其他引用类型一样的特点,但也具有与各自原始类型对应的特殊行为。每当用到某个原始值的方法或属性时,后台都会创建一个相应原始包装类型的对象,从而暴露出操作原始值的各种方法。这种行为可以让原始值拥有对象的行为。引用类型与原始值包装类型的主要区别在于对象的生命周期。在通过 new 实例化引用类型后,得到的实例会在离开作用域时被销毁,而自动创建的原始值包装对象则只存在于访问它的那行代码执行期间。这意味着不能在运行时给原始值添加属性和方法。

let value = "25"; 
let number = Number(value); // 转型函数
console.log(typeof number); // "number" 
let obj = new Number(value); // 构造函数
console.log(typeof obj); // "object"

虽然不推荐显式创建原始值包装类型的实例,但它们对于操作原始值的功能是很重要的。每个原始值包装类型都有相应的一套方法来方便数据操作。

Boolean 是对应布尔值的引用类型。要创建一个 Boolean 对象,就使用 Boolean 构造函数并传入true 或 false,如下例所示:

let booleanObject = new Boolean(true);

Boolean 的实例会重写 valueOf()方法,返回一个原始值 true 或 false。toString()方法被调用时也会被覆盖,返回字符串"true"或"false"。所有对象在布尔表达式中都会自动转换为 true,因此 falseObject 在这个表达式里实际上表示一个 true 值。

原始值和引用值(Boolean 对象)还有几个区别。首先,typeof 操作符对原始值返回"boolean",但对引用值返回"object"。同样,Boolean 对象是 Boolean 类型的实例,在使用instaceof 操作符时返回 true,但对原始值则返回 false。理解原始布尔值和 Boolean 对象之间的区别非常重要,强烈建议永远不要使用后者。

Number 是对应数值的引用类型。要创建一个 Number 对象,就使用 Number 构造函数并传入一个数值,如下例所示:

let numberObject = new Number(10);

与 Boolean 类型一样,Number 类型重写了 valueOf()、toLocaleString()和 toString()方法。valueOf()方法返回 Number 对象表示的原始数值,另外两个方法返回数值字符串。toString()方法可选地接收一个表示基数的参数,并返回相应基数形式的数值字符串。

toFixed()方法返回包含指定小数点位数的数值字符串。toFixed()自动舍入的特点可以用于处理货币。不过要注意的是,多个浮点数值的数学计算不一定得到精确的结果。比如,0.1 + 0.2 = 0.30000000000000004。toFixed()方法可以表示有 0~20 个小数位的数值。

另一个用于格式化数值的方法是 toExponential(),返回以科学记数法(也称为指数记数法)表示的数值字符串。与 toFixed()一样,toExponential()也接收一个参数,表示结果中小数的位数。

toPrecision()方法会根据情况返回最合理的输出结果,可能是固定长度,也可能是科学记数法形式。这个方法接收一个参数,表示结果中数字的总位数(不包含指数)。本质上,toPrecision()方法会根据数值和精度来决定调用 toFixed()还是 toExponential()。为了以正确的小数位精确表示数值,这 3 个方法都会向上或向下舍入。

Number 对象也为数值提供了重要能力。但是,考虑到两者存在同样的潜在问题,因此并不建议直接实例化 Number 对象。在处理原始数值和引用数值时,typeof 和 instacnceof操作符会返回不同的结果

ES6 新增了 Number.isInteger()方法,用于辨别一个数值是否保存为整数。有时候,小数位的 0可能会让人误以为数值是一个浮点值。 console.log(Number.isInteger(1.00)); // true

IEEE 754 数值格式有一个特殊的数值范围,在这个范围内二进制值可以表示一个整数值。这个数值范围从 Number.MIN_SAFE_INTEGER(-2^53+ 1)到 Number.MAX_SAFE_INTEGER(2^53 - 1)。对超出这个范围的数值,即使尝试保存为整数,IEEE 754 编码格式也意味着二进制值可能会表示一个完全不同的数值。为了鉴别整数是否在这个范围内,可以使用 Number.isSafeInteger()方法

String 是对应字符串的引用类型。要创建一个 String 对象,使用 String 构造函数并传入一个数值,如下例所示:

let stringObject = new String(“hello world”);

String 对象的方法可以在所有字符串原始值上调用。3个继承的方法 valueOf()、toLocaleString()和 toString()都返回对象的原始字符串值。

每个 String 对象都有一个 length 属性,表示字符串中字符的数量。String 类型提供了很多方法来解析和操作字符串。

JavaScript 字符串由 16 位码元(code unit)组成。对多数字符来说,每 16 位码元对应一个字符。换句话说,字符串的 length 属性表示字符串包含多少 16 位码元.

charAt()方法返回给定索引位置的字符,由传给方法的整数参数指定。

JavaScript 字符串使用了两种 Unicode 编码混合的策略:UCS-2 和 UTF-16。对于可以采用 16 位编码的字符(U+0000~U+FFFF),这两种编码实际上是一样的。

使用 charCodeAt()方法可以查看指定码元的字符编码。这个方法返回指定索引位置的码元值,索

引以整数指定。

fromCharCode()方法用于根据给定的 UTF-16 码元创建字符串中的字符。这个方法可以接受任意多个数值,并返回将所有数值对应的字符拼接起来的字符串.

这个对应关系在扩展到 Unicode 增补字符平面时就不成立了。问题很简单,即 16 位只能唯一表示65 536 个字符。这对于大多数语言字符集是足够了,在 Unicode 中称为基本多语言平面(BMP)。为了表示更多的字符,Unicode 采用了一个策略,即每个字符使用另外 16 位去选择一个增补平面。这种每个字符使用两个 16 位码元的策略称为代理对。

为正确解析既包含单码元字符又包含代理对字符的字符串,可以使用 codePointAt()来代替charCodeAt()。codePointAt()方法可以从指定码元位置识别完整的码点。 charCodeAt()有对应的 codePointAt()一样,fromCharCode()也有一个对应的 fromCodePoint()。这个方法接收任意数量的码点,返回对应字符拼接起来的字符串

**normalize()**方法

某些 Unicode 字符可以有多种编码方式。有的字符既可以通过一个 BMP 字符表示,也可以通过一个代理对表示。

Unicode提供了 4种规范化形式,可以将类似上面的字符规范化为一致的格式,无论底层字符的代码是什么。这 4种规范化形式是:NFD(Normalization Form D)、NFC(Normalization Form C)、NFKD(Normalization Form KD)和 NFKC(Normalization Form KC)。可以使用 normalize()方法对字符串应用上述规范化形式,使用时需要传入表示哪种形式的字符串:“NFD”、“NFC”、"NFKD"或"NFKC"通过比较字符串与其调用 normalize()的返回值,就可以知道该字符串是否已经规范化了

字符串操作方法

首先是 concat(),用于将一个或多个字符串拼接成一个新字符串。concat()方法可以接收任意多个参数,因此可以一次性拼接多个字符串。

ECMAScript 提供了 3 个从字符串中提取子字符串的方法: slice()、 substr()和 substring()。这
3 个方法都返回调用它们的字符串的一个子字符串,而且都接收一或两个参数。第一个参数表示子字符串开
始的位置,第二个参数表示子字符串结束的位置。对 slice()和 substring()而言,第二个参数是提取结
束的位置(即该位置之前的字符会被提取出来)。对 substr()而言,第二个参数表示返回的子字符串数量。
任何情况下,省略第二个参数都意味着提取到字符串末尾。与 concat()方法一样, slice()、 substr()
和 substring()也不会修改调用它们的字符串,而只会返回提取到的原始新字符串值。 slice()、 substr()和 substring()是以相同方式被调用的,而且多数情况下返回的值也相同。

当某个参数是负值时,这 3 个方法的行为又有不同。

比如, slice()方法将所有负值参数都当成字符串长度加上负参数值。
而 substr()方法将第一个负参数值当成字符串长度加上该值,将第二个负参数值转换为 0。
substring()方法会将所有负参数值都转换为 0。

字符串位置方法

有两个方法用于在字符串中定位子字符串: indexOf()和 lastIndexOf()。这两个方法从字符串中搜索传入的字符串,并返回位置(如果没找到,则返回-1)。两者的区别在于, indexOf()方法从字符串开头开始查找子字符串,而 lastIndexOf()方法从字符串末尾开始查找子字符串。

这两个方法都可以接收可选的第二个参数,表示开始搜索的位置。这意味着, indexOf()会从这个
参数指定的位置开始向字符串末尾搜索,忽略该位置之前的字符; lastIndexOf()则会从这个参数指
定的位置开始向字符串开头搜索,忽略该位置之后直到字符串末尾的字符。

ECMAScript 6 增加了 3 个用于判断字符串中是否包含另一个字符串的方法: startsWith()、endsWith()和 includes()。这些方法都会从字符串中搜索传入的字符串,并返回一个表示是否包含的布尔值。它们的区别在于, startsWith()检查开始于索引 0 的匹配项, endsWith()检查开始于索引(string.length -substring.length)的匹配项,而 includes()检查整个字符串。startsWith()和 includes()方法接收可选的第二个参数,表示开始搜索的位置。如果传入第二个参数,则意味着这两个方法会从指定位置向着字符串末尾搜索,忽略该位置之前的所有字符。endsWith()方法接收可选的第二个参数,表示应该当作字符串末尾的位置。如果不提供这个参数,那么默认就是字符串长度。如果提供这个参数,那么就好像字符串只有那么多字符一样。

ECMAScript 在所有字符串上都提供了 trim()方法。这个方法会创建字符串的一个副本,删除前、后所有空格符,再返回结果。 trim()返回的是字符串的副本,因此原始字符串不受影响,即原本的前、后空格符都会保留。另外, trimLeft()和 trimRight()方法分别用于从字符串开始和末尾清理空格符。

ECMAScript 在所有字符串上都提供了 repeat()方法。这个方法接收一个整数参数,表示要将字
符串复制多少次,然后返回拼接所有副本后的结果。

let stringValue = "na ";
console.log(stringValue.repeat(16) + "batman");
// na na na na na na na na na na na na na na na na batman

padStart()和 padEnd()方法会复制字符串,如果小于指定长度,则在相应一边填充字符,直至满足长度条件。这两个方法的第一个参数是长度,第二个参数是可选的填充字符串,默认为空格.可选的第二个参数并不限于一个字符。如果提供了多个字符的字符串,则会将其拼接并截断以匹配指定长度。此外,如果长度小于或等于字符串长度,则会返回原始字符串。

字符串的原型上暴露了一个@@iterator 方法,表示可以迭代字符串的每个字符。有了这个迭代器之后,字符串就可以通过解构操作符来解构了。比如,可以更方便地把字符串分割为字符数组

toLowerCase()和toUpperCase()方法是原来就有的方法,与 java.lang.String 中的方法同名。 toLocaleLowerCase()和 toLocaleUpperCase()方法旨在基于特定地区实现。在很多地区,地区特定的方法与通用的方法是一样的。但在少数语言中(如土耳其语),Unicode 大小写转换需应用特殊规则,要使用地区特定的方法才能实现正确转换.通常,如果不知道代码涉及什么语言,则最好使用地区特定的转换方法。

String 类型专门为在字符串中实现模式匹配设计了几个方法。第一个就是 match()方法,这个方
法本质上跟 RegExp 对象的 exec()方法相同。 match()方法接收一个参数,可以是一个正则表达式字
符串,也可以是一个 RegExp 对象。match()方法返回的数组与 RegExp 对象的 exec()方法返回的数组是一样的:第一个元素是与整
个模式匹配的字符串,其余元素则是与表达式中的捕获组匹配的字符串(如果有的话)。
另一个查找模式的字符串方法是 search()。这个方法唯一的参数与 match()方法一样:正则表达
式字符串或 RegExp 对象。这个方法返回模式第一个匹配的位置索引,如果没找到则返回1。 search()
始终从字符串开头向后匹配模式。为简化子字符串替换操作, ECMAScript 提供了 replace()方法。这个方法接收两个参数,第一个
参数可以是一个 RegExp 对象或一个字符串(这个字符串不会转换为正则表达式),第二个参数可以是
一个字符串或一个函数。如果第一个参数是字符串,那么只会替换第一个子字符串。要想替换所有子字
符串,第一个参数必须为正则表达式并且带全局标记.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rcUe1vJo-1614079246647)(C:%5CUsers%5C34557%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20210223183534344.png)]

最后一个与模式匹配相关的字符串方法是 split()。这个方法会根据传入的分隔符将字符串拆分成数组。作为分隔符的参数可以是字符串,也可以是 RegExp 对象。(字符串分隔符不会被这个方法当成
正则表达式。)还可以传入第二个参数,即数组大小,确保返回的数组不会超过指定大小。

最后一个方法是 localeCompare(),这个方法比较两个字符串,返回如下 3 个值中的一个。
 如果按照字母表顺序,字符串应该排在字符串参数前头,则返回负值。(通常是-1,具体还要看
与实际值相关的实现。)
 如果字符串与字符串参数相等,则返回 0。
 如果按照字母表顺序,字符串应该排在字符串参数后头,则返回正值。(通常是 1,具体还要看
与实际值相关的实现。)

早期的浏览器开发商认为使用 JavaScript 动态生成 HTML 标签是一个需求。因此,早期浏览器扩展
了规范,增加了辅助生成 HTML 标签的方法。下表总结了这些 HTML 方法。不过,这些方法基本上已
经没有人使用了,因为结果通常不是语义化的标记。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uT0UlPsp-1614079246654)(C:%5CUsers%5C34557%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20210223183932854.png)]

单例内置对象

ECMA-262 对内置对象的定义是“任何由 ECMAScript 实现提供、与宿主环境无关,并在 ECMAScript
程序开始执行时就存在的对象”。这就意味着,开发者不用显式地实例化内置对象,因为它们已经实例
化好了。前面我们已经接触了大部分内置对象,包括 Object、 Array 和 String。本节介绍 ECMA-262
定义的另外两个单例内置对象: Global 和 Math。

Global 对象是 ECMAScript 中最特别的对象,因为代码不会显式地访问它。ECMA-262 规定 Global
对象为一种兜底对象,它所针对的是不属于任何对象的属性和方法。事实上,不存在全局变量或全局函
数这种东西。在全局作用域中定义的变量和函数都会变成 Global 对象的属性 。本书前面介绍的函数,
包括 isNaN()、 isFinite()、 parseInt()和 parseFloat(),实际上都是 Global 对象的方法。除
了这些, Global 对象上还有另外一些方法。

encodeURI()和 encodeURIComponent()方法用于编码统一资源标识符(URI),以便传给浏览器。
有效的 URI 不能包含某些字符,比如空格。使用 URI 编码方法来编码 URI 可以让浏览器能够理解它们,
同时又以特殊的 UTF-8 编码替换掉所有无效字符。

ecnodeURI()方法用于对整个 URI 进行编码,比如"www.wrox.com/illegal value.js"。而
encodeURIComponent()方法用于编码 URI 中单独的组件. encodeURI()不会编码属于 URL 组件的特殊字符,比如冒号、斜杠、问号、井号,而 encodeURIComponent()会编码它发现的所有非标准字符. 一般来说,使用 encodeURIComponent()应该比使用 encodeURI()的频率更高,
这是因为编码查询字符串参数比编码基准 URI 的次数更多。

URI 方法 encodeURI()、encodeURIComponent()、decodeURI()和 decodeURIComponent()取代了 escape()和 unescape()方法, 后者在 ECMA-262 第 3 版中就已经
废弃了。 URI 方法始终是首选方法,因为它们对所有 Unicode 字符进行编码,而原来的方
法只能正确编码 ASCII 字符。不要在生产环境中使用 escape()和 unescape()。

最后一个方法可能是整个 ECMAScript 语言中最强大的了,它就是 eval()。这个方法就是一个完
整的 ECMAScript 解释器,它接收一个参数,即一个要执行的 ECMAScript(JavaScript)字符串。当解释器发现 eval()调用时,会将参数解释为实际的 ECMAScript 语句,然后将其插入到该位置。
通过 eval()执行的代码属于该调用所在上下文,被执行的代码与该上下文拥有相同的作用域链。这意
味着定义在包含上下文中的变量可以在 eval()调用内部被引用,通过 eval()定义的任何变量和函数都不会被提升,这是因为在解析代码的时候,它们是被包含在
一个字符串中的。它们只是在 eval()执行的时候才会被创建。
在严格模式下,在 eval()内部创建的变量和函数无法被外部访问。换句话说,最后两个例子会报
错。同样,在严格模式下,赋值给 eval 也会导致错误

*解释代码字符串的能力是非常强大的,但也非常危险。在使用 eval()的时候必须
极为慎重,特别是在解释用户输入的内容时。因为这个方法会对 XSS 利用暴露出很大的
攻击面。恶意用户可能插入会导致你网站或应用崩溃的代码。

Global 对象属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CwqWPgk9-1614079246665)(C:%5CUsers%5C34557%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20210223191156464.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vWhuxOsm-1614079246672)(C:%5CUsers%5C34557%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20210223191221640.png)]

虽然 ECMA-262 没有规定直接访问 Global 对象的方式,但浏览器将 window 对象实现为 Global
对象的代理。因此,所有全局作用域中声明的变量和函数都变成了 window 的属性

ECMAScript 提供了 Math 对象作为保存数学公式、信息和计算的地方。 Math 对象提供了一些辅助
计算的属性和方法。

注意 Math 对象上提供的计算要比直接在 JavaScript 实现的快得多,因为 Math 对象上的
计算使用了 JavaScript 引擎中更高效的实现和处理器指令。但使用 Math 计算的问题是精
度会因浏览器、操作系统、指令集和硬件而异。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-naP4whh0-1614079246677)(C:%5CUsers%5C34557%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20210223191419681.png)]

min()和 max()方法用于确定一组数值中的最小值和最大值。这两个方法都接收任意多个参数

把小数值舍入为整数的 4 个方法: Math.ceil()、 Math.floor()、 Math.round()
和 Math.fround()。这几个方法处理舍入的方式如下所述。
 Math.ceil()方法始终向上舍入为最接近的整数。

 Math.floor()方法始终向下舍入为最接近的整数。
 Math.round()方法执行四舍五入。
 Math.fround()方法返回数值最接近的单精度(32 位)浮点值表示。

Math.random()方法返回一个 0~1 范围内的随机数,其中包含 0 但不包含 1。Math.random()方法在这里出于演示目的是没有问题的。如果是为了加密而需要生成随机数(传给生成器的输入需要较高的不确定性),那么建议使用 window.crypto.getRandomValues()。

其他方法

小结
JavaScript 中的对象称为引用值,几种内置的引用类型可用于创建特定类型的对象。
 引用值与传统面向对象编程语言中的类相似,但实现不同。
 Date 类型提供关于日期和时间的信息,包括当前日期、时间及相关计算。
 RegExp 类型是 ECMAScript 支持正则表达式的接口,提供了大多数基础的和部分高级的正则表
达式功能。
JavaScript 比较独特的一点是,函数实际上是 Function 类型的实例,也就是说函数也是对象。因
为函数也是对象,所以函数也有方法,可以用于增强其能力。
由于原始值包装类型的存在, JavaScript 中的原始值可以被当成对象来使用。有 3 种原始值包装类
型: Boolean、 Number 和 String。它们都具备如下特点。
 每种包装类型都映射到同名的原始类型。
 以读模式访问原始值时,后台会实例化一个原始值包装类型的对象,借助这个对象可以操作相
应的数据。
 涉及原始值的语句执行完毕后,包装对象就会被销毁。
当代码开始执行时,全局上下文中会存在两个内置对象: Global 和 Math。其中, Global 对象在
大多数 ECMAScript 实现中无法直接访问。不过,浏览器将其实现为 window 对象。所有全局变量和函
数都是 Global 对象的属性。 Math 对象包含辅助完成复杂计算的属性和方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

再读红宝书(第四版) 第五章 基本引用类型 的相关文章

  • 禁用内容安全策略

    当我开发网站时 我经常想看看特定功能在网站上的外观如何 所以我会使用 chrome 开发者工具并经常运行一些 javascript 脚本 我经常发现一些脚本由于内容安全策略 CSP 而无法运行的问题 我完全理解该策略是为了防止跨站点脚本攻击
  • Oo 任何 IDE 中的 javascript 代码补全

    你知道有什么IDE可以自动完成这种代码吗 我这里有一个 javascript 类生成器 function var core bind function method scope if method instanceof Function t
  • 如何将udp发送到udp node.js服务器?

    我对此很陌生 所以我真的不知道我在做什么 但我已经设置了一个 node js udp 服务器 我想从客户端 来自网站 向它发送一个数据包 但我不知道如何在 javascript 中做到这一点 或者是否可能 我不是在研究如何从 Node js
  • 如何使用 selenium 和 Mocha 获取 xPath() 选择的锚标记的文本

    我已经成功选择了 a 标签 我想显示锚标记的文本 但无法这样做 我正在使用 selenium mocha javascript 和 phantomJS 这是我的脚本 详细 var assert require assert var test
  • 如何使用 JavaScript 中的值填充下拉列表?

    我在 Tridion CMS 扩展中的功能区工具栏按钮中添加了一个按钮 单击该按钮后 将显示一个弹出页面 其中包含两个下拉菜单 通过更改第一个下拉控件中的值 我应该填充第二个下拉控件的值 就我而言 我正在使用ASP drop down li
  • jquery 验证错误位置

    这看起来很简单 但我无法弄清楚 我正在使用 jquery 验证插件 我验证所有文件 但我想要的是在输入文本行中显示验证消息警报 例如在电子邮件输入中 请填写电子邮件地址 但现在它出现在所有字段下 在我的html中
  • 如何仅在 NextJS 站点构建期间使用 getInitialProps?

    当使用 NextJS 构建静态站点时 我想要getInitialProps方法仅在构建步骤期间触发 而不是在客户端上触发 在构建步骤中 NextJS 运行getInitialProps 方法 https nextjs org docs fe
  • Ember.js 处理 View 事件后转换到路由

    Setup 我有一个 Ember 应用程序 支持使用 Imgur API 上传图像 我已经有一个工作路线和模板来处理任何 Imgur ID 但我想在上传新图像后转换到此路线 使用返回的 Imgur ID 这是该应用程序的相关部分 http
  • Leaflet js虚构地图

    我是 Leaflet 的新手 我想了解如何创建完全交互式的虚构地图 我有一张图像想要转换为传单地图 该图像基本上像图表一样具有许多连接和点 我想首先将该图像转换为地图 能够将鼠标悬停在这些点上 突出显示它们并显示有关它们的信息 并且还可以在
  • 即使我可以监视其他方法,也无法监视事件处理程序

    我想使用 Jest Jasmine Enzyme 测试 React 中的事件处理程序 MyComponent js import React from react class MyComponent extends React Compon
  • 如何使用 JavaScript 获取没有 HTML 元素的纯文本?

    我的 HTML 中有 1 按钮和一些文本 如下所示 function get content I don t know how to do in here
  • 如果链接包含特定文本,jQuery 将类添加到 href

    我的网站上的列表中有一些动态填充的链接 这些链接链接到文件 是否可以使用 jQuery 查看文件名是否以 pdf 结尾 并在 href 或类似的链接文本以 mp3 结尾时添加一个类 例如 我的列表中有以下链接 文件1 pdf 歌曲1 mp3
  • Google Chrome 106 可拖动导致元素消失

    使用拖放元素时 绝对定位元素中包含的大多数其他元素都会从屏幕上消失 如果我调整窗口大小 这些元素会出现 但在开始拖动时会再次消失 我在最新版本的 Google Chrome 106 和 Beta 版本 107 0 5304 18 以及现在的
  • 如何流式传输 OpenAI 的完成 API?

    我想流式传输结果通过 OpenAI 的 API 完成 https beta openai com docs api reference completions 该文档提到使用服务器发送的事件 https developer mozilla
  • 是否有任何非轮询方式来检测 DOM 元素的大小或位置何时发生变化?

    很长一段时间以来 我一直在寻找一种方法来检测 DOM 元素的大小或位置何时发生变化 这可能是因为窗口调整了大小 或者因为向该元素添加了新的子元素 或者因为在该元素周围添加了新元素 或者因为 CSS 规则已更改 或者因为用户更改了浏览器的字体
  • 使用 JS 合并具有相同值的相邻 HTML 表格单元格

    我已经为此苦苦挣扎了一段时间 我有一个根据一些 JSON 数据自动生成的表 该数据可能会有所不同 我想合并第一列中具有相同值的相邻单元格 例如此表中的 鱼 和 鸟 table tr td fish td td salmon td tr tr
  • 如何使JavaScript函数在Eclipse“大纲视图”中可见?

    我有这样的代码 但如果它在匿名函数中定义 则无法打开函数大纲 类没有问题 我该如何概述something2 请分享一些提示 我可以将所有函数标记为构造函数 但这是无效的方法 start of track event required deb
  • IE11不监听MSFullscreenChange事件

    我正在尝试使用 Bigscreen js 在 IE11 中使用全屏 但 IE11 不监听 MS FullscreenChange 事件 document addEventListener MSFullscreenChange functio
  • 无法在前端使用 JavaScript Fetch API 将文件上传到 FastAPI 后端

    我正在尝试弄清楚如何将图像发送到我的 API 并验证生成的token那是在header的请求 到目前为止 这就是我所处的位置 app post endreProfilbilde async def endreProfilbilde requ
  • 数据表日期范围过滤器

    如何添加日期范围过滤器 like From To 我开始进行常规搜索和分页等工作 但我不知道如何制作日期范围过滤器 我正在使用数据表 1 10 11 版本 My code var oTable function callFilesTable

随机推荐

  • 机器视觉运动控制一体机应用例程(十一)产品全局外观检测

    前面讲述的外观检测的课程中 我们都是以矩形ROI区域框选我们需要检测的外观表面范围 但是很多产品外形通常都不是规则的矩形或者圆形 用矩形或者圆形ROI区域很难对产品的外观进行全局检测 可能会遗漏掉某些细节部分 因此 我们引入了将提取的产品轮
  • 全景解密量子信息技术:高层集中学习,国家战略,三大领域一文看懂

    来源 智东西 内参来源 中国信通院 IPRdaily中文网 10月16日下午 高层就量子科技研究相关前景举行了一次会议 强调当今世界正经历百年未有之大变局 科技创新是其中一个关键变量 要充分认识推动量子科技发展的重要性 加强量子科技发展战略
  • numpy之索引和切片

    索引和切片 一维数组 一维数组很简单 基本和列表一致 它们的区别在于数组切片是原始数组视图 这就意味着 如果做任何修改 原始都会跟着更改 这也意味着 如果不想更改原始数组 我们需要进行显式的复制 从而得到它的副本 copy import n
  • json转xml、xml转json

    一 jar包 所需jar包 二 xml2json 方法一 使用json lib 代码 public String xml2json String xml 创建XMLSerializer对象 XMLSerializer xmlSerializ
  • 计算机房面积标准,机房建设标准与规范[共14页].pdf

    电子信息系统机房设计规范 施行日期 2009 年 6 月 1 日 1 总则 1 0 1 为规范电子信息系统机房设计 确保电子信息系统安全 稳定 可靠地运行 做到技术先进 经 济合理 安全适用 节能环保 制定本规范 1 0 2 本规范适用于建
  • GPU工作原理与理解

    本周看GPU看得有点儿乱 GPU英文全称Graphic Processing Unit 中文翻译为 图形处理器 由于GPU具有高并行结构 highly parallel structure 所以GPU在处理图形数据和复杂算法方面拥有比CPU
  • linux并行计算环境搭建与使用,Windows和Linux系统下并行计算环境MPI和OpenMP的搭建...

    windows平台下在Visual Studio2019配置MPI环境 MPI下载安装 项目配置 右击项目 gt 属性 进行配置 右上角 gt 配置管理器 gt 活动解决方案平台 选择 x64 VC 目录 gt 包含目录 添加 C Prog
  • CUDA 矩阵乘法优化

    矩阵乘法 为了单纯起见 我们这里以方形的矩阵为例子 基本上 假设有两个矩阵 A 和 B 则计算 AB C 的方法如下 for j 0 j lt n j C i j 0 for k 0 k lt n k C i j A i k B k j 一
  • python安装包国内镜像,pip使用国内镜像

    目录 python 安装包镜像 pip下载时使用国内镜像 python 安装包镜像 下载python安装包和pip下载第三方库时 由于一些客观原因 下载外网文件速度很慢 这时可以使用淘宝镜像下载 http npm taobao org mi
  • Qt *.pro文件的INCLUDEPATH和LIBS写法

    Qt pro文件的INCLUDEPATH和LIBS写法 一般的通用 如图所示 INCLUDEPATH usr local qwt 6 1 3 include INCLUDEPATH include LIBS L usr local qwt
  • 基于nginx的tomcat负载均衡和集群(超简单)

    今天看到 基于apache的tomcat负载均衡和集群配置 这篇文章成为javaEye热点 略看了一下 感觉太复杂 要配置的东西太多 因此在这里写出一种更简洁的方法 要集群tomcat主要是解决SESSION共享的问题 因此我利用memca
  • OpenCV的使用——读取、写入和显示图像

    代码 import the cv2 library import cv2 The function cv2 imread is used to read an image Read an image img color cv2 imread
  • Java JDBC连接数据库 查询SELECT

    package com edu import java sql public class jdbctest public static void main String args throws SQLException ClassNotFo
  • ubuntu 查看显卡命令

    要查看 Ubuntu 系统中的显卡信息 可以使用如下命令 lspci grep VGA 这条命令可以列出系统中所有的显卡设备 lshw c video 这条命令可以列出系统中的所有显卡信息 包括型号 芯片厂商和其他详细信息 glxinfo
  • Android颜色透明度(不透明度)对应的十六进制

    颜色值 AARRGGBB 透明度百分比和十六进制对应关系 下面是透明度 再加上平常写得颜色值就表示该颜色值多少透明度了 一 一张表格 基本都概括 方便查找和使用 透明度 十六进制 100 FF 99 FC 98 FA 97 F7 96 F5
  • 计算机操作系统实验三 进程间的通信

    一 实验目的 1 了解什么是管道 2 熟悉UNIX LINUX支持的管道通信方式 3 了解什么是消息 4 熟悉消息传送的机理 二 实验内容 1 编写程序实现进程的管道通信 用系统调用pipe 建立一管道 二个子进程P1和P2分别向管道各写一
  • 数字图像处理 在小波域中分析信号和图像

    一 简述 小波变换是用于分析特征在不同尺度上变化的数据的数学工具 对于信号 特征可以是随时间变化的频率 瞬态或缓慢变化的趋势 对于图像 特征包括边缘和纹理 小波变换主要是为了解决傅立叶变换的局限性而创建的 傅立叶分析是将信号分解为特定频率的
  • sql如何取出前面3行的数据

    sql中如何取出前面3行的数据 用limit 3限制就好 SELECT from tmp test1 order by share desc LIMIT 3 得到结果集
  • Java基础——Java中的枚举类(深入理解,配合代码学习更轻松)

    Java中的枚举类 枚举类的使用 类的对象只有有限个 确定的 比如 星期 一 二三 四 五 六 日 当需要定义一组常量时 强烈建议使用枚举类 配合代码来理解一下 自定义枚举类 JDK5 0之前的版本采用的方式 package com hau
  • 再读红宝书(第四版) 第五章 基本引用类型

    引用值 或者对象 是某个特定引用类型的实例 在 ECMAScript 中 引用类型是把数据和功能组织到一起的结构 经常被人错误地称作 类 虽然从技术上讲 JavaScript 是一门面向对象语言 但ECMAScript 缺少传统的面向对象编