Bagaimana cara menginterpolasi variabel dalam string dalam JavaScript, tanpa penggabungan?


409

Saya tahu di PHP kita bisa melakukan sesuatu seperti ini:

$hello = "foo";
$my_string = "I pity the $hello";

Keluaran: "I pity the foo"

Saya bertanya-tanya apakah hal yang sama ini dimungkinkan dalam JavaScript juga. Menggunakan variabel di dalam string tanpa menggunakan penggabungan - terlihat lebih ringkas dan elegan untuk ditulis.

Jawaban:


696

Anda dapat memanfaatkan Literal Templat dan menggunakan sintaks ini:

`String text ${expression}`

Literal templat terlampir oleh tanda centang-belakang (``) (aksen kubur) alih-alih kutipan ganda atau tunggal.

Fitur ini telah diperkenalkan di ES2015 (ES6).

Contoh

var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b}.`);
// "Fifteen is 15.

Seberapa rapi itu?

Bonus:

Ini juga memungkinkan untuk string multi-line dalam javascript tanpa melarikan diri, yang bagus untuk template:

return `
    <div class="${foo}">
         ...
    </div>
`;

Dukungan browser :

Karena sintaks ini tidak didukung oleh browser lama (kebanyakan Internet Explorer), Anda mungkin ingin menggunakan Babel / Webpack untuk mengubah kode Anda ke ES5 untuk memastikan itu akan berjalan di mana-mana.


Catatan:

Mulai dari IE8 + Anda dapat menggunakan pemformatan string dasar di dalam console.log:

console.log('%s is %d.', 'Fifteen', 15);
// Fifteen is 15.

57
Jangan lewatkan fakta bahwa string template dibatasi dengan tanda centang kembali (`) alih-alih karakter kutipan normal Anda. "${foo}"secara harfiah $ {foo} `${foo}`adalah apa yang sebenarnya Anda inginkan
Hovis Biddle

1
Juga ada banyak transponder untuk mengubah ES6 menjadi ES5 untuk memperbaiki masalah kompatibilitas!
Nick

ketika saya mengubah nilai a atau b. console.log ( Fifteen is ${a + b}.); tidak berubah secara dinamis. itu selalu menunjukkan Lima Belas adalah 15.
Dharan

168

Sebelum Firefox 34 / Chrome 41 / Safari 9 / Microsoft Edge, tidak, itu tidak mungkin di javascript. Anda harus resor ke:

var hello = "foo";
var my_string = "I pity the " + hello;

2
Ini akan segera dimungkinkan dalam javascript (ES6) dengan Templat String, lihat jawaban terperinci saya di bawah ini.
bformet

Mungkin saja jika Anda suka menulis CoffeeScript, yang sebenarnya IS javascript dengan sintaks yang lebih baik.
bformet

1
Seruan luar biasa untuk peramban yang lebih lama :)
Kirsty Marks

1
Aku kasihan pada FOO !!! itu hebat
Adam Hughes


32

baik Anda bisa melakukan ini, tetapi itu bukan esp umum

'I pity the $fool'.replace('$fool', 'fool')

Anda dapat dengan mudah menulis fungsi yang melakukan ini dengan cerdas jika Anda benar-benar perlu


Sebenarnya lumayan lumayan.
Tn. B

1
Jawaban ini bagus ketika Anda perlu menyimpan string template dalam database dan memprosesnya sesuai permintaan
Dima Escaroda

Bagus, itu bekerja dengan baik. sangat sederhana tetapi tidak muncul di pikiran.
Sam

13

