es6加强了对Unicode 的支持,允许\uxxxx的形式展现一个字符,例如:
console.log('\u0061'); // 打印 a
\u后面的为字符的 Unicode 码点 \u 后面4位 xxxx
但是这种写法只识别 \u0000 到 \UFFFF 之间的字符,超出需要使用两个双字节表示,例如:
console.log('\uD842\uDFB7'); // 打印 吉
如果说超出了\uxxxx字节的范围,则为两个字节的拼接,例如:
console.log('\u20BB7'); // 输出 ' 7' \u20BB系统识别为空
console.log('\u00617'); // 输出 'a7'
\u0061识别为a,由于7超出了这个字节,所以为\u0061+7,结果为a7
es6对 Unicode 的支持进行了加强,如果超出了两个字节,放入大括号内即可正常解读
console.log("\u{20BB7}"); // 打印 吉
// 只要将码点放入大括号即可正确解读
console.log('\u{41}\u{42}\u{43}'); // 输出ABC
大括号与双字节的写法是等价的
console.log('\u{1F680}' == '\uD83D\uDE80'); // 大括号与4字节的写法等价 输出true
js对字符的几种表现方法:
console.log('\z' === 'z');
console.log('\172' === 'z');
console.log('\x7A' === 'z');
console.log('\u007A' === 'z');
console.log('\u{7A}' === 'z');
console.log('z' === 'z');
字符串遍历for...of
for (let codePoint of 'foo') {
console.log(codePoint); // f o o
}
其实一般的遍历,例如for,也可以遍历字符串,但是for无法识别大于0xFFFF的码点,而for...of则可以识别
let text = String.fromCodePoint(0x20BB7)
// for循环
for (let i = 0; i < text.length; i++) {
console.log(text[i]); // ' ' 空
}
// for---of可以识别 大于0xFFFF的码点 , 而传统的for无法识别
for (let i of text) {
console.log(i); // 吉
}
有些时候,我们在用JSON.stringify转字符串的时候,发现转译的字符串多了几个\
根据标准,JSON数据必须是 UTF-8 编码。但是JSON.stringify()方法有可能返回不符合 UTF-8 标准的字符串。
UTF-8 标准规定,0xD800到0xDFFF之间的码点,不能单独使用,必须配对使用。比如,\uD834\uDF06是两个码点,但是必须放在一起配对使用。这是为了表示码点大于0xFFFF的字符的一种变通方法。单独使用\uD834和\uDF06这两个码点是不合法的,或者颠倒顺序也不行,因为\uDF06\uD834并没有对应的字符。
JSON.stringify()的问题在于,它可能返回0xD800到0xDFFF之间的单个码点。
JSON.stringify('\u{D834}') // "\u{D834}"
所以 es2019对JSON.stringify()做出了改变,如果遇到0xD800到0xDFFF之间的单个码点,或者不存在的配对形式,它会返回转义字符串,留给应用自己决定下一步的处理。
console.log(JSON.stringify('\u{D834}')) // ""\\uD834""
console.log(JSON.stringify('\uDF06\uD834')) // ""\\uD834""
1、模板字符串识别标签,并却可以识别多行内容,传统的写法需要用+ 号连接,
2、模板字符串识别空格
let context = document.getElementById('context')
let str = `<div>东方 不败</div>
<div>东方求败</div>`
console.log(context.innerhtml = str); // 页面显示 东方 不败
传统的字符串插值,需要使用"字符"+100+"值"的形式,用 + 拼接,值是不能嵌套在引号当中的,否则会解译为字符串。
console.log("<div>东方不败有" + 100 + "元</div>")
模板字符串直接使用${xxx}即可在字符串中插值,并且在里面可以使用表达式以及调用函数。
let str2 = `<div>东方不败${100}</div>` // 东方不败 100
// 表达式
let s = 100
let str3 = `<div>东方不败${s == 100 ? '有100元' : '没有100元'}</div>` // 东方不败有100元
// 调用函数
let str4 = `<div>调用函数:${text2()}</div>`
function text2() {
return '东方不败'
}
let context2 = document.getElementById('context2')
console.log(context2.innerHTML = str4); // 页面显示 调用函数:东方不败
模板字符串可以嵌套使用,此处用的是map遍历结构,需要注意的是,forEach是无法在此遍历结构的,会直接报错,因为forEach会改变原数组,而map则不会(数组为基础类型时原数组不变)。
let context3 = document.getElementById('context3')
let arr = [{
name: '字符串',
index: '01'
}, {
name: '字符串',
index: '02'
}]
let s2 = `
<div>模板字符串嵌套:${
arr.map(el => `
<div>${el.name}</div>
<div>${el.index}</div>
`)
}</div>
`
context3.innerHTML = s2
函数名跟上模板字符串,则为标签模板,左边是函数,右边实际上是函数参数,例如:
alert `hello` // 等同于 alert(['hello'])
此处的alert是函数,紧跟在后面的模板字符串就是它的参数,这里会触发alert弹框,展示hello
但如果模板字符串有变量,就不是简单的调用,而是会先将模板字符串先处理成多个参数,再调用函数,例如:
let a = 5
let b = 10
// alert `hello ${ a + b} , word ${ a * b }`
tag(`hello ${ a + b} , word ${ a * b }`)
此处的tag等同于 tag([hello ', ', word ', ''],15,50),在这里,模板字符串前有一个tag,这个tag是一个函数,整个表达式的返回值就是tag函数处理模板字符串后返回的值,返回结果可以看上面alert打印的内容。
实际上是将tag转换成了:
// 实际上转换成了
function tag(stringArr, value1, value2) {
// ......
}
// 或者
function tag(stringArr, ...values) {
console.log(stringArr, values);
// ......
}
1、tag函数的第一个参数是一个数组,整个数组是模板字符串中没有变量替换的部分。
2、变量的替换,只发生在数组的第一个成员于第二个成员之间,第二个成员与第三个成员之间,以此类推。
3、tag函数的其他参数,都是模板字符串各个变量被替换后的值。这里的模板字符串有两个参数,所以这里会接收 value1,value2 两个参数。
例如:
第一个参数:[hello ', ', word ', '']
第二个参数:15
第三个参数:50
其实也就是 tag([hello ', ', word ', ''],15,50)
这里再举一个例子:
下面就是关于标签模板是怎样将字符串与值拼接的过程,最终展现的就是标签模板编译后的结果
let total = 30; // 变量
let msg = passthru `The total is ${total} (${total*1.05} with tax)`;
function passthru(literals) {
//literals : ['The total is ', ' (', ' with tax)', raw: Array(3)]
let result = ''
let i = 0
while (i < literals.length) {
result += literals[i++];
if (i < arguments.length) {
/* arguments:
0:['The total is ', ' (', ' with tax)', raw: Array(3)]
1 : 30
2 : 31.5
*/
console.log(arguments); // 参数的数组
result += arguments[i]
}
}
return result
}
输出结果:The total is 30 (31.5 with tax)
步骤拆解:
1: passthru函数的参数literals就是标签模板的参数['The total is ', ' (', ' with tax)', raw: Array(3)]
2: while 遍历了数组参数的长度,并且在内部进行判断
3: if中的arguments就是参数的数组,这一步就是关键的字符串与值得拼接,拼接的步骤如下:
while遍历,如果参数为true则循环遍历,直到false终止
遍历内容如下:
The total is
30
(
31.5
前面说过了:变量的替换,只发生在数组的第一个成员于第二个成员之间,第二个成员与第三个成员之间,以此类推。所以此处也是这样处理的,最后返回的结果就是The total is 30 (31.5 with tax)。
恶意输入
标签模板还有一个重要的作用就是防止用户恶意输入,如果用户在输入框恶意嵌套标签是非常不安全的行为。
let sender = '<script>alert("恶意代码")</cript>'
function SaferHTML(templateData) {
let s = templateData[0]
for (let i = 1; i < arguments.length; i++) {
let arg = String(arguments[i])
s +=arg.replace(/&/g,"&")
.replace(/</g,"<")
.replace( />/g,">")
// 过滤 转义 &为&字符; <为<字符; >为>字符;
s += templateData[i]
}
return s
}
此处将用户嵌套的script标签进行了转译,&为&字符、<为<字符、 >为>字符
let message = SaferHTML `<p>${sender}个人信息</p>`
console.log(message);
// 打印 <p><script>alert("恶意代码")</script> 个人信息</p>
由于我的编译器会自动格式化,所以用 sxxxcript 代替 script
标签模板可以做多语言转(国际化)
i18n `Welcome to ${userName}, you are visitor number ${visitorNumber}!`
甚至可以在标签模板嵌套其他语言
jsx `
<div>
<input
ref='input'
onChange='${this.handleChange}'
defaultValue='${this.state.value}' />
${this.state.value}
</div>
`
// 此处就是通过jsx函数,将dom字符串转换为react对象
模板处理函数的第一个参数,也就是非参数的模板字符串数组,有一个raw属性
console.log(`abc`) // ['abc',row:Array[1]]
// 这个raw保存的是转义后的原字符串
这个数组后面的raw保存的是转义后的原字符串。
案例源码:https://gitee.com/wang_fan_w/es6-science-institute
如果觉得这篇文章对你有帮助,欢迎点亮一下star
原文来自:https://www.cnblogs.com/wang-fan-w/archive/2023/02/14/17119878.html
我们先温习一下JavaScript基础知识。在JavaScript中,根据+左右两边变量的类型的不同,+符号可以用于数字相加或则字符串拼接。我用了string += +string这样的写法,也就是说:由于写代码的时候拷贝黏贴,不小心整了一个多余的+号?
在我们使用JavaScript编写脚本的时候,经常会遇到把字符串两边的空格进行清除,它不想其它语言会有内置方法函数处理,js需要我们自己代码来实现。如果用过jquery库的话,它提供了trim方法,我们可以直接使用。
我们都知道prototype可以向对象上添加属性和方法,语法如下:object.prototype.name=value。这篇文章就是利用prototype,为字符串扩展过滤空格的方法
在开发中过程中,经常会遇到使用占位符的形式来格式化字符串,我们通过js扩展String.prototype.format字符串拼接的功能,实现如下:
es6中新增的字符串方法:字符串模板用法${变量名}、字符串查找方法string.includes(要找得字符串)、检查字符串是否已xxx开头、字符串重复方法string.repeat(次数)、字符串填充string.padStart
众所周知,js提供了很多字符串截取的方式。下面主要介绍js中slice(),splice(),split(),substring(),substr()的使用和区别,主要介绍了JavaScript截取、切割字符串的技巧,需要的朋友可以参考
看到一个题目要求写一个函数times,输出str重复num次的字符串。除了利用循环还有几种方法:递归,结合三元表达式更简洁。数组的 join() 方法。ES6的 repeat() 方法。ES6目前没有全部兼容。
对于常用的字符串原型的举例:在字符串末尾追加字符串 、删除指定索引位置的字符,索引无效将不删除任何字符 、删除指定索引区间的字符串 、检查字符串是否以subStr结尾
javascript提供stringA.localeCompare(stringB)方法,来判断一个字符串stringB是否排在stringA的前面。返回值: 如果引用字符存在于比较字符之前则为负数; 如果引用字符存在于比较字符之后则为正数; 相等的时候返回 0 。
ES6的includes, 返回 Boolean、ES5 indexOf,返回子串起始位置,不包含则返回-1、search,返回起始位置或者-1、lodash includes, JavaScript 工具库
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!