New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
实现一个插值表达式处理函数 #40
Comments
上述方案存在一个问题,那就是如果我想在插值表达式里执行一些运算逻辑,那么就会报错。如果要执行一个字符串,第一时间想到的是 eval 函数,但是这仍然存在一个问题,就是 eval 执行字符串的时候,里面的变量上下文该如何获取?这时候就可以使用 with 函数,把 data 传递进去,这样就避免了访问数据时还得加上 data. 前缀。 let template = "大家好,我的名字叫做${ name.includes('H') ? name : '' },我是一名${ job },今年${ age[1] }岁。"
let data = {
name: 'Henry',
gender: 'male',
job: 'software engineer',
age: [24, 25]
}
function render (template = '', data) {
if (data === null) return
const MUSTACHE_REG = /\$\{.*?\}/ig
const KEY_REG = /(?<=\$\{(\s*?)).*?(?=(\s*?)\})/ig
return template.replace(MUSTACHE_REG, function (match = '') {
let content = match.match(KEY_REG)[0].trim()
let result
with (data) {
result = eval(content)
}
return result
})
}
console.log(render(template, data)) // 大家好,我的名字叫做Henry,我是一名software engineer,今年25岁。 |
第二种方案其实仍然不够好,原因就是 eval 存在安全隐患,不推荐继续使用它。能够想到的替代方案就是 new Function,把需要执行的代码拼接成字符串: let template = "大家好,我的名字叫做 ${ name.includes('H') ? name : '' },我是一名 ${ job },今年 ${ age[1] } 岁。"
let data = {
name: 'Henry',
gender: 'male',
job: 'software engineer',
age: [24, 25]
}
function render (template = '', data) {
if (data === null) return
const MUSTACHE_REG = /\$\{.*?\}/ig
const KEY_REG = /(?<=\$\{(\s*?)).*?(?=(\s*?)\})/ig
return template.replace(MUSTACHE_REG, function (match = '') {
let content = match.match(KEY_REG)[0].trim()
let result = new Function('obj', 'with (obj) { return ' + content + '}')(data)
return result
})
}
console.log(render(template, data)) // 大家好,我的名字叫做 Henry,我是一名 software engineer,今年 25 岁。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The text was updated successfully, but these errors were encountered: