阅读 521

你真的懂es6提出的模板字符串(反引号 ` `)

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金

1、基本使用

我们先看看传统的字符串拼接模板写法,如下

let username="管理员";
let age=18;
let phone=123456789;
$('#addList').append(
  '<li>'+username+'<li>'+
  '<li>'+age+'<li>'+
  '<li>'+phone+'<li>'+
)
复制代码

可以看到的是,上面这种写法是相当繁琐的,而且在模板复杂的情况还会造成阅读困难。为了解决这类问题,在ES6中引入了模板字符串(反引号)。写法如下

let username="管理员";
let age=18;
let phone=123456789;
$('#addList').append(`
  <li>${username}</li>
  <li>${age}</li>
  <li>${phone}</li>
`)
复制代码

可以看到它不仅可以直接定义多行的字符串,还可以直接在字符串中嵌入变量,简直方便极了!!

2、嵌入变量

模板字符串中嵌入变量只需要将变量名写在${}中即可,当然它不仅仅提供了简单的嵌入变量,我们还可以在大括号内放入任意的javaScript表达式、字符串、数字等,喔喔喔牛啊!!,让我们直接看看下面的代码

let obj={
    numOne:1,
    numTwo:2,
    nameOne:"哥哥",
    nameTwo:"小花",
    ai:"爱",
}
function fn(name){
  return `${name}在吗?`
}

//对象引用
let a = `${obj.nameOne}在吗?`
alert(a);

//数值运算
let b = `${obj.numOne + obj.numTwo}`
alert(`1+2=${b}`)

//字符串拼接一
let c = `${obj.nameOne + obj.ai + obj.nameTwo}`
alert(c)

//字符串拼接二(拼接字符串和数字)
let c = `${obj.nameOne + obj.ai + obj.nameTwo + ',哥哥不爱我了吗?' + '123456789'}`
alert(c)

//函数调用
let d = `${fn(obj.nameOne)}`
alert(d)

//模板字符串嵌套,这里遍历返回p标签包含的数组,通过空格进行分割展示
let e = `<div>
${ 
    Object.keys(obj).map(item=>{
       return `<p>${obj[item]}</p>`
    }).join(' ')       //输出: <p>1</p> <p>2</p> <p>哥哥</p> <p>小花</p> <p>爱</p>
}
</div>`
console.log(e)

复制代码

3、标签模板

字符串模板还可以紧跟在一个函数后面,当做参数传递到函数体内处理,如果模板字符里面有变量,会先将模板字符串和变量先处理成多个参数,再调用函数。

要注意的是:
1、处理后的参数,第一个参数为切割后的字符串数组,往后的每个参数均为变量。
2、写法与正常函数传参并不相同,如下代码所示。

//可以使用value接受第一个和第二个参数,但是这样是不实际,所以使用解构语法才是最好的实践
//function test(stringArr, value1, value2){
function test(stringArr, ...values){
    console.log(stringArr)
    console.log(values)
}
let a = '内容1'
let b = '内容2'
//执行函数
test`${a}---${b}` //实际调用形式:test(['', '---', ''], '内容1', '内容2')
复制代码

image.png 我们可以看到上面的执行结果,首先stringArr数组中有三个,其中三横杠---属于正常切割出来的字符串,那么还有两个空格是从何而来呢?接下来我们继续分析,执行以下代码

我们分别在开头,结尾处加入字符串,看看以下的执行结果

test`测试开头 ${a}---${b}`  //实际调用形式:test(['测试开头 ', '---', ''], '内容1', '内容2')
test`${a}---${b} 测试结尾`  //实际调用形式:test(['', '---', ' 测试结尾'], '内容1', '内容2')
test`测试开头 ${a}---${b} 测试结尾`  //实际调用形式:test(['测试开头 ', '---', ' 测试结尾'], '内容1', '内容2')
复制代码

执行第一个函数,原数组中的第一个空格已经被 "测试开头 " 这个字符串占据了。

image.png

执行第二个函数,原数组最后一个空格已经被 " 测试结尾" 这个字符串占据了。

image.png

执行第三个函数,原数组中的所有空格已经被 "测试开头 " 和 " 测试结尾" 这个字符串占据了。

image.png

注意:
1、若模板字符串不是以字符串开头或结尾,函数处理参数时会以 空格 代替开头和结尾
2、切割后的字符串是包含空格的

4、标签模板的应用场景

上面我们已经学会了如何去使用标签模板,也知道了标签模板的特性,下面我们举个栗子🌰

4.1 过滤 HTML 字符串

为防止用户输入恶意代码,我们可以通过标签模板重新格式化掉用户输入的内容
如下所示:

//获取input输入框的内容
let sender = '<script>alert("这是恶意代码")</script>'; 
//拼接内容显示在页面中
let appendHtml = `<p>您输入的是${sender}</p>`
$("body").append(appendHtml)
复制代码

代码在控制台执行之后便会执行alert函数,虽然看起来不太恶意,但是别有用心之人可以用它来制作真正的恶意代码。 image.png 为防止这种意外的发生,我们可以定义一个函数,转义掉恶意代码中的标签,这样就不会执行代码了。

//stringArr: 原字符串切割后的数组
//values: 变量数组
function SaferHTML(stringArr,...values) {
  let s = stringArr[0]
  for (let i = 0; i < values.length; i++) {
    let strValue = String(values[i]);
    s += strValue.replace(/&/g, "&amp;")  //转义 &    ==>    &amp;
            .replace(/</g, "&lt;")        //转义 <    ==>    &lt;
            .replace(/>/g, "&gt;");       //转义 >    ==>    &gt;

    s += stringArr[i+1];
  }
  return s;
}
//获取input输入框的内容
let sender = '<script>alert("这是恶意代码")</script>'; 
//拼接内容显示在页面中
let appendHtml = SaferHTML`<p>您输入的是${sender}</p>`
$("body").append(appendHtml)
复制代码

执行完成之后正常在body底部插入一段字符串

image.png

因为标签模板函数处理时,会将字符串和变量转换成对应的参数,所以我们只需处理变量的参数,并正常拼接返回即可。

文章分类
前端
文章标签