如果密钥不存在,则使用默认插值

时间:2015-09-05 19:33:23

标签: javascript string interpolation string-interpolation

我在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: ?"

建议很好!

1 个答案:

答案 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'}}));