このコードを考えてみましょう:
var age = 3;
console.log("I'm " + age + " years old!");
文字列の連結以外に、変数の値を文字列に挿入する方法は他にありますか?
このコードを考えてみましょう:
var age = 3;
console.log("I'm " + age + " years old!");
文字列の連結以外に、変数の値を文字列に挿入する方法は他にありますか?
ES6以降、テンプレートリテラルを使用できます。
const age = 3
console.log(`I'm ${age} years old!`)
PSバックティックの使用に注意してください:``
。
該当する場合は、ECMAScript2015のテンプレート文字列リテラルを使用します。
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.jsv2.4.0を使用しました。最新のChromeを使用して、上記の例をテストすることもできます。
注: ES6仕様は現在完成していますが、すべての主要なブラウザーでまだ実装されていません。Mozilla Developer Network
のページによると、これは次のバージョンから始まる基本的なサポートのために実装されます:Firefox 34、Chrome 41、Internet Explorer12。Opera、Safari、またはInternet Explorerのユーザーで、今これに興味がある場合、このテストベッドは、誰もがこれをサポートするまで遊ぶために使用できます。
DouglasCrockfordのRemedialJavaScriptには関数が含まれてい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のプロトタイプを変更したくない場合は、いつでもスタンドアロンに適合させたり、他の名前空間に配置したりすることができます。
注意:独自の区切り文字をエスケープできないテンプレートシステムは避けてください。たとえば、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(" ");
このパターンは、まだ適切に行う方法がわからず、すぐにアイデアを出したいときに、多くの言語で使用します。
// JavaScript
let stringValue = 'Hello, my name is {name}. You {action} my {relation}.'
.replace(/{name}/g ,'Inigo 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}));
console.log
出力を補間したい場合は、
console.log("Eruption 1: %s", eruption1);
^^
%s
これがいわゆる「フォーマット指定子」です。console.log
この種の補間サポートが組み込まれています。
ES6を使用して簡単に実行できtemplate string
、babelなどの利用可能なトランスピラールを使用してES5にトランスパイルできます。
const age = 3;
console.log(`I'm ${age} years old!`);
文字列補間用の軽量JavaScriptモジュールであるkiwiを試してみてください。
できるよ
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>
最も単純なのは
`my string ${VARIABLE}`
これを達成するための効率の悪い方法は
function format(str, ...params) {
for(const param of params)
str = str.replace("%", param);
return str;
}
で使用できます
format("My % string", "interpolation")
グレッグキンデルの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'));
探していたものが見つからなかったので、見つけました-
Node.jsを使用している場合は、次のutil
ように機能するフォーマット関数を備えた組み込みパッケージがあります。
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
let age = 3;
console.log(`I'm ${age} years old!`);
バッククォート``とES6テンプレート文字列を使用できます
ES6以降、オブジェクトキーで文字列補間を実行するSyntaxError: expected property name, got '${'
場合は、次のような操作を行うと次のようになります。
let age = 3
let obj = { `${age}`: 3 }
代わりに次のことを行う必要があります。
let obj = { [`${age}`]: 3 }
@ChrisNielsenの投稿の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";
var a=S('the color is ',color);
JavaScriptでは、可変数の引数を使用して、これをサポートする効率的な関数を記述できます。この例では連結に勝る利点はありませんが、式が長くなると、この構文がより明確になる可能性があります。または、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);