由于前不久遇到一个前端笔试题,实现一个简易的模板渲染函数,但是没能做出来,于是在此进行总结记录。

题目大致内容如下:

1
2
// 实现一个简易模板渲染
// 例 renderTpl('我已经有${year}年${pos}开发经验了', {year: '2', pos: '前端'}) 输出 '我已经有2年前端开发经验了'

使用过ES6的模板字符串语法的人都知道,可以使用${}将变量包起来,替代原来ES5+拼接字符串。这个函数要实现的功能正是如此。

因为是使用${}这种特定的语法,我们很容易想到,使用正则将${}里面的内容替换出来,填充我们定义的变量进去即可。这里使用到字符串的replace方法:(更多replace内容点这里)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 模板字符串的实现函数
* @param {String} str 要匹配的字符串
* @param {Object} obj 要替换的对象
* @returns
*/
function renderTpl(str, obj) {
// 该正则用来匹配 ${} 里的内容
const regex = /\$\{([^}]+)\}/g
// 该函数用来替换第一个参数`match`匹配到的结果,返回值就是替换后的结果
const replacer = function (match, item) {
console.log(match, item);
return obj[item]
}
// 返回替换函数执行后的结果
return str.replace(regex, replacer)
}
// 这里的打印语句会打印出
// ${year} year
// ${pos} pos

const renderStr = renderTpl("我已经有${year}年${pos}开发经验了", { year: '2', pos: '前端' })
console.log(renderStr) // 打印结果: "我已经有2年前端开发经验了"

实现这个函数的主要难点我认为是正则表达式的书写,对正则表达式不是很熟悉的话,真的很难…

该正则进行拆分:

/\$\{([^}]+)\}/g

  1. 首先是g后缀,表示全局匹配,不会匹配到一个就结束
  2. 前面的\$\{表示转义,进行匹配${
  3. 匹配到${后,接下来这一串([^}]+)表示匹配一个或多个非}的字符
  4. 最后匹配\}, 匹配右花括号