没有直接的内置方法(好吧,也许有 - 见下文),但如果您使用replace
函数,其中替换可以是函数而不是字符串(返回值是替换的内容),您可以相当轻松地实现这一点。
例如,假设您使用 Ruby 表示法#{xyz}
为你的占位符。此代码循环遍历这些:
var mappings, str;
str = "One #{X} three #{Y} five";
mappings = {
"X": 2,
"Y": 4
};
str = str.replace(/\#\{([^#]+)\}/g, function(match, key) {
var result;
result = mappings[key];
/* ...processing here */
return result;
});
结果字符串是One 2 three 4 five
, 因为#{X}
and #{Y}
已通过查找替换。您可以查看该键,看看它是否是一个表达式,是否需要计算,而不是简单地查找。该评估才是您真正工作的所在。
现在轮到你could use with
and eval
实现表达支持;改变result = mapping[key];
上面一行:
with (mappings) {
result = eval(key);
}
如果你喂绳子"One #{X} three #{Y} five #{X + Y * 2}"
对此,结果是One 2 three 4 five 10
- 因为2 + 4 * 2
= 10.
这有效是因为with
将给定对象粘贴在作用域链的顶部,因此这是解析不合格引用时检查的第一件事(例如X
), and eval
执行 Javascript 代码——因此可以计算表达式——并且在调用它的范围内神奇地执行此操作。但要小心;正如 Eric 指出的,并非所有运算符在各种表达形式上都是相同的,特别是 Javascript 解释^
意思是“按位异或”,而不是“的幂”。 (它没有指数运算符;您必须使用Math.pow
.)
但你需要非常小心这类事情with
and eval
(各自以自己的方式)可能会出现问题。但主要问题是with
如果你做一项作业,你很难知道某样东西从哪里来,又会去哪里,而你却没有做;以及主要问题eval
来自使用它来解释您无法控制的字符串。只要您采取适当的保护措施并意识到这些问题......
将其归结为一个函数:
function evaluate(str, mappings) {
return str.replace(/\#\{([^#]+)\}/g, function(match, key) {
var result;
with (mappings) {
result = eval(key);
}
return result;
});
}
alert(evaluate(
"The expression '(#{X} + #{Y}) * 2' equals '#{(X + Y) * 2}'",
{"X": 2, "Y": 4}
)); // alerts "The expression '(2 + 4) * 2' equals '12'"
alert(evaluate(
"The expression '(#{X} + #{Y}) * 2' equals '#{(X + Y) * 2}'",
{"X": 6, "Y": 3}
)); // alerts "The expression '(6 + 3) * 2' equals '18'"