Jawaban lengkap, siap digunakan:

 var Strings = {
        create : (function() {
                var regexp = /{([^{]+)}/g;

                return function(str, o) {
                     return str.replace(regexp, function(ignore, key){
                           return (key = o[key]) == null ? '' : key;
                     });
                }
        })()
};

Sebut sebagai

Strings.create("My firstname is {first}, my last name is {last}", {first:'Neo', last:'Andersson'});

Untuk melampirkannya ke String.prototype:

String.prototype.create = function(o) {
           return Strings.create(this, o);
}

Kemudian gunakan sebagai:

"My firstname is ${first}".create({first:'Neo'});

10

Anda dapat menggunakan fungsi javascript ini untuk melakukan templating semacam ini. Tidak perlu menyertakan seluruh perpustakaan.

function createStringFromTemplate(template, variables) {
    return template.replace(new RegExp("\{([^\{]+)\}", "g"), function(_unused, varName){
        return variables[varName];
    });
}

createStringFromTemplate(
    "I would like to receive email updates from {list_name} {var1} {var2} {var3}.",
    {
        list_name : "this store",
        var1      : "FOO",
        var2      : "BAR",
        var3      : "BAZ"
    }
);

Keluaran :"I would like to receive email updates from this store FOO BAR BAZ."

Menggunakan fungsi sebagai argumen ke fungsi String.replace () adalah bagian dari spesifikasi ECMAScript v3. Lihat jawaban SO ini untuk lebih jelasnya.


Apakah ini efisien?
mmm

Efisiensi akan sangat tergantung pada browser pengguna, karena solusi ini mendelegasikan "angkat berat" yang cocok dengan regex dan melakukan penggantian string ke fungsi asli browser. Bagaimanapun, karena hal ini terjadi pada sisi browser, efisiensi bukanlah masalah besar. Jika Anda ingin templating sisi-server (untuk Node.JS atau sejenisnya) Anda harus menggunakan solusi literal template ES6 yang dijelaskan oleh @bformet, karena kemungkinan lebih efisien.
Eric Seastrand

9

Jika Anda suka menulis CoffeeScript, Anda dapat melakukannya:

hello = "foo"
my_string = "I pity the #{hello}"

CoffeeScript sebenarnya IS javascript, tetapi dengan sintaks yang jauh lebih baik.

Untuk tinjauan umum tentang CoffeeScript, periksa panduan pemula ini .



3

Saya menulis paket npm ini stringinject https://www.npmjs.com/package/stringinject yang memungkinkan Anda melakukan hal berikut

var string = stringInject("this is a {0} string for {1}", ["test", "stringInject"]);

yang akan mengganti {0} dan {1} dengan item-item array dan mengembalikan string berikut

"this is a test string for stringInject"

atau Anda bisa mengganti placeholder dengan kunci dan nilai objek seperti:

var str = stringInject("My username is {username} on {platform}", { username: "tjcafferkey", platform: "GitHub" });

"My username is tjcafferkey on Github" 

3

Saya akan menggunakan tanda centang-kembali ``.

let name1 = 'Geoffrey';
let msg1 = `Hello ${name1}`;
console.log(msg1); // 'Hello Geoffrey'

Tetapi jika Anda tidak tahu name1kapan Anda membuatnya msg1.

Contohnya jika msg1berasal dari API.

Kamu bisa menggunakan :

let name2 = 'Geoffrey';
let msg2 = 'Hello ${name2}';
console.log(msg2); // 'Hello ${name2}'

const regexp = /\${([^{]+)}/g;
let result = msg2.replace(regexp, function(ignore, key){
    return eval(key);
});
console.log(result); // 'Hello Geoffrey'

Itu akan menggantikan ${name2}nilainya.


2

Tidak melihat perpustakaan eksternal yang disebutkan di sini, tetapi Lodash memiliki _.template(),

https://lodash.com/docs/4.17.10#template

Jika Anda sudah menggunakan perpustakaan, ada baiknya memeriksa, dan jika Anda tidak menggunakan Lodash, Anda selalu dapat memilih metode dari npm npm install lodash.templatesehingga Anda dapat mengurangi biaya overhead.

Bentuk paling sederhana -

var compiled = _.template('hello <%= user %>!');
compiled({ 'user': 'fred' });
// => 'hello fred!'

Ada banyak opsi konfigurasi juga -

_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
var compiled = _.template('hello {{ user }}!');
compiled({ 'user': 'mustache' });
// => 'hello mustache!'

Saya menemukan pembatas khusus paling menarik.


0

Buat metode yang mirip dengan String.format()Java

StringJoin=(s, r=[])=>{
  r.map((v,i)=>{
    s = s.replace('%'+(i+1),v)
  })
return s
}

menggunakan

console.log(StringJoin('I can %1 a %2',['create','method'])) //output: 'I can create a method'

0

Kutipan damai tahun 2020:

Console.WriteLine("I {0} JavaScript!", ">:D<");

console.log(`I ${'>:D<'} C#`)

0

Cukup gunakan:

var util = require('util');

var value = 15;
var s = util.format("The variable value is: %s", value)

-1
String.prototype.interpole = function () {
    var c=0, txt=this;
    while (txt.search(/{var}/g) > 0){
        txt = txt.replace(/{var}/, arguments[c]);
        c++;
    }
    return txt;
}

Uso:

var hello = "foo";
var my_string = "I pity the {var}".interpole(hello);
//resultado "I pity the foo"

-2

var hello = "foo";

var my_string ="I pity the";

console.log (my_string, halo)


1
Itu tidak menjawab pertanyaan. Anda mungkin keluar dari kedua string dalam satu baris, tetapi itu tidak memberi Anda string baru yang mengandung kedua string, yang diminta OP.
Max Vollmer
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.