实用-字符串模板解析 
一、简单版 
描述 
实现一个 render(template, context) 方法,将 template 中的占位符用 context 填充。
不需要有控制流成分(如 循环、条件 等等),只要有变量替换功能即可 级联的变量也可以展开 被转义的的分隔符 { 和 } 不应该被渲染,分隔符与变量之间允许有空白字符
实现 
js
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."二、复杂版 
描述 
实现函数使得将str字符串中的 {} 内的变量替换,如果属性不存在保持原样(比如 {a.d} )
类似于模版字符串,但有一点出入,实际上原理大差不差
js
var a = {
	b: 123,
	c: '456',
	e: '789',
}
var str=`a{a.b}aa{a.c}aa {a.d}aaaa`;
// => 'a123aa456aa {a.d}aaaa'实现 
js
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;
}