模板引擎是通过字符串拼接得到的

let template = 'hello <% name %>!'
let template = 'hello ' + name + '!'

字符串是通过new Function执行的

let name = 'world'
let template = `
  let str = 'hello ' +  name  + '!'
  return str
`
let fn = new Function('name', template)
console.log(fn(name)) // hello world!

将模板转换为字符串并通过函数执行返回

let template = 'hello <% name %>!'
let name = 'world'
function compile (template) {
  let html = template.replace(/<%([\s\S]+?)%>/g, (match, code) => {
    return `' + ${code} + '`
  })
  html = `let str = '${html}'; return str`
  return new Function('name', html)
}
let str = compile(template)
console.log(str(name)) // hello world!

函数只能接收一个name变量作为参数,功能太单一了,一般会通过对象来传参,with来减少变量访问。

with功能

let params = {
  name: '张三',
  age: 18
}
let str = ''
with (params) {
  str = `用户${name}的年龄是${age}岁`
}
console.log(str) // 用户张三的年龄是18岁

实现简单的模板引擎

let template = 'hello <% name %>!'
let name = 'world'
function compile (template) {
  let html = template.replace(/<%([\s\S]+?)%>/g, (match, code) => {
    return `' + ${code.trim()} + '`
  })
  html = `'${html}'`
  html = `let str = ''; with (params) { str = ${html}; } return str`
  return new Function('params', html)
}
let str = compile(template)
console.log(str({ name })) // hello world!