一,基本引用类型:
1,Date:
1.1 Date类型简介及两个辅助方法:
Date类型将日期保存世界时间 1970年1月1日零时 至今所经过的毫秒数。使用这种存储格式,Date类型可以精确表示1970年1月1日之前及之后285161年的日期。
>>使用new操作符来调用Date构造函数来 创建日期对象:
let nowDate = new Date();
不给Date构造函数传参的话,创建的对象保存的是当前日期和时间。
所有日期实现都必须支持下列日期格式:
> 月/日/年 如 12/05/2020
> 月名 日,年 如 Dec 23, 2020
>周几 月名 日 年 时:分:秒 时区 如 Tue Dec 23 2020 00:00:00 GMT-0700
>ISO 8601扩展格式 YYYY-MM-DDTHH:mm:ss:sssZ 如 2020-12-15T00:00:00(只适用于兼容ES5的实现)
例如要创建一个表示 2020年12月05日的日期时间对象,代码如下:
let someDate = new Date(Date.parse('Dec 05, 2020'))
>>要基于其他日期和时间创建日期对象,必须传入其毫秒表示。提供了两个辅助方法 Date.parse() 和 Date.UTC()。
Date.parse()方法一个表示日期的字符串参数,尝试将这个字符串转换为表示该日期的毫秒数,如果传给Date.parse()的字符串并不表示日期,则该方法会返回NaN,如果直接把表示日期的字符串传给Date构造函数,那么Date会在后台调用Date.parse(),示例如下:
//下面面两行代码时等价的
let someDate = new Date(Date.parse('Dec 23, 2020'))
let newDate = new Date('Dec 23, 2020')
Date.UTC()方法也返回日期的毫秒表示,使用的是跟Date.parse()不同的信息来生成这个值,传给Date.UTC()的参数是年,零起点月数(1月是0,2月是1.....)日(0-31),时(0-23),分,秒和毫秒。这些参数中,只要前面两个年和月是必须的,如果不提供日,那么默认为1日,其他参数的默认值都是0;
示例如下:
var msecs = new Date(Date.UTC(2020,12,6));
console.log(msecs); //Wed Jan 06 2021 08:00:00 GMT+0800 (中国标准时间)
let allfive = new Date(Date.UTC(2005,4,5,17,55,55))
console.log(allfive);//Fri May 06 2005 01:55:55 GMT+0800 (中国标准时间)
还提供了Date.now()方法,表示执行时日期和时间的毫秒数,这个方法可方便的用在代码分析中:示例如下:
//起始时间:
let start = Date.now();
doSomething()//调用函数
//结束时间:
let stop = Date.now();
result = stop - start;
1.2 继承的方法:
Date重写了toLocaleString(),toString(),和 valueOf()方法,重写后这些方法的返回值与其他类型不同:
Date类型的toLocaleString()方法返回与浏览器运行的本地环境一直的日期和时间,格式中包含针对时间的AM或PM,不包含时区信息(具体格式可能因浏览器不同);
toString()方法通常返回带时区信息的日期和时间,而时间也是24小时制(0-23)表示的;
示例如下:
var d=new Date();
var n=d.toLocaleString();
var ns=d.toString();
console.log(n)//2020/12/13 下午4:21:35
console.log(ns)//Sun Dec 13 2020 16:21:35 GMT+0800 (中国标准时间)
Date类型的valueOf()方法,被重写后返回的是日期的毫秒表示,因为,操作符可以直接使用它返回的值,示例如下:
let d1 = new Date(2019,0,1);
let d2 = new Date(2019,1,1);
console.log(d1 < d2)//true
console.log(d1 > d2)//false
1.3 日期格式化方法:
Date类型有几个专门用于格式化日期的方法,都会返回字符串:
① toDateString()显示日期中的周几,月,日,年;
② toTimeString()显示日期中的时,分,秒和时区;
③ toLocaleDateString() 显示日期中的周几,月,日年;(格式特定于实现和地区)
④ toLocaleTimeString() 显示日期中的时,分,秒(格式特定于实现和地区)
⑤ toUTCString() 显示完整的UTC日期
这些方法和 toLocaleString(),toString()一样,会因浏览器而异,因此不能用于在用户界面上一致的显示日期;
let d1 = new Date();
let d2 = d1.toDateString();
let d3 = d1.toTimeString();
let d4 = d1.toLocaleDateString();
let d5 = d1.toLocaleTimeString();
let d6 = d1.toUTCString();
console.log(d2)//Sun Dec 13 2020
console.log(d3)//16:35:33 GMT+0800 (中国标准时间)
console.log(d4)//2020/12/13
console.log(d5)//下午4:50:14
console.log(d6)//Sun, 13 Dec 2020 08:51:56 GMT
1.4 日期/时间组件方法:(常用方法整理)
方法 | 说明 |
getTime() | 返回日期的毫秒表示,与valueof()相同 |
setTime() | 设置日期的毫秒数,从而修改整个日期 |
getFullYear() | 返回四位数年(即2020,而不是20) |
getMonth() | 返回日期的月(0表示1月,11表示12) |
getDate() | 返回日期中的日(0-31) |
getDay() | 返回日期中表示周几的数值(0表示周几,6表示周六) |
getHourse() | 返回日期中的时(0-23小时) |
getMinutes() | 返回日期 中的分(0-59) |
getSeconds() | 返回日期中的秒(0-59) |
2,RegExp:
ECMAScript通过RegExp类型支持正则表达式,正则表达式使用类似perl的简洁语法来创建;
let expression = /pattern/flags;
2.1正则表达式定义方式:
pattern(模式)可以使任何简单或复杂的正则表达式,包括字符类,限定类,分组,向前查找和反向引用;每个正则表达式可以带0个或多个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 pattern2 = /.at/gi;
与其他语言中的正则表达式类似,所有元字符在模式中也必须转义,包括:( [ { \ ^ $ | } ] ) ? * + .
元字符在正则表达式中都有一种或多种特殊功能,所以要匹配上面这些字符串本身,就必须使用反斜杠来转义:示例如下:
//匹配第一个'bat'或'cat',忽略大小写
let pattern1 = /[bc]at/i;
//匹配第一个'[bc]at',忽略大小写
let pattern2 = /\[bc\]at/i;
//匹配字符串中所有以 'at' 结尾的三字符组合,忽略大小写
let pattern3 = /.at/gi;
//匹配所有 '.at',忽略大小写
let pattern4 = /\.at/gi;
pattern1匹配‘bat’或者‘cat’,不区分大小写;要直接匹配‘'[bc]at'’,左右中括号都必须像pattern12中那样使用反斜杠转义;
pattern3中,点号表示‘at’前面的任意字符都可以匹配,如果想匹配'.at',那么要像 pattern4中那样对点号进行转义;
正则表达式还可以使用RegExp构造函数来穿件,接收两个参数:模式字符串(可选的) 标记字符串。任何使用字面量定义的正则表达式也可以通过构造函数来创建;
示例如下:
//字面量:匹配第一个'bat'或'cat',忽略大小写
let pattern1 = /[bc]at/i;
//构造函数:匹配第一个'bat'或'cat',忽略大小写
let pattern2 = new RegExp("[bc]at",'i')
使用RegExp也可以基于已有的正则表达式实例,并可选择性的修改它们的标记:
const re1 = /cat/g;
console.log(re1)// '/cat/g'
const re2 = new RegExp(re1);
console.log(re2)// '/cat/g'
const re3 = new RegExp(re1,'i');
console.log(re3)// '/cat/i'
2.2 RegExp实例属性:
每个RegExp实例都有下列属性,提供有关模式的各方面信息;不过以下实际开发中用的并不多,因为模式声明中包含这些信息;
① global:布尔值,表示是否设置了 g 标记;
② ignoreCase:布尔值,表示是否设置了 i 标记;
③ unicode:布尔值,表示是否设置了 u 标记;
④ sticky布尔值:表示是否设置了y标记;
⑤ lastIndex:整数,表示在源字符串中下一次搜索的开始位置,始终从 0 开始;
⑥ multiline:布尔值,表示是否设置了 m 标记;
⑦ dotAll:布尔值,表示是否设置了 s 标记;
⑧ source:正则表达式的字面量字符串(不是传给构造函数的模式字符串)。没有开头和结尾的斜杠;
⑨ flags:正则表达式的标记字符串,始终以字面量而非传入构造函数的字符串模式返回(没有前后斜杠);
示例如下:
let pattern1 = /\[bc\]at/i;
console.log(pattern1.global)// false
console.log(pattern1.ignoreCase)// true
console.log(pattern1.multiline)// false
console.log(pattern1.lastIndex)// 0
console.log(pattern1.source)// '\[bc\]at'
console.log(pattern1.flags)// 'i'
let pattern2 = new RegExp('\\[bc\\]at','i');
console.log(pattern2.global)// false
console.log(pattern2.ignoreCase)// true
console.log(pattern2.multiline)// false
console.log(pattern2.lastIndex)// 0
console.log(pattern2.source)// '\[bc\]at'
console.log(pattern2.flags)// 'i'
注意:pattern1和pattern2中的 source和flags属性是相同的,source和flags属性返回的是规范化之后可以在字面量中使用的形式;;
2.3 RegExp实例方法:
RegExp实例主要方法是 exec(),用于配合捕获组使用;
这个方法只接收一个参数:模式字符串。如果找到了匹配项,则返回包含第一个匹配信息的数组;如果没找到匹配项,则返回nul;
① 返回的数组是Array的实例,包含 index和input属性,index是字符串中匹配模式的起始位置,input是要查找的字符串。这个数组中第一个字符串是匹配整个模式的字符串,其他元素是与表达式中的捕获组匹配的字符串,如果模式中没有捕获组,则数组中包含一个元素。
示例如下:
let txt = 'mom and dad and baby';
let pattern = /mom (and dad( and baby)?)?/gi;
let matches = pattern.exec(txt);
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’,以及外部匹配项 ‘dad dad’ 或者 ‘and dad and baby’。调用exec()后找到了一个匹配项,整个字符串匹配模式,所以matchs数组的index是0;
数组的第一个元素是匹配的整个字符串:matches[0] 为‘mom and dad and baby’;
数组的第二个元素是匹配第一个捕获组的字符串:matches[1]为 ‘and dad and baby’;
数组的第三个元素是匹配第二个捕获组的字符串:matches[2]为‘and baby’;
② 如果模式设置了全局标记,则每次调用exec()方法都会返回一个匹配的信息;
如果没有设置全局标记,则无论对同一个字符串调用多少次exec(),也只会返回第一个匹配信息;
示例如下:
let txt = 'cat, bat, sat, fat';
let pattern = /.at/;
//未设置全局模式:调用exec()只返回第一个匹配项,lastIndex非全局模式始终不变;
let matches = pattern.exec(txt);
console.log(matches.index)//0
console.log(matches[0])//cat
console.log(pattern.lastIndex)//0
matches = pattern.exec(txt);
console.log(matches.index)//0
console.log(matches[0])//cat
console.log(pattern.lastIndex)//0
设置全局标记:
//设置全局标记:每次调用exec()都会返回字符串中的下一个匹配项,知道搜索到字符串末尾。lastIndex属性每次都会变化;
let txt = 'cat, bat, sat, fat';
let pattern = /.at/g;
let matches = pattern.exec(txt);
console.log(matches.index)//0
console.log(matches[0])//cat
console.log(pattern.lastIndex)//3
matches = pattern.exec(txt);
console.log(matches.index)//5
console.log(matches[0])//cat
console.log(pattern.lastIndex)//8
matches = pattern.exec(txt);
console.log(matches.index)//10
console.log(matches[0])//cat
console.log(pattern.lastIndex)//13
③ 如果模式设置了粘附标记y,则每次调用exec()就只会在lastIndex的位置上寻找匹配项,粘附标记覆盖全局标记;
let txt = 'cat, bat, sat, fat';
let pattern = /.at/y;
let matches = pattern.exec(txt);
console.log(matches.index)//0
console.log(matches[0])//cat
console.log(pattern.lastIndex)//3
//以索引5对应的字符串开头找不到匹配项,因此exec()返回null;
//exec()未找到匹配项,所以返回0;
matches = pattern.exec(txt);
console.log(matches)//null
console.log(pattern.lastIndex)//0
//向前设置lastIndex可以让粘附的模式通过exec()找到下一个匹配项
pattern.lastIndex = 5;
matches = pattern.exec(txt);
console.log(matches.index)//5
console.log(matches[0])//bat
console.log(pattern.lastIndex)//8
④ 正则表达式另一个方法是 test(),接收一个字符串参数,如果输入的文本与模式匹配,则显示匹配成功,返回true,否则返回false,适用于只想测试模式是否匹配,而不需要实际匹配内容的情况,
test()经常用在if语句中:
let txt = '000-00-0000';
let pattern = /\d{3}-\d{2}-\d{4}/;
if(pattern.test(txt)){
console.log('哈哈哈哈');//'哈哈哈哈'
无论正则表达式是怎么创建的,继承的方法 toLocaleString()He toString()都返回正则表达式的字面量表示,valueOf()方法返回正则表达式本身 如:
let pattern = new RegExp('\\[bc\\]at','gi');
console.log(pattern.toLocaleString())// /\[bc\]at/gi
console.log(pattern.toString())// /\[bc\]at/gi
2.4 RegExp构造函数属性:
下表列出了构造函数属性:
全名 | 简写 | 说明 |
input | $_ | 最后搜索的字符串(非标准特性) |
lastMatch | $& | 最后匹配的文本 |
lastParen | $+ | 最后匹配的捕获组(非标准特性) |
leftContext | $` | input字符串中出现在lastParen前面的文本 |
rightContext | $' | input字符串中出现在lastParen后面的文本 |
通过上面属性可以提取出于exec()和test()执行的操作相关的信息:如下示例:
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
}
二,原始值包装类型:
每当用到某个原始值的方法或属性时,后台都会创建一个相应原始包装类型的对象,从而暴露出操作原始值的各种方法;
示例如下:
let s1 = "some text";//原始值
let s2 = s1.substring(2);
console.log(s2);//'me text' 正常运行
原始值本身不是对象,因此所逻辑上不应该有方法,以上代码能够正常运行,是因为后台进行了很多处理,具体来说,当第二行访问s1的时,是以读模式访问的,也就是要从内存中读取变量保存的值,后台会执行以下三步:
① 创建一个string类型的实例
② 调用实例上的特殊方法
③ 销毁实例
可以把以上三步想象成执行了如下三步代码:
let s1 = new String("some text");
let s2 = s1.substring(2);
s1 = null;
引用类型与原始值包装类型的主要区别在于对象的生命周期,在通过new实例化引用类型后,得到的实例会在离开作用域时被销毁,而自动创建的原始值包装对象则只存在于访问它的哪行代码执行期间。这意味着不能在运行时给原始值添加属性和方法;如下示例:
let s1 = "some text";
s1.color = 'blue';//本行代码运行时会临时创建一个String对象,当下一行代码执行时,这个对象已经被销毁了;
console.log(s1.color);//报错,因本行代码在这里创建了自己的String对象,这个对象没有color属性;
1.Boolean:
要创建一个Boolean对象,就使用Boolean构造函数并传入true或者false。示例如下:
let boolObject = new Boolean(true);
Boolean会重写valueOf()方法,返回一个原始值true或false,toString()方法被调用时也会被覆盖,返回字符串true或者false,Boolean对象使用较少,并建议慎用,尤其是在Boolean表达式中使用Boolean对象时,示例如下:
let falseObject = new Boolean(false);
let res = falseObject && true;
console.log(res)//true;
let falseVlaue = false;
let rest = falseVlaue && true;
console.log(rest)//false;
在Boolean算术中,false && true 等于false,因这个表达式是对falseObject对象,在布尔表达式中都会自动转换为true,所以falseObject在这个表达式里实际上表示一个true值,也就是true&&true 等于true;
原始值和Boolean对象(引用值)的区别:
① typeof操作符对原始值返回 boolean,对引用值返回 object
② Boolean对象是Boolean类型的实例,在使用instanceof操作符时返回true,对原始值则返回false
示例如下:
let falseObject = new Boolean(false);
let falseVlaue = false;
console.log(typeof falseObject)//object
console.log(typeof falseVlaue)// Boolean
console.log(falseObject instanceof Boolean)// true
console.log(falseVlaue instanceof Boolean)// false
2.Number:
要创建一个Number对象,就要使用Number构造函数,如下示例:
let numberObject = new Number(2)
与Boolean类似,Number类型重写了 valueOf(),toLocaleString()和toString()方法,valueOf()返回Number对象表示的原始数值,另外两个返回数值字符串,toString()方法可选地接受一个表示基数的参数,并返回基数形式的数值字符串;示例如下:
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'
2.1.1. toFixed()方法
返回包含指定小数点位数的数值字符串,如下示例:
let num = 10;
console.log(num.toFixed(2));//'10.00'
toFixed()方法可以表示由 0-20 个小数位的数值;
2.1.2 toExponential()方法
返回以科学计数法表示的数值字符串,与toFixed()方法一样,也接收一个参数,表示结果中小数的位数;
示例如下:
let num = 9;
console.log(num.toExponential(1));//'9.0e+0'
console.log(num.toExponential(2));//'9.00e+0'
console.log(num.toExponential(3));//'9.000e+0'
在处理原始数值和引用树脂制,typeof()和instanceof操作符会返回不同的结果:
原始数值在调用typeof时始终返回 number,
而Number对象则返回 object,类似的,
Number对象是Number类型的实例,而原始值不是;
示例如下:
let numberObject = new Number(10);
let numberValue = 10;
console.log(typeof numberObject);// 'object '
console.log(typeof numberValue);// 'number'
console.log(numberObject instanceof Number);// 'true'
console.log(numberValue instanceof Number);// 'false'
2.1.3 isInteger方法与安全整数
ES6新增方法,Number.isInteger()方法,用于辨别一个数值是否保存为整数。(有时小数位的 0 可能会让人误以为数值是一个浮点值);
示例如下:
console.log(Number.isInteger(1));// 'true'
console.log(Number.isInteger(1.00));// 'true'
console.log(Number.isInteger(1.01));// 'false'
IEEE 754数值格式有一个特殊的数值范围,在这个范围内二进制值可以表示一个整数值,这个数值范围从Number.MIN_SAFE+INTEGER(-2的53次方 + 1) 到Number.MAX_SAFE+INTEGER(-2的53次方 - 1)。对超出这个范围的数值,即使尝试保存为整数 IEEE 754编码格式也意味着二进制值可以能会表示一个我完全不同的数值。为了鉴别整数是否在这个范围内,可以使用Number.isSafeInteger()方法;
示例如下:
console.log(Number.isSafeInteger(-1 * (2 ** 53)));// 'false'
console.log(Number.isSafeInteger(-1 * (2 ** 53) + 1));// 'true'
console.log(Number.isSafeInteger(2 ** 53));// 'true'
console.log(Number.isSafeInteger((2 ** 53) - 1));// 'false'
3.String:
要创建一个String对象,就要使用String构造函数,如下示例:
let stringObject = new String('javaScript');
String类型解析和操作字符串的方法:
3.1 JavaScript字符
JavaScript 字符串由16位 code unit 组成,字符串的length 属性表示字符串包含多少位 code unit;
如下示例:
let msg = 'javaScript';
console.log(msg.length)// 10
① charAt()方法:返回给定索引位置的字符,查找指定索引位置的16位code unit ,并返回该 code unit对应的字符;示例如下:
let msg = 'javaScript';
console.log(msg.charAt(2))// 'v'
JavaScript字符串使用了两种Unicode编码混合的策略:UCS-2和UTF-16,对于可以采用16位编码的字符(U+0000~U+FFFF),两种编码实际上是一样的;
② charCodeAt()方法:返回指定索引位置的code unit值,索引以整数指定;示例如下:
let msg = 'javaScript';
console.log(msg.charCodeAt(2))// '118'
③ formCharCode()方法:用于根据给定的UTF-16 code unit 创建字符串中的字符,可以接受任意多个数值,返回将所有数值对应的字符拼接起来的字符串;
3.2 字符串操作方法:concat()
concat() 用于将一个或多个字符串拼接成一个新字符串,示例如下:
let stringValue = 'javaScript ';
let res = stringValue.concat('nice')
console.log(res)//'javaScript nice'
concat() 方法可以接收任意多个参数,因此可以一次性拼接多个字符串,示例如下:
let stringValue = 'javaScript ';
let res = stringValue.concat('nice','!')
console.log(res)//'javaScript nice!'
更常用的拼接字符串的方式是使用 + 号操作符,多数情况下,对于拼接多个字符串来说,使用加号更方便;
3.3 字符串操作方法:slice() 、substr()、substring()
slice() 、substr()、substring() 都可以从字符串中提取子字符串,返回调用他们的字符串的一个子字符串,都接受一个或者两个参数;
slice(子字符串开始位置,子字符串结束位置)
substring(子字符串开始位置,子字符串结束位置)
substr(子字符串开始位置,返回的子字符串数量)
任何情况下省略第二个参数意味着提取到字符串末尾,也不会修改调用他们得字符串,只会返回提取到的原始新字符串值;
示例如下:
let strVal = 'javaScritp nice';
console.log(strVal.slice(3));//'aScritp nice'
console.log(strVal.substr(3));//'aScritp nice'
console.log(strVal.substring(3));//'aScritp nice'
console.log(strVal.slice(2,6));//'vaSc'
console.log(strVal.substring(2,6));//'vaSc'
console.log(strVal.substr(2,6));//'vaScri' 第二个参数表示返回的字符数
当某个参数是负值时,slice() 、substr()、substring() 返回又有不同:
slice():将所有负值参数都当成字符串长度加上负参数值;
substr():将第一个负参数值当成字符串长度加上该值,将第二个负参数值转换为0;
substring():将所有负参数值转换为0;
示例如下:
let strVal = 'javaScritp nice';
console.log(strVal.slice(-3));//'ice'
console.log(strVal.substr(-3));//'ice'
console.log(strVal.substring(-3));//'javaScritp nice'
console.log(strVal.slice(2,-3));//'vaScritp n'
console.log(strVal.substring(2,-3));//'ja'
console.log(strVal.substr(2,-3));//''
3.4 字符串位置方法
indexOf()和lastIndexOf() 用于在字符串中定位子字符串;
indexOf()从字符串开头开始查找子字符串;
lastIndexOf()从字符串末尾开始查找子字符串;
示例如下:
let strVal = 'javaScritp nice';
console.log(strVal.indexOf('i'));//7
console.log(strVal.lastIndexOf('i'));//12
indexOf()和lastIndexOf()都可以接收第二个参数:表示开始搜索的位置,
indexOf()会从这个参数指定的位置开始向字符串末尾搜索,忽略该位置之前的字符;
lastIndexOf()则会从这个参数指定的位置开始向字符串开头搜索,忽略该位置之前后到字符串末尾的字符;
示例如下:
let strVal = 'javaScritp nice';
console.log(strVal.indexOf('i',5));//7
console.log(strVal.lastIndexOf('i',5));//-1
示例如下:在字符串中找到所有的目标子字符串:
let strVal = 'JavaScript is the best language in the world. There is no substitute for it';
let pos = new Array();
let posVal = strVal.indexOf('e');
while(posVal > -1){
pos.push(posVal);
posVal = strVal.indexOf('e',posVal + 1);
}
console.log(pos);//[16, 19, 30, 37, 48, 50, 67]
3.5 字符串包含方法
startsWith() endsWith() includes() 用于判断字符串中是否包含另一个字符串的方法,这些方法都会从字符串中搜索传入的字符串,并返回一个表示是否包含的布尔值,
startsWith() 检查开始于索引0的匹配
endsWith() 检查开始于索引 string.length - substring.length() 的匹配项
includes() 检查整个字符串;
示例如下:
let strVal = 'javascript';
console.log(strVal.startsWith('java'))//true
console.log(strVal.startsWith('jsp'))//false
console.log(strVal.endsWith('ript'))//true
console.log(strVal.endsWith('jsp'))//false
console.log(strVal.includes('java'))//true
console.log(strVal.includes('jsp'))//false
startsWith()和includes()方法接收可选的第二个参数,表示开始搜索的位置,传入第二个参数,这两个方法从指定位置向着字符串末尾搜索,忽略该位置之前的所有字符串,示例如下:
let strVal = 'javascript';
console.log(strVal.startsWith('java'))//true
console.log(strVal.startsWith('java',1))//false
console.log(strVal.includes('java'))//true
console.log(strVal.includes('java',2))//false
endsWith() 接收可选的第二个参数,表示应该当做字符串末尾的位置,如果提供这个参数,默认就是字符串的长度,提供这个参数,就好像字符串只有那么多字符一样,示例如下:
let strVal = 'javascript';
console.log(strVal.endsWith('java'))//false
console.log(strVal.endsWith('java',4))//true
3.6 trim()方法
创建字符串一个副本,删除前后所有空格符,再返回结果,示例如下:
let strVal = ' javascript ';
console.log(strVal.trim())//'javascript'
console.log(strVal)//' javascript '
3.7 repeat()方法
接收一个整数参数,表示要将字符串复制多少次,然后返回拼接所有副本后的结果;
示例如下:
let strVal = 'js ';
console.log(strVal.repeat(5) + 'nice')//'js js js js js nice'
3.8 字符串迭代与解构
字符串的原型上有一个@@iterator方法,表示可以迭代字符串的每个字符,可以手动使用迭代器,示例如下:
let strVal = 'abc';
let strInterator = strVal[Symbol.iterator]();
console.log(strInterator.next())// {value: "a", done: false}
console.log(strInterator.next())// {value: "b", done: false}
console.log(strInterator.next())// {value: "c", done: false}
console.log(strInterator.next())// {value: undefined, done: true}
//在for循环中可以通过这个迭代器按顺序访问每个字符:
for (const c of 'abcde'){
console.log(c)
}
//a
//b
//c
//d
//e
有了迭代器后,字符串就可以通过结构操作来解构了,例如可以更方便的吧字符串分割为字符数组,示例如下:
let strVal = 'abcde';
console.log([...strVal])// ["a", "b", "c", "d", "e"]
3.9 字符串大小写转换
涉及字符串大小写转换的方法有:toLowerCase() toLocaleLowerCase() toUpperCase() toLocaleUpperCase();
toLowerCase() 和 toUpperCase() 方法是原来就有的,与java.lang.String中的方法同名,toLocaleLowerCase()和toLocaleUpperCase() 旨在基于特定地区实现;
示例如下:
let strVal = 'abcde javascaript';
console.log(strVal.toLocaleUpperCase())//'ABCDE JAVASCARIPT'
console.log(strVal.toUpperCase())//'ABCDE JAVASCARIPT'
console.log(strVal.toLocaleLowerCase())//'abcde javascaript'
console.log(strVal.toLowerCase())//'abcde javascaript'
3.10 字符串模式匹配方法
① match() 方法:接收一个参数,可以使一个正则表达式字符串,也可以是一个RegExp对象,示例如下:
let strVal = 'cat, bat, sat, fat';
let pattern = /.at/;
let matches = strVal.match(pattern);//等价于 pattern.exec(text)
console.log(matches.index)// 0
console.log(matches[0])// cat
console.log(pattern.lastIndex)// 0
// match()方法第一个元素是与整个模式匹配的字符串,其余元素则是与表达式中的捕获组匹配的字符串(如果有的话)
② search()方法,也是查找模式匹配的字符串方法,参数与match()一样(正则表达式字符串或者RegExp对象),返回模式第一个匹配的位置索引,如果没找到返回-1.始终从字符串开头向后匹配模式:
示例如下:
let strVal = 'cat, bat, sat, fat';
let pos = strVal.search(/at/);
console.log(pos)// 1 这里search(/at/)返回1 即“at”的第一个字符在字符串中的位置
③ replace()方法:简化子字符串替换操作,接收两个参数,第一个参数可以使一个RegExp对象或者一个字符串,第二个参数可以使一个字符串或者一个函数。如果第一个参数可是字符串,那么只会替换第一个子字符串,想要替换所有子字符串,第一个参数必须为正则表达式并且带全局标记,示例如下:
let strText = 'cat, bat, sat, fat';
let pos = strText.replace('at','ond');
console.log(pos)// 'cond, bat, sat, fat'
let post = strText.replace(/at/g,'ond');
console.log(post)// 'cond, bond, sond, fond'
④ split()方法:根据传入的分隔符将字符串拆分成数组,作为分隔符的参数可以是字符串,也可以是RegExp对象,还可传入第二个参数,即数组大小,确保返回的数组不会超过指定大小;示例如下:
let strText = 'cat,bat,sat,fat';
console.log(strText.split(','))//["cat", "bat", "sat", "fat"]
console.log(strText.split(',',2))// ["cat", "bat"]
console.log(strText.split(/[^,]+/))//["", ",", ",", ",", ""]
3.11 localeCompare()方法
比较两个字符串,返回如下3个值中的一个:
如果按照字母表顺序,字符串应该排在字符串参数前头,则返回负值(通常是-1,具体要看与实际值相关的实现)
如果字符串与字符串参数相等,则返回0;
如果按照字母表顺序,字符串应该排在字符串参数后头,则返回正值(通常是1,具体要看与实际值相关的实现)
示例如下:
let strText = 'blue';
console.log(strText.localeCompare('abc'))// 1
console.log(strText.localeCompare('blue'))// 0
console.log(strText.localeCompare('gjk'))// -1
因为返回的具体值可能因具体实现而异,所以最好像如下示例一样使用localeCompare()方法:
let strText = 'blue';
function determinOrder(value){
let res = strText.localeCompare(value);
if(res < 0){
console.log(`blue' before '${value}'.`)
}else if(res > 0){
console.log(`blue' after '${value}'.`)
}else{
console.log(`blue' is equal '${value}'.`)
}
}
console.log('abc')
console.log('blue')
console.log('gjk')
//以上这样写可以保证在所有实现总都可以正确判断字符串的顺序;