手动实现一个模板字符串的编译函数

手动实现一个模板字符串的编译函数

缘起

一方面是为了加深前端基础,提升代码能力,另一方面是一个悲哀的故事。

目标

实现一个Compile函数,可以编译 JavaScript 中的模板字符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 输入
// 1. 实现一个字符串模板函数
var a = {
b: '[字符串]',
c: [
'[数组中的字符]',
['[数组中的数组]', ['[数组中的数组中的数组]']],
{
g: '[数组中的对象项]'
}
],
e: {
f: '[对象中的对象]',
h: ['[对象中的数组项]']
}
}
var string =
'Start-${e.f}${b}${c[0]}-Middle-${c[1][0]}${c[1][1][0]}${c[2].g}${e.h[0]}End'
// 执行
compile(string, a)
// 输出
Start-[对象中的对象][字符串][数组中的字符]-Middle-[数组中的数组][数组中的对象项][对象中的数组项]End

具体的实现代码分为两块,一块儿是获取字符中的模板替换位置,另一部分是通过字符去获得对象中,相应的值。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

let getVarable = function (a, varableNameStr) {
// 如果是空的话,返回空字符
if (!varableNameStr) return ''
// 扒皮
varableNameStr = varableNameStr.replace('${', '').replace('}', '')
// 这个地方是为了兼容通过对象的点式写法来获取变量的方法。
let packages = varableNameStr.split('.')
let middleTemp = a
packages.forEach(each => {
each.split(/[\[|\]]+/).forEach(varable => {
if (varable) {
let key = parseInt(varable)
// 判断是否为数字, NaN != NaN 的特性
if (key === key) {
middleTemp = middleTemp[key]
} else {
middleTemp = middleTemp[varable]
}
}
})
})
return middleTemp
}

let compile = function (str, a) {
let regVar = /\$\{.+?\}/g
let matchVar = str.match(regVar)
matchVar.forEach(m => {
str = str.replace(m, getVarable(a, m))
})
return str
}

console.log(compile(string, a))

手动实现一个模板字符串的编译函数

https://www.borgor.cn/posts/97d33bdb.html

Author

BorGor

Posted on

2020-05-11

Updated on

2022-01-08

Licensed under

Comments