首页IT科技字符串中的字符怎么表示(字符串的解读和标签模板)

字符串中的字符怎么表示(字符串的解读和标签模板)

时间2025-06-20 14:55:24分类IT科技浏览6633
导读:字符串解读 es6加强了对Unicode 的支持,允许\uxxxx的形式展现一个字符,例如:...

字符串解读

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,"&amp") .replace(/</g,"&lt") .replace( />/g,"&gt") // 过滤 转义 &为&amp字符; <为&lt字符; >为&gt字符; s += templateData[i] } return s }

此处将用户嵌套的script标签进行了转译               ,&为&amp字符               、<为&lt字符        、 >为&gt字符

let message = SaferHTML `<p>${sender}个人信息</p>` console.log(message); // 打印 <p>&lt;script&gt;alert("恶意代码")&lt;/script&gt; 个人信息</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

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
win11版本22000.194(Win11 Build 22000.348更新补丁KB5007262预览版发布(附更新修复内容汇总))