首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JavaScript 高级程序设计(第 4 版)- 基本引用类型

JavaScript 高级程序设计(第 4 版)- 基本引用类型

作者头像
Cellinlab
发布2023-05-17 15:06:31
发布2023-05-17 15:06:31
98200
代码可运行
举报
文章被收录于专栏:Cellinlab's BlogCellinlab's Blog
运行总次数:0
代码可运行

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

对象被认为是某个特定引用类型的实例。新对象通过使用new操作符后跟一个构造函数来创建。

# Date

Date类型将日期保存为自协调世界时(UTC, Universal Time Coordinate)时间1970年1月1日午夜(零时)至今所经过的毫秒数。在不给Date构造函数传参的情况下,创建的对象保存当前日期和时间。

  • Date.parse()
    • 接收一个表示日期的字符串参数,尝试将这个字符串转换为表示该日期的毫秒数
    • 支持下列格式日期
      • “月/日/年”,如"5/23/2019"或“05/23/2020”;
      • “月名 日, 年”,如"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 的实现)。
    • 如果传入的字符串并不表示日期,则该方法会返回NaN
    • 如果直接把表示日期的字符串传给Date构造函数,那么Date会在后台调用Date.parse()
  • Date.UTC()
    • 返回日期的毫秒表示
    • 参数是年、零起点月数(1 月是 0, 2 月是 1,以此类推)、日(1~31)、时(0~23)、分、秒和毫秒。只有年月是必需的
    • Date.UTC()也会被Date构造函数隐式调用(Date.UTC()隐式调用创建的是本地日期,不是GMT日期)
  • Date.now()
    • 返回表示方法执行时日期和时间的毫秒数

# 继承的方法

与其他类型一样,Date类型重写了toLocaleString()、toString()和valueOf()

  • toLocaleString()方法返回与浏览器运行的本地环境一致的日期和时间,包含对时间的AM或PM,但不包含时区信息
  • toString()方法通常返回带时区信息的日期和时间(24小时制即0-23)
  • Date类型的valueOf()方法根本就不返回字符串,这个方法被重写后返回的是日期的毫秒表示。因此,操作符(如大小于号)可以直接使用他返回的值

# 日期格式化方法

  • toDateString()显示日期中的周几、月、日、年(格式特定于实现);
  • toTimeString()显示日期中的时、分、秒和时区(格式特定于实现)
  • toLocaleDateString()显示日期中的周几、月、日、年(格式特定于实现和地区);
  • toLocaleTimeString()显示日期中的时、分、秒(格式特定于实现和地区);
  • toUTCString()显示完整的 UTC 日期(格式特定于实现)

# RegExp

代码语言:javascript
代码运行次数:0
运行
复制
let expression = /pattern/flags;

上面正则表达式的pattern(模式)可以是任何简单或复杂的正则表达式,包括字符类、限定符、分组、向前查找和反向引用。每个正则表达式可以带零个或多个flags(标记),用于控制正则表达式的行为。

表示匹配模式的标记:

  • g:全局模式,查找字符串的所有内容,而不是找到第一个匹配的内容就结束
  • i:不区分大小写
  • m: 多行模式,表示查找到一行文本末尾时会继续查找
  • y:粘附模式,表示只查找从lastIndex开始及之后的字符串
  • u: Unicode模式,启用Unicode匹配
  • s:dotAll模式,表示元字符.匹配任何字符(包括\n和\r)

元字符在模式中必须转义,包括:([{^$|}])?*+.。元字符在正则表达式中都有一种或多种特殊功能,所以要匹配元字符本身就需要用反斜杠转义

代码语言:javascript
代码运行次数:0
运行
复制
// 匹配第一个“bat”或“cat”,忽略大小写
let pattern1 = /[bc]at/i;
// 匹配第一个“[bc]at”,忽略大小写
let pattern2 = /\[bc\]at/i;
// 匹配所有以“at”结尾的三字符组合,忽略大小写
let pattern3 = /.at/i;
// 匹配所有“.at”,忽略大小写
let pattern4 = /\.at/i;

正则表达式也可以使用RegExp构造函数来创建,接收两个参数:模式字符串和(可选的)标记字符串

  • 因为RegExp的模式参数是字符串,所以在某些情况下需要二次转义。所有元字符都必须二次转义,包括转义字符序列,如\n(\转义后的字符串时\\,在这表达式字符串中则要写成\\\\)
  • 常用字面量转字符串

字面量模式

对应的字符串

/[bc]at/

"\\[bc\\]at"

/\.at/

"\\.at"

/name\/age/

"name\\/age"

