ES6字符串新增方法及扩展
程序员文章站
2023-12-21 15:45:16
...
// 实例方法:includes(), startsWith(), endsWith()
// 传统上,JavaScript 只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6 又提供了三种新方法。
// includes():返回布尔值,表示是否找到了参数字符串。
// startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
// endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
let s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
// 这三个方法都支持第二个参数,表示开始搜索的位置。
let s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
// 上面代码表示,使用第二个参数n时,endsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束。
// 实例方法:repeat() § ⇧
// repeat方法返回一个新字符串,表示将原字符串重复n次。
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""
// 参数如果是小数,会被取整。
'na'.repeat(2.9) // "nana"
// 如果repeat的参数是负数或者Infinity,会报错。
'na'.repeat(Infinity)
// RangeError
'na'.repeat(-1)
// RangeError
// 但是,如果参数是 0 到-1 之间的小数,则等同于 0,这是因为会先进行取整运算。0 到-1 之间的小数,取整以后等于-0,repeat视同为 0。
'na'.repeat(-0.9) // ""
// 参数NaN等同于 0。
'na'.repeat(NaN) // ""
// 如果repeat的参数是字符串,则会先转换成数字。
'na'.repeat('na') // ""
'na'.repeat('3') // "nanana"
// 实例方法:trimStart(),trimEnd()
// ES2019 对字符串实例新增了trimStart()和trimEnd()这两个方法。它们的行为与trim()一致,trimStart()消除字符串头部的空格,trimEnd()消除尾部的空格。它们返回的都是新字符串,不会修改原始字符串。
const s = ' abc ';
s.trim() // "abc"
s.trimStart() // "abc "
s.trimEnd() // " abc"
// 上面代码中,trimStart()只消除头部的空格,保留尾部的空格。trimEnd()也是类似行为。
// 除了空格键,这两个方法对字符串头部(或尾部)的 tab 键、换行符等不可见的空白符号也有效。
// 浏览器还部署了额外的两个方法,trimLeft()是trimStart()的别名,trimRight()是trimEnd()的别名。
// 模板字符串
// 传统的 JavaScript 语言,输出模板通常是这样写的(下面使用了 jQuery 的方法)。
$('#result').append(
'There are <b>' + basket.count + '</b> ' +
'items in your basket, ' +
'<em>' + basket.onSale +
'</em> are on sale!'
);
// 上面这种写法相当繁琐不方便,ES6 引入了模板字符串解决这个问题。
$('#result').append(`
There are <b>${basket.count}</b> items
in your basket, <em>${basket.onSale}</em>
are on sale!
`);
// 模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。
// 字符串中嵌入变量
let name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`
$('#list').html(`
<ul>
<li>first</li>
<li>second</li>
</ul>
`);
// 上面代码中,所有模板字符串的空格和换行,都是被保留的,比如<ul>标签前面会有一个换行。如果你不想要这个换行,可以使用trim方法消除它。
$('#list').html(`
<ul>
<li>first</li>
<li>second</li>
</ul>
`.trim());
// 如果大括号中的值不是字符串,将按照一般的规则转为字符串。比如,大括号中是一个对象,将默认调用对象的toString方法。
// 模板编译
// 下面,我们来看一个通过模板字符串,生成正式模板的实例。
let template = `
<ul>
<% for(let i=0; i < data.supplies.length; i++) { %>
<li><%= data.supplies[i] %></li>
<% } %>
</ul>
`;
// 上面代码在模板字符串之中,放置了一个常规模板。该模板使用<%...%>放置 JavaScript 代码,使用<%= ... %>输出 JavaScript 表达式。
// 怎么编译这个模板字符串呢?
// 一种思路是将其转换为 JavaScript 表达式字符串。
echo('<ul>');
for(let i=0; i < data.supplies.length; i++) {
echo('<li>');
echo(data.supplies[i]);
echo('</li>');
};
echo('</ul>');
// 标签模板
alert`123`
// 等同于
alert(123)
如果模板字符里面有变量,就不是简单的调用了,而是会将模板字符串先处理成多个参数,再调用函数。
let a = 5;
let b = 10;
tag`Hello ${ a + b } world ${ a * b }`;
// 等同于
tag(['Hello ', ' world ', ''], 15, 50);
// 上面代码中,模板字符串前面有一个标识名tag,它是一个函数。整个表达式的返回值,就是tag函数处理模板字符串后的返回值。
// 函数tag依次会接收到多个参数。
function tag(stringArr, value1, value2){
// ...
}
// 等同于
function tag(stringArr, ...values){
// ...
}
// tag函数的第一个参数是一个数组,该数组的成员是模板字符串中那些没有变量替换的部分,也就是说,变量替换只发生在数组的第一个成员与第二个成员之间、第二个成员与第三个成员之间,以此类推。
// tag函数的其他参数,都是模板字符串各个变量被替换后的值。由于本例中,模板字符串含有两个变量,因此tag会接受到value1和value2两个参数。
// tag函数所有参数的实际值如下。
// 第一个参数:['Hello ', ' world ', '']
// 第二个参数: 15
// 第三个参数:50
// 也就是说,tag函数实际上以下面的形式调用。
tag(['Hello ', ' world ', ''], 15, 50)
let a = 5;
let b = 10;
function tag(s, v1, v2) {
console.log(s[0]);
console.log(s[1]);
console.log(s[2]);
console.log(v1);
console.log(v2);
return "OK";
}
tag`Hello ${ a + b } world ${ a * b}`;
tag(['Hello ', ' world ', ''], 5, 10)
// "Hello "
// " world "
// ""
// 15
// 50
// "OK"