JavaScript学习-05-基本引用类型
引用类型可以称为对象定义,描述了自己的对应应有的属性和方法(类)
对象被认为是某个特定引用类型的实例
函数也是一种引用类型
5.1 Date
-
Date类型将日期保存为1970年1月1日零时至今所经过的毫秒数
-
在不给Date构造函数传参数的情况下,创建的对象将保存当前日期和时间
let now = new Date(); -
Date.parse()方法接收一个表示日期的字符串参数,尝试将这个字符串转换为表示该日期的毫秒数;
如果传给Date.parse()的字符串并不表示日期,则该方法返回NaN
let someDate = new Date(Date.parse('May 23, 2019')); -
如果直接把表示日期的字符串传给Date构造函数,那么Date会在后台调用Date.parse()
let someDate = new Date('May 23, 2019'); // 和上面的是等价的 -
Date.UTC()方法也返回日期的毫秒表示,但是传入的参数不同:传给Date.UTC()的参数是年、零起点月数(1月是0,2月是1,以此类推)、日(1
31)、时(023)、分、秒和毫秒这些参数,只有年和月是必须的,如果不提供日,那么默认为1,其余的参数默认值是0
let y2k = new Date(Date.UTC(2000, 0)); let allFives = new Date(Date.UTC(2005, 4, 5, 17, 55, 55)); // 月数用4表示5 -
Date.UTC()方法和Date.parse()方法一样,也会被Date构造函数隐式调用
-
Date.now()方法,返回表示方法执行日期和时间的毫秒数
let start = Date.now(); doSomething(); let stop = Date.now(); result = stop - start; // 计算代码的执行时间
5.1.1 继承的方法
Date类型重写了Object的toLocaleString()、toString()、valueOf()方法。
-
toLocaleString()方法返回与浏览器的本地环境一致的日期和时间,通常包含针对时间的AM(上午)或PM(下午),但是不包含时区信息 -
toString()方法通常返回带时区信息的日期和时间,而时间也是以24小时表示的// 2019年2月1日零点 toLocaleString() - 2/1/2019 12:00:00 AM toString() - Thu Feb 1 2019 00:00:00 GMT-0800 (Pacific Standard Time) -
valueOf()方法返回的是日期的毫秒表示,因为,可以直接比较两个日期的大小,实际上会调用valueOf()方法,然后比较毫秒值的大小let date1 = new Date(2019, 0, 1); let date2 = new Date(2019, 1, 1); console.log(date1 < date2); // true
5.1.2 日期格式化方法
日期的格式化方法的返回值,会因浏览器而异,因此一般不会使用,通常会自己封装函数来格式化日期
5.1.3 日期/时间组件方法
用的时候再去查
5.2 RegExp
let expression = /pattern/flags;
-
pattern: 模式,包括字符类、限定符、分组、向前查找和反向引用
-
flag: 标记, 每个正则表达式可以带0个或多个flags,用于控制正则表达式的行为
- g: 全局模式,表示查找字符串的全部内容,而不是找到第一个匹配的内容就结束
- i: 不区分带小写,忽略大小写
- m: 多行模式,表示查找到一行文本末尾时会继续查找
- y: 粘附模式,表示只查找从lastIndex开始及之后的字符串
- u: 启用Unicode匹配
- s: dotAll模式,表示元字符.匹配任何字符(包括\n或\r)
let pattern1 = /at/g; // 匹配字符串中所有的'at' let pattern2 = /[bc]at/i; // 匹配第一个'bat'或'cat',忽略大小写 let pattern3 = /.at/gi; // 匹配所有以at结尾的三字符数组,忽略大小写 -
元字符在模式中必须转义:元字符在正则表达式中都有一种或多种特殊功能,如果要匹配这些字符本身,就必须使用反斜杠来转义
( ) [ ] { } \ ^ $ | ? * + .let pattern1 = /[bc]at/i; // 匹配第一个'bat'或'cat',忽略大小写 let pattern2 = /\[bc\]at/i; // 匹配第一个'[bc]at',忽略大小写 let pattern3 = /.at/gi; // 匹配所有以'at'结尾的三字符组合,忽略大小写 let pattern4 = /\.at/gi; // 匹配所有'.at',忽略大小写 -
也可以使用RegExp构造函数来创建,接收两个参数:模式字符串和标记字符串
let pattern1 = /[bc]at/i; // 匹配第一个'bat'或'cat',忽略大小写 let pattern2 = new RegExp('[bc]at', 'i'); // 效果同pattern1,注意这里的参数都是字符串,如果字符串里包含了元字符,则需要二次转义 '\\[bc\\]at' -
也可以基于已有的正则表达式实例,并可选择性的修改它们的标记
let re1 = /cat/g; console.log(re1); // '/cat/g' let re2 = new RegExp(re1, 'i'); console.log(re2); // '/cat/i'
5.2.1 RegExp实例属性
每个RegExp实例都有下列属性
| 属性 | 类型 | 信息 |
|---|---|---|
| global | 布尔值 | 表示是否设置了g标记 |
| ignoreCase | 布尔值 | 表示是否设置了i标记 |
| unicode | 布尔值 | 表示是否设置了u标记 |
| sticky | 布尔值 | 表示是否设置了y标记 |
| lastIndex | 整数 | 表示在源字符串中下一次搜索的开始位置,始终从0开始 |
| multiline | 布尔值 | 表示是否设置了m标记 |
| dotAll | 布尔值 | 表示是否设置了s标记 |
| source | 字符串 | 正则表达式的字面量字符串(不是传给构造函数的模式字符串),没有开头和结尾的斜杠 |
| flags | 字符串 | 正则表达式的标记字符串 |
5.2.2 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' -
如果模式设置了全局标记,则每次调用
exec()方法会返回一个匹配的信息,如果没有设置全局标记,则无论对同一个字符串用多少次exec(),也只会返回第一个匹配的信息let text = 'cat, bat, sat, fat'; let pattern = /.at/; let matches = pattern.exec(text); console.log(matches.index); // 0 console.log(matches[0]); // cat console.log(pattern.lastIndex); // 0 matches = pattern.exec(text); console.log(matches.index); // 0 console.log(matches[0]); // cat console.log(pattern.lastIndex); // 0let text = 'cat, bat, sat, fat'; let pattern = /.at/g; let matches = pattern.exec(text); console.log(mathces.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[1]); // sat console.log(pattern.lastIndex); // 13
-
-
test()-
test()方法接收一个字符串参数,如果输入的文本与模式匹配,则参数返回true,否则返回falselet text = '000-00-0000'; let pattern = /\d{3}-\d{2}-\d{4}/; console.log(pattern.test(text)); // true -
toLocaleString()和toString()返回的都是正则表达式的字面量的形式
-
5.2.3 RegExp构造函数属性
-
RegExp构造函数也有几个属性(在其他语言中,这种属性被称为静态属性,比如Java中的静态属性)
-
这些属性适用于作用域中的所有正则表达式,而且会根据最后执行的正则表达式操作而变化
-
每个属性都有一个全名和简写
全名 简写 说明 input $_ 最后搜索的字符串 lastMatch $& 最后匹配的文本 lastParen $+ 最后匹配的捕获组 leftContext $` input字符串中出现在lastMatch前面的文本 rightContext $' input字符串出现在lastMatch后面的文本 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' } 或者 if (pattern.test(text)) { console.log(RegExp.$_); // 'this has been a short summer' console.log(RegExp['$`']); // 'this has been a' console.log(RegExp['$']); // 'summer' console.log(RegExp['$&']); // 'short' console.log(RegExp['$+']); // 's' } -
RegExp还有其他几个构造函数属性,可以存储最多9个捕获组的匹配项,这些属性通过RegExp.2访问,分别包含了第1~9个捕获组的匹配项
let text = 'this has bben a short summer'; let pattern = /(..)or(.)/g; if (pattern.test(text)) { console.log(RegExp.$1); // sh console.log(RegExp.$2); // t }
5.2.4 模式局限
5.3 原始值包装类型
每当用到某个原始值的方法或属性时,后台都会创建一个相应原始包装类型的对象,从而暴露出操作原始值的各种方法
let s1 = 'some text';
let s2 = s1.substring(2);
// 1. 创建一个String类型的实例
// 2. 调用实例上的特定方法
// 3. 销毁实例
let s1 = new String('some text');
let s2 = s1.substring(2);
s1 = null;
5.3.1 Boolean
很少使用,容易引起误解,建议永远不要使用
let falseObject = new Boolean(false); // true
5.3.2 Number
- 进制转换
let num = 10;
console.log(num.toString()); // '10'
console.log(num.toString(2)); // '1010'
console.log(num.toString(8)); // '12'
console.log(num.toString(10)); // '10'
console.log(num.toString(16)); // 'a'
- 截取小数位数
let num = 10;
console.log(num.toFixed(2)); // '10.00'
如果数值本身的小数位数超过了参数指定的位数,则四舍五入到最近的小数位
let num = 10.005;
console.log(num.toFixed(2)); // '10.01'
- 科学计数法
let num = 10;
console.log(num.toExponential(1)); // 参数表示结果中小数的位数:'1.0e+1'
- 如果想得到数值的最适当的形式,可以使用toPrecision(),方法接收一个参数,表示结果中数字的总位数
let num = 99;
console.log(num.toPrecision(1)); // '1e+2'
console.log(num.toPrecision(2)); // '99'
console.log(num.toPrecision(3)); // '99.0'
- 判断一个数值是否是整数:
Number.isInteger()
console.log(Number.isInteger(1)); // true
console.log(Number.isInteger(1.00)); // true
console.log(Number.isInteger(1.01)); // false
5.3.3 String
5.3.3.1 JavaScript字符
-
给定索引位置的字符:
charAt()let message = 'abcde'; console.log(message.charAt(2)); // 'c' -
查看指定字符的字符编码:
charCodeAt(),参数为索引,返回指定索引位置的码元值let message = 'abcde'; console.log(message.charCodeAt(2)); // 99 -
根据码元值创建字符串:
fromCharCode()console.log(String.fromCharCode(97, 98, 99, 100, 101)); // 'abcde'
5.3.3.2 normalize()方法
5.3.3.3 字符串操作方法
-
concat()方法,+号更经常用let stringValue = 'hello '; let result = stringValue.concat('world'); // 'hello world' // 也可以拼接多个字符串 let result = stringValue.concat('world', '!'); // 'hello world!' -
提取字符串
-
slice(),接收2个参数:字符串开始的位置和字符串结束(不包括)的位置,左闭右开 -
substring(),接收2个参数:字符串开始的位置和字符串结束(不包括)的位置,左闭右开 -
substr(),接收2个参数:字符串开始的位置和返回的子字符串的数量 -
任何情况下,省略第二个参数意味着提取到字符串末尾
let stringValue = 'hello world'; console.log(stringValue.slice(3, 7)); // 'lo w' console.log(stringValue.substring(3, 7)); // 'lo w' console.log(stringValue.substr(3, 7)); // 'lo worl' -
当某个参数是负值时,slice方法将所有负值参数都当成字符串长度加上负参数值
-
当某个参数是负值时,substr方法将第一个负参数值当成字符串长度加上该值,第二个参数转换为0
-
当某个参数是负值时,substring方法会将所有负参数值都转换为0
let stringValue = 'hello world'; console.log(stringValue.slice(-3)); // 'rld' console.log(stringValue.substring(-3)); // 'hello world' console.log(stringValue.substr(-3)); // 'rld' console.log(stringValue.slice(3, -4)); // 'lo w' console.log(stringValue.substring(3, -4)); // 'hel' console.log(stringValue.substr(3, -4)); // ''
-
5.3.3.4 字符串位置方法
-
从头开始查找字符串
indexOf(),从尾开始查找字符串lastIndexOf()let str = 'hello world'; console.log(str.indexof('o')); // 4 console.log(str.lastIndexOf('0')); // 7 -
两个方法都接收第二个参数:表示开始搜索的位置,lastIndexOf会从这个参数指定的位置开始想字符串开头搜索
let str = 'hello world'; console.log(str.indexOf('o', 6)); // 7 console.log(str.indexOf('o', 6)); // 4
5.3.3.5 字符串包含方法
-
startWith()endsWith()includes()let message = 'foobarbaz'; console.log(message.startsWith('foo')); // true console.log(message.endsWith('bar')); // false console.log(message.endsWith('baz')); // true console.log(message.includes('bar')); // true -
startsWith()和includes()方法接收可选的第二个参数,表示开始搜索的位置let message = 'foobarbaz'; console.log(message.startsWith('foo')); // true console.log(message.startsWith('foo', 1)); // false console.log(message.includes('bar')); // true console.log(message.includes('bar', 4)); // false -
endsWith()方法接收可选的第二个参数,表示应该当做字符串末尾的位置,如果不提供,那么默认就是字符串长度let message = 'foobarbaz'; console.log(message.startsWith('bar')); // false console.log(message.endsWith('bar', 6)); // true
5.3.3.6 trim()方法
trim()删除前后空格trimLeft()删除前面的空格trimRight()删除后面的空格
5.3.3.7 repeat()方法
- 该方法接收一个整数参数,表示要将字符串复制多少次
5.3.3.8 padStart()和padEnd()方法
padStart()和padEnd()方法会复制字符串,如果小于指定长度,则在相应一边填充字符,直至满足长度条件
let str = 'foo';
console.log(str.padStart(6)); // ' foo'
console.log(str.padStart(9, '.')); // '......foo'
console.log(str.padEnd(6)); // 'foo '
console.log(str.padEnd(9, '.')); // 'foo......'
可选的第二个参数可以是多个字符,如果是多个字符,则会将其拼接并截断以匹配指定长度
let str = 'foo';
console.log(str.padStart(8, 'bar')); // 'barbafoo'
console.log(str.padStart(2)); // 'foo'
console.log(str.padEnd(8, 'bar')); // 'foobarba'
console.log(str.padEnd(2)); // 'foo'
5.3.3.9 字符串迭代与解构
字符串的原型上暴露了一个@@iterator方法,表示可以迭代字符串的每个字符
let message = 'abc';
let strIterator = message[Symbol.iterator]();
console.log(strIterator.next()); // { value: 'a', done: false }
console.log(strIterator.next()); // { value: 'b', done: false }
console.log(strIterator.next()); // { value: 'c', done: false }
console.log(strIterator.next()); // { value: undefined, done: true }
for (const c of 'abcde') {
console.log(c); // a b c d e
}
let message = 'abcde';
console.log([...message]); // ['a', 'b', 'c', 'd', 'e']
5.3.3.10 字符串大小写转换
toLowerCase()toLocaleLowerCase()toUpperCase()toLocaleUpperCase()
5.3.3.11 字符串模式匹配方法
-
match(),本质上跟RegExp对象的exec()方法,方法接收一个参数,可以是一个正则表达式字符串,也可以是一个RegExp对象let text = 'cat, bat, sat, fat'; let pattern = /.at/; let matches = text.match(pattern); console.log(macthes.index); // 0 console.log(matches[0]); // 'cat' console.log(matches.lastIndex); // 0 -
search(),入参:正则表达式对象或RegExp对象,方法返回模式第一个匹配的位置索引,如果没有找到返回-1let text = 'cat, bat, sat, fat'; let pos = text.search(/at/); console.log(pos); // 1 -
replace(),这个方法接收两个参数,第一个参数可以是RegExp对象或一个字符串,第二个参数可以是一个字符串或一个函数let text = 'cat, bat, sat, fat'; let result = text.replace('at', 'ond'); console.log(result); // 'cond, bat, sat, fat' result = text.replace(/at/g, 'ond'); console.log(result); // 'cond, bond, sond, fond'第二个参数是字符串的情况下,有几个特殊的字符序列,可以用来插入正则表达式操作的值
字符序列 替换文本 $$ $ $& 匹配整个模式的子字符串 $' 匹配的子字符串之前的字符串 $` 匹配的子字符串之后的字符串 $n 匹配第n个捕获组的字符串 $nn 匹配第nn个捕获组的字符串 let text = 'cat, bat, sat, fat'; result = text.replace(/(.at)/g, 'word ($1)'); console.log(result); // word (cat), word (bat), word (sat), word (fat) -
split(),入参:分隔符,可以是字符串,也可以是正则对象;还可以传入第二个参数,即数组大小,确保返回的数组不会超过指定大小
5.3.3.12 localeCompare()方法
比较两个字符串:
- 参数排前面:1
- 参数排后面:-1
- 相等:0
5.4 单例内置对象
5.4.1 Global
兜底对象,针对的是不属于任何对象的属性和方法
5.4.1.1 URL编码方法
encodeURI()encodeURIComponent()decodeURI()decodeURIComponent()
5.4.1.2 eval(),不建议使用
执行JS语句,ECMAScript解释器,接收一个参数:JS语句字符串
5.4.1.3 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构造函数 |
| ... | ... |
5.4.1.4 window对象
虽然没有直接访问Global对象的方式,但浏览器将window对象实现为Global对象的代理,因此,所有全局作用域中声明的变量和函数都变成了window的属性
var color = 'red';
function sayColor() {
console.log(window.color);
}
window.sayColor(); // 'red'
5.4.2 Math
5.4.2.1 Math对象属性
| 属性 | 说明 |
|---|---|
| Math.E | E |
| Math.LN10 | 10为底的自然对数 |
| Math.LN2 | 2为底的自然对数 |
| Math.PI | PI的值 |
5.4.2.2 最大值和最小值
let max = Math.max(3, 54, 32, 16);
console.log(max); // 54
let min = Math.min(3, 54, 32, 16);
console.log(min); // 3
let values = [1, 2, 3, 4, 5, 6];
let max = Math.max(...values); // 6
5.4.2.3 舍入
Math.ceil()向上取整Math.floor()向下取整Math.round()四舍五入Math.fround()返回数值最接近的单精度(32位)浮点值表示
5.4.2.4 随机数
Math.random()0~1范围内的随机数
5.4.2.5 其他方法
Math.abs()绝对值Math.exp()Math.E的x次幂
5.5 小结
无