1.字符的unicode表示法 :将码点放入大括号,正确解读字符。
"\u{20BB7}"
// ""
"\u{41}\u{42}\u{43}"
// "ABC"
let hello = 123;
hell\u{6F} // 123
'\u{1F680}' === '\uD83D\uDE80'
// true
6中方法表示一个字符:
'\z' === 'z' // true
'\172' === 'z' // true
'\x7A' === 'z' // true
'\u007A' === 'z' // true
'\u{7A}' === 'z' // true
2.字符串的遍历器接口
let text = String.fromCodePoint(0x20BB7);
for (let i of text) {
console.log(i);
}
// ""
3.JSON。stringify()的改造
如果遇到0xD800 到0xDFFF 之间的单个码点,或者不存在的配对形式,它会返回转义字符串。
JSON.stringify('\u{D834}') // ""\\uD834""
JSON.stringify('\uDF06\uD834') // ""\\udf06\\ud834""
4.模板字符串:用反引号(`)标识。
// 普通字符串
`In JavaScript '\n' is a line-feed.`
// 多行字符串
`In JavaScript this is
not legal.`
console.log(`string text line 1
string text line 2`);
// 字符串中嵌入变量
let name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`
如果在模板字符串中需要使用反引号,则前面要用反斜杠转义。
let greeting = `\`Yo\` World!`;
使用反引号,所有模板字符串的空格和换行,都是会被保留的,如果不需要,则trim方法消除。
$('#list').html(`
<ul>
<li>first</li>
<li>second</li>
</ul>
`.trim());
模板字符串中嵌入变量,需要将变量名写在${}中。
let x = 1;
let y = 2;
`${x} + ${y} = ${x + y}`
// "1 + 2 = 3"
`${x} + ${y * 2} = ${x + y * 2}`
// "1 + 4 = 5"
let obj = {x: 1, y: 2};
`${obj.x + obj.y}`
// "3"
function fn() {
return "Hello World";
}
`foo ${fn()} bar`
// foo Hello World bar
大括号内部是字符串,则原样输出。
`Hello ${'World'}`
// "Hello World"
模板字符串还能嵌套:
const tmpl = addrs => `
<table>
${addrs.map(addr => `
<tr><td>${addr.first}</td></tr>
<tr><td>${addr.last}</td></tr>
`).join('')}
</table>
`;
const data = [
{ first: '<Jane>', last: 'Bond' },
{ first: 'Lars', last: '<Croft>' },
];
console.log(tmpl(data));
// <table>
//
// <tr><td><Jane></td></tr>
// <tr><td>Bond</td></tr>
//
// <tr><td>Lars</td></tr>
// <tr><td><Croft></td></tr>
//
// </table>
也可以写成函数:
let func = (name) => `Hello ${name}!`;
func('Jack') // "Hello Jack!"
5.模板编译(没怎么看明白。。。)
模板编译函数:
function compile(template){
const evalExpr = /<%=(.+?)%>/g;
const expr = /<%([\s\S]+?)%>/g;
template = template
.replace(evalExpr, '`); \n echo( $1 ); \n echo(`')
.replace(expr, '`); \n $1 \n echo(`');
template = 'echo(`' + template + '`);';
let script =
`(function parse(data){
let output = "";
function echo(html){
output += html;
}
${ template }
return output;
})`;
return script;
}
正式用法:
let parse = eval(compile(template));
div.innerHTML = parse({ supplies: [ "broom", "mop", "cleaner" ] });
// <ul>
// <li>broom</li>
// <li>mop</li>
// <li>cleaner</li>
// </ul>
6.标签模板 : 函数调用的一种特殊形式。
“标签”指的是函数,紧跟在后面的模板字符串就是它的参数;如果模板字符里面有变量,需要先将模板字符串先处理成多个参数,在调用函数。
let a = 5;
let b = 10;
tag`Hello ${ a + b } world ${ a * b }`;
// 等同于
tag(['Hello ', ' world ', ''], 15, 50);
tag函数:第一个参数是一个数组(没有变量替换的部分)
function tag(stringArr, value1 ,value2) {
//....
}
等同于
function tag(stringArr , ...values ) {
//...
}
举例:
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 };
// "Hello "
// " world "
// ""
// 15
// 50
// "OK"
“标签模板”:
1.过滤HTML字符串,放置用户输入恶意内容。
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>
2.多语言转换(国际化处理)。
i18n`Welcome to ${siteName}, you are visitor number ${visitorNumber}!`
// "欢迎访问xxx,您是第xxxx位访问者!"
模板处理函数的第一个参数(模板字符串数组),还有一个raw属性。
console.log`123`
// ["123", raw: Array[1]]
//保存的是转以后的原字符串。
tag`First line\nSecond line`
function tag(strings) {
console.log(strings.raw[0]);
// strings.raw[0] 为 "First line\\nSecond line"
// 打印输出 "First line\nSecond line"
}
//strings.raw数组会将 \n 视为 \\ 和 n 两个字符,而不是换行符
7.模板字符串的限制:模板字符串默认会将字符串转义
function tag(strs) {
strs[0] === undefined
strs.raw[0] === "\\unicode and \\u{55}";
}
tag`\unicode and \u{55}`
//第一个字符设置为undefined,但是raw属性依然可以得到原始字符串
字符串的新增方法:
1.String.fromCodePoint()
String.fromCodePoint(0x20BB7)
// ""
String.fromCodePoint(0x78, 0x1f680, 0x79) === 'x\uD83D\uDE80y'
// true 多个参数,会合并成一个字符串返回
//fromCodePoint方法定义在 string 对象上,而 codePointAt 方法定义在字符串的实例对象上。
-------------------------------------------------------
2.String.raw() : 返回一个斜杠都被转义 -- 专用于模板字符串的标签函数
String.raw`Hi\n${2+3}!`
// 实际返回 "Hi\\n5!",显示的是转义后的结果 "Hi\n5!"
String.raw`Hi\u000A!`;
// 实际返回 "Hi\\u000A!",显示的是转义后的结果 "Hi\u000A!"
如果原字符串的斜杠已经转义,那么 String.raw() 会再次转义。
String.raw`Hi\\n`
// 返回 "Hi\\\\n"
String.raw`Hi\\n` === "Hi\\\\n" // true
如果写成正常的函数:
// `foo${1 + 2}bar`
// 等同于
String.raw({ raw: ['foo', 'bar'] }, 1 + 2) // "foo3bar"
----------------------------------------------------------
3.codePointAt() : 会正确返回 UTF-16 字符的码点。
----------------------------------------------------------
4.normalize() : 不能识别三个或以上字符的合成。
NFC:默认参数,返回多个简单字符的合成字符。
NFD:返回合成字符分解的多个简单字符。
'\u004F\u030C'.normalize('NFC').length // 1
'\u004F\u030C'.normalize('NFD').length // 2
NFKC:返回合成字符。
NFKD:返回合成字符分解的多个简单字符。
------------------------------------------------------------
5.includes() - 表示是否找到参数字符串 ; 返回布尔值
startsWith() - 表示参数字符串是否在原字符串的头部 ;返回布尔值
endsWith() - 表示参数字符串是否在原字符串的尾部 ; 返回布尔值
举例:
let s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
支持第二个参数:endsWith的针对前 N 个字符,其他两个针对从第 N 个位置知道字符串结束。
let s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
------------------------------------------------------------
6.repeat() : 返回一个新字符串,表示将原字符串重复 n 次
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""
//参数是小数,会被取整
'na'.repeat(2.9); // "nana"
//参数是负数或者 Infinity ,会报错
'na'.repeat(Infinity); //报错
'na'.repeat(-1); //报错
//参数是 0 到 -1 之间的小数,等同于 0
'na'.repeat(-0.9); // ""
//参数是 NaN ,等同于 0
'na'.repeat(NaN); // ""
//参数是字符串,则先用 Number 转换为数字
'na'.repeat('na') // ""
'na'.repeat('3') // "nanana"
------------------------------------------------------------
7.padStart() : 用于头部补全; padEnd() : 用于尾部补全。
都接受两个参数,第一个参数是字符串补全生效的最大长度,第二个参数是用来补全的字符串。
'x'.padStart(4,'ab'); // abax
'x'.padEnd(4,'ab'); //xaba
如果原字符串的长度等于或大于最大长度,则返回原字符串。
'xxx'.padStart(2,'ab'); // xxx
如果补全字符串的最终长度大于最大长度,则截去超出位数的字符串。
'xxx'.padStart(10,'aaaaaaaa'); // aaaaaaaaxx
如果省略第二个参数,默认使用空格补全长度。
'x'.padStart(3); // 'x '
padStart()用途:
1.数值补全指定位数: '12'.padStart(10, '0') // "0000000012"
2.提示字符串格式:'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"
------------------------------------------------------------
8.trimStart():消除字符串头部的空格; trimEnd():消除尾部的空格。
---- 都返回新的字符串,不会修改原始字符串。
const s = ' abc ';
s.trim() // "abc"
s.trimStart() // "abc "
s.trimEnd() // " abc"
------------------------------------------------------------
9.matchAll() : 返回一个正则表达式在当前字符串的所有匹配。
|