このコードを考えてみましょう:
var age = 3;
console.log("I'm " + age + " years old!");
文字列の連結以外に、変数の値を文字列に挿入する方法は他にありますか?
Show GRAPH of : ${fundCode}-${funcCode}
私を取得しますShow GRAPH of : AIP001-_sma
(文字列1.の周りにバックティックを使用します...ここには表示されないようです)
このコードを考えてみましょう:
var age = 3;
console.log("I'm " + age + " years old!");
文字列の連結以外に、変数の値を文字列に挿入する方法は他にありますか?
Show GRAPH of : ${fundCode}-${funcCode}
私を取得しますShow GRAPH of : AIP001-_sma
(文字列1.の周りにバックティックを使用します...ここには表示されないようです)
回答:
ES6以降、テンプレートリテラルを使用できます。
const age = 3
console.log(`I'm ${age} years old!`)
PSバックティックの使用に注意してください``
。
必要に応じて、ECMAScript 2015のテンプレート文字列リテラルを使用します。
ECMAScript 5仕様のとおり、直接実行する方法はありませんが、ECMAScript 6にはテンプレート文字列があり、仕様の草案では準リテラルとしても知られていました。次のように使用します。
> var n = 42;
undefined
> `foo${n}bar`
'foo42bar'
内では任意の有効なJavaScript式を使用できます{}
。例えば:
> `foo${{name: 'Google'}.name}bar`
'fooGooglebar'
> `foo${1 + 3}bar`
'foo4bar'
もう1つ重要なことは、複数行の文字列についてもう心配する必要がないことです。単純に次のように書くことができます
> `foo
... bar`
'foo\n bar'
注: io.js v2.4.0を使用して、上記のすべてのテンプレート文字列を評価しました。また、最新のChromeを使用して、上記の例をテストすることもできます。
注: ES6仕様は最終決定されましたが、すべての主要なブラウザーでまだ実装されていません。Mozilla Developer Networkページに
よると、これは、Firefox 34、Chrome 41、Internet Explorer 12以降の基本的なサポートのために実装される予定です。Opera、Safari、またはInternet Explorerのユーザーで、これに興味がある場合、このテストベッドは、誰もがこれをサポートするまで、遊ぶために使用できます。
Douglas CrockfordのRemedial JavaScriptにはString.prototype.supplant
関数が含まれています。短く、使いやすく、使いやすいです。
String.prototype.supplant = function (o) {
return this.replace(/{([^{}]*)}/g,
function (a, b) {
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a;
}
);
};
// Usage:
alert("I'm {age} years old!".supplant({ age: 29 }));
alert("The {a} says {n}, {n}, {n}!".supplant({ a: 'cow', n: 'moo' }));
Stringのプロトタイプを変更したくない場合は、いつでもスタンドアロンに適合させるか、他の名前空間などに配置できます。
"The {0} says {1}, {1}, {1}!".supplant(['cow', 'moo'])
注意事項:独自の区切り文字をエスケープできないテンプレートシステムは避けてください。たとえば、supplant()
ここに記載されている方法を使用して以下を出力する方法はありません。
「{age}変数のおかげで3歳です。」
単純な補間は小さな自己完結型のスクリプトで機能する可能性がありますが、深刻な使用を制限するこの設計上の欠陥がしばしば付属しています。私は正直に、次のようなDOMテンプレートを好みます。
<div> I am <span id="age"></span> years old!</div>
そしてjQuery操作を使用します: $('#age').text(3)
または、単に文字列の連結に飽き飽きしている場合は、常に代替の構文があります。
var age = 3;
var str = ["I'm only", age, "years old"].join(" ");
token
-したがって、age
メンバーを持つデータオブジェクトを指定しない場合は問題ありません。
supplant
は不当です"I am 3 years old thanks to my {age} variable.".supplant({}));
。指定された文字列を正確に返します。指定された場合age
でも、印刷{
して}
使用できます{{age}}
多くの言語でこのパターンを使用していますが、適切に実行する方法がわからないため、アイデアをすばやく取得したいと考えています。
// JavaScript
let stringValue = 'Hello, my name is {name}. You {action} my {relation}.'
.replace(/{name}/g ,'Indigo Montoya')
.replace(/{action}/g ,'killed')
.replace(/{relation}/g,'father')
;
特に効率的ではありませんが、読みやすいと思います。それは常に機能し、常に利用可能です:
' VBScript
dim template = "Hello, my name is {name}. You {action} my {relation}."
dim stringvalue = template
stringValue = replace(stringvalue, "{name}" ,"Luke Skywalker")
stringValue = replace(stringvalue, "{relation}","Father")
stringValue = replace(stringvalue, "{action}" ,"are")
常に
* COBOL
INSPECT stringvalue REPLACING FIRST '{name}' BY 'Grendel'
INSPECT stringvalue REPLACING FIRST '{relation}' BY 'Mother'
INSPECT stringvalue REPLACING FIRST '{action}' BY 'did unspeakable things to'
ハンマーを使ってナットをクラックしたい場合は、Prototypeのテンプレートシステムを使用できます。
var template = new Template("I'm #{age} years old!");
alert(template.evaluate({age: 21}));
ES6 template string
を使用して簡単に行うことができ、babelなどの利用可能な任意の乳頭を使用してES5にトランスパイルできます。
const age = 3;
console.log(`I'm ${age} years old!`);
console.log
出力で補間したい場合は、
console.log("Eruption 1: %s", eruption1);
^^
ここで、%s
「書式指定子」と呼ばれるものです。console.log
この種の補間サポートが組み込まれています。
これは、オブジェクトに値を提供する必要があるソリューションです。オブジェクトをパラメーターとして指定しない場合、デフォルトでグローバル変数が使用されます。しかし、パラメータの使用に固執するほうがずっときれいです。
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
、eval
悪です!
eval
、そうでない場合もあります。たとえば、OPが現在のスコープを使用して補間する方法が必要な場合(たとえば、Groovy補間のように)ルックアップオブジェクトを渡さなくてeval
も、必要になると確信しています。古い「eval is evil」に頼るだけではいけません。
eval
スコープ内のローカル変数にアクセスする唯一の方法です。それはあなたの気持ちを傷つけるからといってそれを拒否しないでください。ところで、私はそれがより安全であるので、私も代替の方法を好みます、しかし、eval
方法はOPの質問に正確に答えるものであり、それゆえ、それは答えにあります。
eval
は、別のスコープからvarにアクセスできないため、.interpolate
呼び出しがグローバルではなく別の関数内にある場合、機能しないことです。
Greg Kindelの 2番目の答えを拡張すると、定型文の一部を削除する関数を記述できます。
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."
古いブラウザでテンプレート構文を使用すると失敗します。これは、パブリック用のHTMLを作成する場合に重要です。連結の使用は、特に式が多い場合や長い場合、または括弧を使用して数値と文字列の両方の項目(+演算子を使用)を処理する必要がある場合は、面倒で読みにくいものです。
PHPは、非常にコンパクトな表記法を使用して、変数および一部の式を含む引用文字列を拡張します。 $a="the color is $color";
JavaScriptでは、var a=S('the color is ',color);
可変数の引数を使用して、これをサポートする効率的な関数を作成できます。この例では連結に勝る利点はありませんが、式が長くなると、この構文はより明確になる場合があります。または、ドル記号を使用して、PHPのようにJavaScript関数を使用して式の開始を示すことができます。
一方、古いブラウザにテンプレートのような文字列の拡張を提供する効率的な回避策関数を書くことは難しくありません。おそらく誰かがすでにそれを行っているでしょう。
最後に、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>
テンプレートはおそらく説明するケースに最適ですが、データや引数を反復可能/配列形式で持っている、または必要とする場合は、を使用できますString.raw
。
String.raw({
raw: ["I'm ", " years old!"]
}, 3);
データを配列として使用すると、spread演算子を使用できます。
const args = [3, 'yesterday'];
String.raw({
raw: ["I'm ", " years old as of ", ""]
}, ...args);
探していたものが見つからず、見つかりました-
Node.jsを使用している場合、次のutil
ように機能するformat関数を備えた組み込みパッケージがあります。
util.format("Hello my name is %s", "Brent");
> Hello my name is Brent
偶然にも、これはconsole.log
Node.jsでもフレーバーに組み込まれています-
console.log("This really bad error happened: %s", "ReferenceError");
> This really bad error happened: ReferenceError