web-dev-qa-db-ja.com

JavaScriptで文字列を補間する方法を教えてください。

このコードを見てください:

var age = 3;

console.log("I'm " + age + " years old!");

文字列の連結以外に、変数の値を文字列に挿入する方法は他にありますか?

414
Tom Lehman

ES6以降、 テンプレートリテラル を使用できます。

let age = 3
console.log(`I'm ${age} years old!`)

P.S。バッククォートの使用に注意してください:``

353
Damjan Pavlica

tl; dr

該当する場合は、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'

もう一つ重要なことは、複数行の文字列についてもう心配する必要はないということです。あなたはそれらを単純に書くことができます

> `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のユーザーで、今これに興味を持っています。 このテストベッド は、誰もがこれをサポートするようになるまで使用できます。

220
thefourtheye

Douglas Crockfordの 修復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のプロトタイプを変更したくない場合は、いつでもスタンドアローンにすることも、他の名前空間に配置することもできます。

185
Chris Nielsen

注意事項:独自の区切り文字をエスケープできないようなテンプレートシステムは避けてください。たとえば、ここで説明した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(" ");
49
greg.kindel

sprintf を試してください。例えば:

vsprintf('The first 4 letters of the english alphabet are: %s, %s, %s and %s', ['a', 'b', 'c', 'd']);
22
NawaMan

あなたが本当にハンマーを使ってナッツをクラックするのが好きなら、 Prototypeのテンプレートシステム を使うことができます。

var template = new Template("I'm #{age} years old!");
alert(template.evaluate({age: 21}));
21
shuckster

まだ適切に実行する方法がわからず、すぐにアイデアを得たい場合は、このパターンを多くの言語で使用します。

// JavaScript
var 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'
15
Jefferey Cave

ES6のtemplate stringを使って簡単に行うことができ、babelのような利用可能な任意のtranspilarを使ってES5にtranspileすることができます。

const age = 3;

console.log(`I'm ${age} years old!`);

http://www.es6fiddle.net/im3c3euc/

9
Mohammad Arif

これはオブジェクトに値を提供することを要求する解決策です。オブジェクトをパラメータとして指定しないと、デフォルトでグローバル変数が使用されます。しかし、パラメータの使用に固執すると、はるかにきれいになります。

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>
6

kiwi を試してください。文字列補間のための軽量なJavaScriptモジュールです。

できるよ

Kiwi.compose("I'm % years old!", [age]);

または

Kiwi.compose("I'm %{age} years old!", {"age" : age});
6
zs2020

一重引用符(`)または二重引用符(')およびドル記号/括弧記号"の代わりに${ variable }グレーブアクセントをバッククォート としても使用)

例えば:

console.log(
  `current date: ${new Date()}`
);

テンプレートリテラル についての詳細はこちら をご覧ください。

5
Hardik

console.logの出力を補間したい場合は、

console.log("Eruption 1: %s", eruption1);
                         ^^

ここで、%sは「フォーマット指定子」と呼ばれるものです。 console.logには、この種の補間サポートが組み込まれています。

4
user663031

もう1つのハンマー: jquery-tmpl (jQueryによるテンプレート)。

3
Jo Liss

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!');
2
James Ko

例を挙げて説明します。

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'));
1
shades3002

ES6以降、オブジェクトキーで文字列補間を行いたい場合は、次のようにするとSyntaxError: expected property name, got '${'が返されます。

let age = 3
let obj = { `${age}`: 3 }

代わりに次のことをしてください。

let obj = { [`${age}`]: 3 }
1
Yuxuan Chen

@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."
0
SoEzPz

カスタムの柔軟な補間:

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>
0
vsync

テンプレート構文を使用すると、古いブラウザでは失敗します。一般向けのHTMLを作成している場合は重要です。連結を使用するのは面倒で読みにくく、特に多数のまたは長い式がある場合、または数字と文字列の項目の混合を処理するために括弧を使用する必要がある場合(両方とも+演算子を使用)は。

PHPは非常にコンパクトな表記法を使用して、変数といくつかの式を含む引用符付き文字列を展開します。$a="the color is $color";

JavaScriptでは、これをサポートする効率的な関数var a=S('the color is ',color);を可変数の引数を使って書くことができます。この例では連結に勝る利点はありませんが、式が長くなると、この構文はより明確になります。 PHPのように、JavaScript関数を使用してドル記号を使用して式の開始を通知することもできます。

一方、古いブラウザでテンプレートのような文字列の展開を提供する効率的な回避策を書くのは難しくありません。誰かがすでにそれをやっているでしょう。

最後に、sprintf(C、C++、PHPなど)はJavaScriptで記述できると思いますが、これらの他のソリューションよりも効率は少し劣ります。

0
David Spector