一、 字符串的扩展
1. 字符串的遍历:for...of
let foo=[{a:2},{b:3}]
for(let temp of foo){
console.log(temp);//{a:2},{b:3}
}
2. JSON.stringify()
根据标准,JSON数据必须是UTF-8编码,但是,现在的JSON.stringify()方法有可能返回不符合 UTF-8 标准的字符串。为了确保返回的是合法的 UTF-8 字符,ES2019 改变了JSON.stringify()的行为。如果遇到0xD800到0xDFFF之间的单个码点,或者不存在的配对形式(UTF-8规定,0xD800到0xDFFF之间的码点,不能单独使用,必须配对使用),它会返回转义字符串,留给应用自己决定下一步的处理。
JSON.stringify('\u{D834}') // ""\\uD834""
3. 模板字符串
① 利用模板字符串可以以另一种方法解决字符串拼接的问题。模板字符串用反引号(`)标识,它可以当做普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量
② 如果使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中。若不想要头和尾的换行,可以用
trim
方法消除它
let str=`In '\n' is a a`;
let str1 =`In JavaScript this is
not legal.`//当折行前面有空格时会被输出(如图2)
let name="Bob";
let str3 = `Hello ${name} `
console.log(str3);//Hello Bob
图1:
图2:
③当需要将反引号作为普通字符串输出时需要加
\
。
let a="123";
console.log(`${a}\``);//123`
④ 在模板字符串中,大括号内部可以放入任意的
javascript
表达式,可以进行运算,以及引入对象属性。还可以调用函数。在进行运算时要注意将做运算的变量放到一个${}
内,否则结果为字符串的运算。如果大括号中的值不是字符串,将按照一般的规则转为字符串。比如,大括号中是一个对象,将默认调用对象的toString方法。
let a = 1;
let b=3;
let c = `${a}+${b}`;//1+3
let d=`${a+b*b}`;//10
console.log(c,d);
let e = {a:1,b:3};
function fn(){
return "hello world";
}
console.log(`${e.a+e.b}`)//4
console.log(`${fn()}`);//hello world
console.log(`${e}`);//调用e.toString()方法
⑤ 大括号内部实际是在执行js代码,故若大括号内部为一个字符串,则会原样输出
`hello ${`world`}`//hello world
console.log(`hello ${"world"}`);//hello world
⑥ 模板字符串可以进行嵌套
const a = [
{first:'hello',last:'world'},
{first:'lars',last:'world'}
];
// console.log(`${a}`);
`${a.map(dataTemp=>{
console.log(`${dataTemp.first + dataTemp.last}`);
})}`//helloworld larsworld
⑦ 标签模板:模板字符串可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能。注意:当模板字符串中有变量时,会将字符串和变量拆分开,具体见下例
⑧ ==在向函数传参时,模板字符串中有变量时,若变量后面没有字符串,则会自动添加一个空字符串"",当变量后面有字符串时,则不会添加。所有字符串会被第一个参数接收集合成数组,而变量会被其他参数接收。第一个参数有一个raw属性,其中保存的是转以后的原字符串。==在下例中,raw中保存识别的\n
不是换行符,而是\n
字符串。这样可以通过raw
属性获得转义之前的字符串。
⑨ 向函数传参时,若函数形参只有一个,则无法接收到模板字符串的变量值。但是可以通过arguments
来获取(在arguments
中,字符串数组为第一个元素,变量都以不同元素存储起来)
alert`123`;//弹出123
let a=5;
let b=10;
tag`Hello${a+b}world${a*b}123${a-b}`;
function tag(a,...b) {
console.log(a,b)//a为["Hello","world","",raw:Array[3]],b为[15,50]
}
tag`Hello${a+b}world${a*b}123${a-b}qqq`;
function tag(a,b,c) {
console.log(a,b)//a为["Hello","world","qqq",raw:Array[3]],b为15,c为50
}
//恢复原来字符串
let total = 30;
let msg = caculate`HELLO ${total} WORLD,My ${total} money is ${total*5}`;
;
function caculate(args,...value) {
let sum="";
console.log(args,value)
for(let i=0;i<value.length;i++){
sum +=args[i]+value[i];
}
console.log(sum)//HELLO 30 WORLD,My 30 money is 150
}
//另一种方法
let total = 30;
let msg = passthru`The total is ${total} (${total*1.05} with tax)`;
function passthru(literals) {
let result = '';
let i = 0;
while (i < literals.length) {
result += literals[i++];//i先自增再去获取对应的arguments中的元素,故取不到arguments[0]
if (i < arguments.length) {
result += arguments[i];
}
}
return result;
}
msg // "The total is 30 (31.5 with tax)"
//raw参数
tag`First line\nSecond line`
function tag(strings) {
console.log(strings.raw[0]);//"First line\nSecond line"
console.log(strings);//第一个参数为Frist line换行Second line
}
⑩ “标签模板”的一个重要应用,就是过滤 HTML 字符串,防止用户输入恶意内容。具体见下例
let message =
SaferHTML`<p>${sender} has sent you a message.</p>`;
function SaferHTML(templateData) {
let s = templateData[0];
for (let i = 1; i < arguments.length; i++) {
let arg = String(arguments[i]);
// Escape special characters in the substitution.
s += arg.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">");
// Don't escape special characters in the template.
s += templateData[i];
}
return s;
}
let sender = '<script>alert("abc")</script>'; // 恶意代码
let message = SaferHTML`<p>${sender} has sent you a message.</p>`;
message// <p><script>alert("abc")</script> has sent you a message.</p>
二、 字符串新增方法
1.String.fromCodePoint();
ES5提供
String.fromCharCode()
方法,用于从Unicode码点返回对应字符串,但是这个方法不能识别码点大于0xFFFF的字符.String.fromCodePoint()
可以识别大于0xFFFF的字符。如果String.fromCodePoint方法有多个参数,则它们会被合并成一个字符串返回。
2. String.raw();
- 该方法返回一个斜杠都被转义的字符串,往往用于模板字符串的处理方法。
String.raw()
本质是一个正常的函数。它的第一个参数是一个具有raw属性的对象,且raw属性的值为一个数组(与模板字符串给函数传参的情况相同),其等同于原始的模板字符串解析后得到的数组。注意:raw方法的返回结果是第一个参数的字符和其余参数交叉拼接的,若除第一个参数外还有偶数个参数,必须给第一个参数的raw属性添加一个""字符串,否则结果不正确(见例2)
String.raw`Hi\n${2+3}!`;//调用该方法,返回的值为Hi\n5!而不是Hi换行5!
String.raw`Hi\\n`;//返回:Hi\\\\n
/*例2*/
`foo${1+2}bar`===String.raw({raw:['foo','bar']},1+2);//foo3bar
String.raw({raw:['foo','bar']},1,2);//foo1bar
String.raw({raw:['foo','bar','']},1,2);//foo1bar2
3. 对象.includes(str,n)
- 返回布尔值,表示是否找到了参数字符串
- 该方法支持第二个参数,表示开始搜索位置的索引
- 该方法针对从第n个位置直到字符串结束
4. 对象.startsWith(str,n)
- 返回布尔值,表示参数字符串是否在原字符串的头部
- 该方法支持第二个参数,表示开始搜索位置的索引
- 该方法针对从第n个位置直到字符串结束
5. 对象.endsWith(str,n)
- 返回布尔值,表示参数字符串是否在原字符串的尾部
- 该方法支持第二个参数,表示开始搜索位置的索引
- 该方法是针对前n个字符
6. 对象.repeat(n)
该方法返回一个新的字符串,表示将原字符串重复n次。如果n为小数,会被向下取整。如果n负数(除-10的负数外的其他负数)或者Infinity,会报错。-10被视为0。NaN等同于0。如果n为字符串则会先转成数字。
'na'.repeat('na') // ""
'na'.repeat('3') // "nanana"
'na'.repeat(-0.9) // ""
'na'.repeat(NaN) // ""
'na'.repeat(Infinity)
// RangeError
'na'.repeat(-1)
// RangeError
7. 对象.padStart(),对象.padEnd()
- 字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart()方法为头部补全,padEnd()为尾部补全。
- 如果原字符串的长度,等于或大于最大长度,则字符串补全不生效,返回原字符串。
- 如果用来补全的字符串与原字符串,两者的长度之和超过了最大长度,则会截去超出位数的补全字符串。
let str = "12"
str.padStart(5,"ab");aba12
str.padEnd(4,"abc")12ab
8. 对象.trimStart(),对象.trimEnd()
- trimStart()消除字符串头部的空格,trimEnd()消除尾部的空格。它们返回的都是新字符串,不会修改原始字符串
- 这两个方法对字符串头部(或尾部)的 tab 键、换行符等不可见的空白符号也有效。
- ES5中的trim()方法是去除字符串头部和尾部的空格,同时对字符串头部(或尾部)的 tab 键、换行符等不可见的空白符号也有效。