RegExp也可以基于已有的正则表达式实例,并可选择性地修改他们的标记

代码语言:javascript
代码运行次数:0
运行
复制
const rel = /cat/g;
console.log(rel); // "/cat/g"
const re2 = new RegExp(rel);
console.log(re2); // "/cat/g"
const re3 = new RegExp(rel, "i");
console.log(re3); // "/cat/i"

# RegExp实例属性

  • global:布尔值,是否开启全局模式
  • ignoreCase: 布尔值,是否忽略大小写
  • unicode: 布尔值,是否开启Unicode匹配
  • sticky:布尔值,是否开启粘附模式
  • lastIndex:整数,表示在源字符串中下一次搜索的开始位置(上次结束的index),始终从0开始
  • multiline:布尔值,是否开启多行模式
  • dotAll: 布尔值,是否开启元字符.全匹配
  • source:正则表达式的字面量字符串(不是传给构造函数的模式字符串),没有开头和结尾斜杠
  • flags:正则表达式的标记字符串

# RegExp实例方法

exec(),主要用于配合捕获组使用,参数是要应用模式的字符串

  • 如果找到了匹配项,则返回包含第一个匹配信息的数组
  • 如果没有找到匹配项则返回null
  • 返回的数组实例包含两个额外的属性:index和input
    • index是字符串中匹配模式的起始位置
    • input是要查找的字符串
    • 数组的第一个元素时匹配整个模式的字符串,其他元素时与表达式中的捕获组匹配的字符串
    • 如果模式中没有捕获组,则数组只包含一个元素
代码语言:javascript
代码运行次数:0
运行
复制
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"

如果在模式上设置了g标记,则每次调用exec()都会在字符串中向前搜索下一个匹配项

lastIndex在非全局模式下始终不变

代码语言:javascript
代码运行次数:0
运行
复制
let text = "cat, bat, sat, fat";
let pattern = /.at/g;
let matches = pattern.exec(text);
console.log(matches.index); // 0
console.log(matches[0]); // cat
console.log(pattern.lastIndex); // 3

matches = pattern.exec(text);
console.log(matches.index); // 5
console.log(matches[0]); // bat
console.log(pattern.lastIndex); // 8

matches = pattern.exec(text);
console.log(matches.index); // 10
console.log(matches[0]); // sat
console.log(pattern.lastIndex); // 13

如果模式设置了粘附标记y,则每次调用exec()就只会在lastIndex的位置上寻找匹配项,粘附标记覆盖全局标记

代码语言:javascript
代码运行次数:0
运行
复制
let text = "cat, bat, sat, fat";
let pattern = /.at/y;

let matches = pattern.exec(text);
console.log(matches.index); // 0
console.log(matches[0]); // cat
console.log(pattern.lastIndex); // 3

// 以索引3对应的字符开头找不到匹配项,因此exec()返回null
// exec()没找到匹配项,于是将lastIndex设置为0
matches = pattern.exec(text);
console.log(matches); // null
console.log(pattern.lastIndex); // 0

// 向前设置lastIndex可以让粘附的模式通过exec()找到下一个匹配项
pattern.lastIndex = 5;
matches = pattern.exec(text);
console.log(matches.index); // 5
console.log(matches[0]); // bat
console.log(pattern.lastIndex); // 8

test(),接收一个字符串参数

  • 如果输入的文本域模式匹配,则参数返回true,否则返回false
  • 适用于测试模式是否匹配,而不需要实际匹配内容的情况

toLocaleString()和toString()都是返回其字面量的形式

# RegExp构造函数属性

全名

简写

说明

input

$_

最后搜索的字符串(非标准特性)

lastMatch

$&

最后匹配的文本

lastParen

$+

最后匹配的捕获组(非标准特性)

leftContext

