考虑以下代码:
var age = 3;
console.log("I'm " + age + " years old!");
除了使用字符串拼接,还有其他方式将变量的值插入到字符串中吗?
考虑以下代码:
var age = 3;
console.log("I'm " + age + " years old!");
除了使用字符串拼接,还有其他方式将变量的值插入到字符串中吗?
let age = 3;
console.log(`I'm ${age} years old!`);
``
和ES6模板字符串。试试 kiwi,一个轻量级的 JavaScript 模块,用于字符串插值。
你可以这样做:
Kiwi.compose("I'm % years old!", [age]);
或者
Kiwi.compose("I'm %{age} years old!", {"age" : age});
以下是一种解决方案,需要您提供一个包含值的对象作为参数。如果不提供对象作为参数,它将默认使用全局变量。但最好使用参数,这样更加清晰易懂。
String.prototype.interpolate = function(props) {
return this.replace(/\{(\w+)\}/g, function(match, expr) {
return (props || window)[expr];
});
};
// Test:
// Using the parameter (advised approach)
document.getElementById("resultA").innerText = "Eruption 1: {eruption1}".interpolate({ eruption1: 112 });
// Using the global scope
var eruption2 = 116;
document.getElementById("resultB").innerText = "Eruption 2: {eruption2}".interpolate();
<div id="resultA"></div><div id="resultB"></div>
eval
,它是有害的! - chris97ongeval
,但有时候也不行。例如,如果发帖者想要一种方式来使用当前作用域进行插值,而不必传递查找对象(就像Groovy插值的工作方式),我确信需要使用eval
。不要只是诉诸于老掉牙的“eval
是邪恶的”。 - Ian一开始没找到想要的,后来找到了 -
如果你使用Node.js,内置有一个名为util
的包,其中有一个格式化函数,用法如下:
util.format("Hello my name is %s", "Brent");
> Hello my name is Brent
console.log
里了。console.log("This really bad error happened: %s", "ReferenceError");
> This really bad error happened: ReferenceError
在Greg Kindel的第二个答案基础上,您可以编写一个函数来消除一些样板文件:
var fmt = {
join: function() {
return Array.prototype.slice.call(arguments).join(' ');
},
log: function() {
console.log(this.join(...arguments));
}
}
使用方法:
var age = 7;
var years = 5;
var sentence = fmt.join('I am now', age, 'years old!');
fmt.log('In', years, 'years I will be', age + years, 'years old!');
我可以用一个例子来说明:
function fullName(first, last) {
let fullName = first + " " + last;
return fullName;
}
function fullNameStringInterpolation(first, last) {
let fullName = `${first} ${last}`;
return fullName;
}
console.log('Old School: ' + fullName('Carlos', 'Gutierrez'));
console.log('New School: ' + fullNameStringInterpolation('Carlos', 'Gutierrez'));
为@Chris Nielsen的文章提供更多关于ES6版本的替代内容。
String.prototype.supplant = function (o) {
return this.replace(/\${([^\${}]*)}/g,
(a, b) => {
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a;
}
);
};
string = "How now ${color} cow? {${greeting}}, ${greeting}, moo says the ${color} cow.";
string.supplant({color: "brown", greeting: "moo"});
=> "How now brown cow? {moo}, moo, moo says the brown cow."
SyntaxError: expected property name, got '${'
:let age = 3
let obj = { `${age}`: 3 }
let obj = { [`${age}`]: 3 }
如果你正在创建公共使用的HTML,那么在旧版浏览器中使用模板语法会失败,这一点非常重要。使用连接操作很繁琐且难以阅读,特别是当你有许多或长表达式时,或者必须使用括号来处理数字和字符串项的混合(两者都使用+运算符)。
PHP使用非常紧凑的符号扩展带有变量甚至某些表达式的引用字符串:$a="the color is $color";
在JavaScript中,可以编写一个高效的函数来支持此操作:var a=S('the color is ',color);
,使用可变数量的参数。虽然在这个例子中与连接操作相比没有优势,但当表达式变得更长时,这种语法可能更清晰。或者,可以使用美元符号来表示使用JavaScript函数开始表达式,就像在PHP中一样。
另一方面,为旧版浏览器编写一个有效的解决方案函数以提供类似模板的字符串扩展并不难。可能已经有人做过了。
最后,我想象sprintf(如C、C++和PHP中所示)可以在JavaScript中编写,尽管它可能比其他解决方案稍微低效一些。
var sourceElm = document.querySelector('input')
// interpolation callback
const onInterpolate = s => `<mark>${s}</mark>`
// listen to "input" event
sourceElm.addEventListener('input', parseInput)
// parse on window load
parseInput()
// input element parser
function parseInput(){
var html = interpolate(sourceElm.value, undefined, onInterpolate)
sourceElm.nextElementSibling.innerHTML = html;
}
// the actual interpolation
function interpolate(str, interpolator = ["{{", "}}"], cb){
// split by "start" pattern
return str.split(interpolator[0]).map((s1, i) => {
// first item can be safely ignored
if( i == 0 ) return s1;
// for each splited part, split again by "end" pattern
const s2 = s1.split(interpolator[1]);
// is there's no "closing" match to this part, rebuild it
if( s1 == s2[0]) return interpolator[0] + s2[0]
// if this split's result as multiple items' array, it means the first item is between the patterns
if( s2.length > 1 ){
s2[0] = s2[0]
? cb(s2[0]) // replace the array item with whatever
: interpolator.join('') // nothing was between the interpolation pattern
}
return s2.join('') // merge splited array (part2)
}).join('') // merge everything
}
input{
padding:5px;
width: 100%;
box-sizing: border-box;
margin-bottom: 20px;
}
*{
font: 14px Arial;
padding:5px;
}
<input value="Everything between {{}} is {{processed}}" />
<div></div>
Show GRAPH of : AIP001-_sma
(在字符串1周围使用反引号,无法在此处显示)。 - Marcos