我在GitHub找到了一个用于字符串插值的简短代码段,并将其缩短为:
var interpolate = function (tmpl, data) {
return new Function('data', 'with(data){return \'' +
tmpl.replace(/{{\s*(.+?)\s*}}/g, '\'+($1)+\'') + '\';}')(data);
};
它适用于此:
interpolate('Hello {{user.name}}!', {user: {name: 'Admin'}});
// Hello Admin!
但是有两个我不喜欢的结果:
interpolate('Hello {{user.firstname}}!', {user: {name: 'Admin'}});
// Hello undefined!
和这一个:
interpolate('Hello {{user.name}}!', {userinfo: {name: 'Admin'}});
// Uncaught ReferenceError: user is not defined(…)
如果密钥不存在,有没有办法修改剪切使用默认(空字符串)?
更新 现在我找到了满足我所有要求的解决方案:
function interpolate(tmpl, data, defaultValue, reg) {
return tmpl.replace(reg || /{{([^{}]*)}}/g, function(a, b) {
try {
return new Function('data', ['with(data){return ',b,' || \'',(defaultValue || ''),'\';}'].join(''))(data);
}
catch(e) {
return defaultValue || '';
}
});
}
interpolate('Existing value: {{user.name}} - global value: {{Date.now()}} - undefined: {{user.age}} - exception: {{dat.haha}}', {user: {name: 'Admin'}}, '?');
// "Existing value: Admin - global value: 1441555682168 - undefined: ? - exception: ?"
建议很好!
答案 0 :(得分:1)
以下是有效的,假设您在字符串中只有一个占位符:
var interpolate = function(s, data) {
var RE= /{{\s*(.+?)\s*}}/,
sp= s.match(RE)[1].split('.'); //example: ['user','name']
sp.forEach(function(key) {
data= data[key] || ''; //walk the object, defaulting to null string if undefined
});
return s.replace(RE, data);
};
console.log(interpolate('Hello {{user.name}}!', {user: {name: 'Admin'}}));
console.log(interpolate('Hello {{user.firstname}}!', {user: {name: 'Admin'}}));
console.log(interpolate('Hello {{user.name}}!', {userinfo: {name: 'Admin'}}));
不幸的是像{{Date.now()}}这样的表达式不适用于此 溶液
在这种情况下,您执行需要使用new Function()
或eval()
。
您可以在函数声明字符串中添加短路评估(|| ''
)以避免未定义的对象属性,以及try...catch
以避免未捕获的引用错误。
在下面的Snippet中,第二个示例的函数字符串最终看起来像这样:
with(data) try {
return 'Hello '+(user.firstname || "")+'!';
} catch(e) {
return 'Hello !'
}
<强>段:强>
var interpolate = function (tmpl, data) {
var f= 'with(data) try{return \'' +
tmpl.replace(/{{\s*(.+?)\s*}}/g, ('\'+($1 || "")+\'') ) + '\';}'+
'catch(e) {return \'' +
tmpl.replace(/{{\s*(.+?)\s*}}/g, '') + "'"+
'}';
return new Function('data', f)(data);
};
console.log(interpolate('Hello {{user.name}}, it is currently {{Date()}}!', {user: {name: 'Admin'}}));
console.log(interpolate('Hello {{user.firstname}}!', {user: {name: 'Admin'}}));
console.log(interpolate('Hello {{user.name}}!', {userinfo: {name: 'Admin'}}));