$`

input字符串中出现在lastMatch前面的文本

rightContext

$'

input字符串中出现在lastMatch后面的文本

-

$1~$9

存储最多9个捕获组的匹配项

代码语言:javascript
代码运行次数:0
运行
复制
let text = "this has been a short summer";
let pattern = /(.)hort/g;

if (pattern.test(text)) {
  console.log(RegExp.input); // this has been a short summer
  console.log(RegExp.leftContext); // this has been a 
  console.log(RegExp.rightContext); // summer 
  console.log(RegExp.lastMatch); // short 匹配整个正则表达式的上一个字符串
  console.log(RegExp.lastParen); // s 捕获组的上一次匹配
}

# 模式局限

缺少特性

  • \A和\Z锚(分别匹配字符串的开始和末尾)
  • 联合及交叉类
  • 原子组
  • x(忽略空格)匹配模式
  • 条件式匹配
  • 正则表达式注释

# 原始值包装类型

为了方便操作原始值,ECMAScript提供了3种特殊的引用类型:Boolean、Number和String。每当用到某个原始值的方法或属性时,后台都会创建一个相应的原始包装类型的对象,从而暴露出操作原始值的各种方法。

  • 引用类型与原始值包装类型的主要区别在于对象的生命周期
    • 在通过new实例化引用后,得到的实例会在离开作用域时被销毁
    • 自动创建的原始值包装对象则只存在于访问它的那行代码执行期间
    • 不能在运行时给原始值添加属性和方法
  • 可以显式地使用Boolean、Number和String构造函数创建原始值包装对象
  • Object构造函数作为一个工厂方法,可以根据传入值的类型返回相应原始值包装类型的实例
  • 所有原始值包装对象都会转换为布尔值true

# Boolean

  • Boolean的实例会重写valueOf()方法,返回一个原始值true或false
  • toString()方法被调用时也会被覆盖,返回字符串'true'或'false'

# Number

  • valueOf()返回Number对象表示的原始数值
  • toLocaleString()和toString()返回数值字符串
  • toString()可选地接收一个表示基数的参数,并返回相应基数形式的数值字符串
  • toFixed()返回包含小数点位数的数值字符串
  • toExponential()返回科学计数法表示的数值字符串(接收一个参数,表示结果中小数的位数)
  • toPrecision()会根据情况返回最合理的输出结果,可能是固定长度,也可能是科学记数法形式
  • isInteger()用于辨别一个数值是否保存为整数
  • IEEE754数值格式有一个特殊的数值范围,在这个范围内二进制可以表示一个整数值(Number.MIN_SAFE_INTEGER(-2^53 + 1)~ Number.MAX_SAFE_INTEGER(2^53 - 1))

# String

  • 每个String对象都有一个length属性,表示字符串中字符的数量
  • JS字符
    • JS字符串由16位码元组成,对于多数字符来说,每16位码元对应一个字符
    • charAt()返回给定索引位置的字符
    • 使用两种Unicode编码混合的策略:UCS-2和UTF-16,对于可采用16位编码的字符(U+0000~U+FFFF),这两种编码实际上是一样的
    • charCodeAt()可以查看指定码元的字符编码,返回指定索引位置的码元值,索引以整数指定
    • fromCharCode()用于根据给定的UTF-16码元创建字符串中的字符
    • 为了正确解析既包含单码元字符又包含代理对字符的字符串,可以使用codePointAt()来代替charCodeAt()
      • codePointAt()接收16位码元的索引并返回该索引位置上的码点
      • 码点是Unicode中一个字符的完整标识,码点可能是16位也可能是32位,codePointAt()可以从指定码元位置识别完整的码点
  • normalize()
    • 某些Unicodez字符可以有很多种编码方式,可以通过BMP字符,也可以通过一个代理对表示
    • Unicode提供4种规范化形式,可以将字符规范化为一致的格式,无论底层字符的代码是什么
    • 4种规范化形式:NFD、NFC、NFKD和NFKC
  • 字符串操作方法
    • concat(),拼接字符串,可以接收任意多个参数
    • 提取子字符串方法:slice()、substr()和substring()
  • 字符串位置方法:indexOf() 和 lastIndex()
  • 字符串包含方法:startsWith()、endsWith()和includes()
  • trim(),删除前后所有空格
  • repeat(),接收一个整数参数,表示将字符串复制多少次,然后返回拼接所有副本后的结果
  • padStart()和padEnd()填充字符串直至满足指定长度
  • 字符串迭代与解构,@@iterator和for-of
  • 大小写转换,toLowerCase()、toLocaleLowerCase()、toUpperCase()和toLocaleUpperCase()
  • 字符串模式匹配方法
    • match(),返回第一个元素时与整个模式匹配的字符串,其余元素则是与表达式中的捕获组匹配的字符串
    • search(),返回模式第一个匹配的位置索引
  • localeCompare()

# 单例内置对象

# Global

ECMA-262规定Global对象为一种兜底对象,它所针对的是不属于任何对象的属性和方法。事实上不存在全局变量或全局函数,在全局作用域中定义的变量和函数都会变成Global对象的属性。

  • URL编码方法
    • encodeURI()和encodeURIComponent()方法用于编码统一资源标识符(URI),以便传给浏览器
    • 使用URI编码方法来编码URI可以让浏览器能够理解它们,同时又以特殊的UTF-8编码替换掉所有无效字符
    • encodeURI()用于对整个URI进行编码,不会编码属于URL组件的特殊字符,比如冒号、斜杠、问号、井号
    • encodeURIComponent()用于编码URI中单独的组件,会编码它发现的所有非标准字符
    • decodeURI()对使用encodeURI()编码过的字符解码
    • decodeURIComponent()解码所有被encodeURIComponent()编码的字符,基本上就是解码所有的特殊值
  • eval()
    • 该方法是一个完整的ECMAScript解释器,接收一个参数,即要执行的ECMAScript字符串
    • 通过eval()执行的代码属于该调用所在上下文,被执行的代码与该上下文拥有相同的作用域链
      • 上下文中的变量可以在eval()调用内部被引用
      • eval()内部定义一个函数或变量,可以在外部代码中引用
    • 通过eval()定义的任何变量和函数都不会被提升,因为在解析代码的时候,它们包含在一个字符串中,只是在eval()执行的时候才会被创建
    • 在严格模式下,在eval()内部创建的变量和函数无法被外部访问
  • Global对象属性

属性

说明

undefined

特殊值undefined

NaN

特殊值NaN

Infinity

特殊值Infinity

Object

Object的构造函数

Array

Array的构造函数

Function

Function的构造函数

Boolean

Boolean的构造函数

String

String的构造函数

Number

Number的构造函数

Date

Date的构造函数

RegExp

RegExp的构造函数

Symbol

Symbol的构造函数

Error

Error的构造函数

EvalError

EvalError的构造函数

RangerError

RangerError的构造函数

ReferenceError

ReferenceError的构造函数

SyntaxError

SyntaxError的构造函数

TypeError

TypeError的构造函数

URIError

URIError的构造函数

  • window对象
    • 浏览器将window对象实现为Global对象的代理。因此,所有全局作用域中声明的变量和函数都变成了window的属性

# Math

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

Math对象属性

属性

说明

Math.E

自然对数的基数e的值

Math.LN10

10为底的自然对数

Math.LN2

2为底的自然对数

Math.LOG2E

以2为底e的对数

Math.LOG10E

以10为底e的对数

Math.PI

π的值

Math.SQRT1_2

1/2的平方根

Math.SQRT2

2的平方根

min()和max()

  • 接受任意多个参数

舍入方法

  • Math.ceil() 向上舍入为最接近的整数
  • Math.floor() 向下舍入为最接近的整数
  • Math.round() 执行四舍五入
  • Math.fround() 返回数值最接近的单精度浮点值表示

random()

  • Math.random()返回一个0~1范围内的随机数,其中包含0但是不包含1
代码语言:javascript
代码运行次数:0
运行
复制
// number = Math.floor(Math.random() * total_number_of_choices + first_possible_value);
// 从1~10选一个
let num =  Math.floor(Math.random() * 10 + 1);
// 2~9,可选总数是9,最小可能值是2
let num2 = Math.floor(Math.random() * 9 + 2);

  • 如果为了加密而需要生成随机数,建议使用window.crypto.getRandomValues()

其他方法

方法

说明

Math.abs(x)

返回x的绝对值

Math.exp(x)

返回Math.E的x次幂

MAth.expm1(x)

返回Math.exp(x)-1

Math.log(x)

返回x的自然对数

Math.log1p(x)

等于1+Math.log(x)

Math.pow(x, power)

返回x的power次幂

Math.hypot(...nums)

返回nums中每个数平方和的平方根

Math.clz32(x)

返回32位整数x的前置零的数量

Math.sign(x)

返回表示x符号的1、0、-0或-1

Math.trunc(x)

返回x的整数部分,删除所有小数

Math.sqrt(x)

返回x的平方根

Math.cbrt(x)

返回x的立方根

Math.acos(x)

返回x的反余弦

Math.acosh(x)

返回x的反双曲余弦

Math.asin(x)

返回x的反正弦

Math.asinh(x)

返回x的反双曲正弦

Math.atan(x)

返回x的反正切

Math.atanh(x)

返回x的反双曲正切

Math.atan2(y, x)

返回y/x的反正切

Math.cos(x)

返回x的余弦

Math.sin(x)

返回x的正弦

Math.tan(x)

返回x的正切

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/11/30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • # Date
    • # 继承的方法
    • # 日期格式化方法
  • # RegExp
    • # RegExp实例属性
    • # RegExp实例方法
    • # RegExp构造函数属性
    • # 模式局限
  • # 原始值包装类型
    • # Boolean
    • # Number
    • # String
  • # 单例内置对象
    • # Global
    • # Math
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档