# 实用-字符串模板解析
# 一、简单版
# 描述
实现一个 render(template, context) 方法,将 template 中的占位符用 context 填充。
不需要有控制流成分(如 循环、条件 等等),只要有变量替换功能即可 级联的变量也可以展开 被转义的的分隔符 { 和 } 不应该被渲染,分隔符与变量之间允许有空白字符
# 实现
function render(templateStr, context) {
return templateStr.replace(/\$\{(.*?)\}/g, (match, key) => context[key.trim()]);
}
render("My name is ${name}, I'm ${age} years old.", {name: 'Aaron', age: 31})
// "My name is Aaron, I'm 31 years old."
1
2
3
4
5
6
2
3
4
5
6
# 二、复杂版
# 描述
实现函数使得将str字符串中的 {}
内的变量替换,如果属性不存在保持原样(比如 {a.d}
)
类似于模版字符串,但有一点出入,实际上原理大差不差
var a = {
b: 123,
c: '456',
e: '789',
}
var str=`a{a.b}aa{a.c}aa {a.d}aaaa`;
// => 'a123aa456aa {a.d}aaaa'
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 实现
const fn1 = (str, obj) => {
let res = '';
// 标志位,标志前面是否有{
let flag = false;
let start;
for (let i = 0; i < str.length; i++) {
if (str[i] === '{') {
flag = true;
start = i + 1;
continue;
}
if (!flag) res += str[i];
else {
if (str[i] === '}') {
flag = false;
res += match(str.slice(start, i), obj);
}
}
}
return res;
}
// 对象匹配操作
const match = (str, obj) => {
const keys = str.split('.').slice(1);
let index = 0;
let o = obj;
while (index < keys.length) {
const key = keys[index];
if (!o[key]) {
return `{${str}}`;
} else {
o = o[key];
}
index++;
}
return o;
}
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
36
37
38
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
36
37
38