Làm cách nào để nội suy các biến trong chuỗi trong JavaScript mà không cần nối?


409

Tôi biết trong PHP chúng ta có thể làm một cái gì đó như thế này:

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

Đầu ra: "I pity the foo"

Tôi đã tự hỏi nếu điều này cũng có thể có trong JavaScript. Sử dụng các biến bên trong chuỗi mà không sử dụng nối - nó trông ngắn gọn và thanh lịch hơn để viết.

Câu trả lời:


696

Bạn có thể tận dụng Văn bản mẫu và sử dụng cú pháp này:

`String text ${expression}`

Các chữ mẫu được kèm theo dấu tick (``) (dấu trọng âm) thay vì dấu ngoặc kép hoặc dấu ngoặc đơn.

Tính năng này đã được giới thiệu trong ES2015 (ES6).

Thí dụ

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

Làm thế nào gọn gàng?

Tặng kem:

Nó cũng cho phép các chuỗi nhiều dòng trong javascript mà không thoát, điều này rất tốt cho các mẫu:

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

Hỗ trợ trình duyệt :

Vì cú pháp này không được hỗ trợ bởi các trình duyệt cũ hơn (chủ yếu là Internet Explorer), bạn có thể muốn sử dụng Babel / Webpack để chuyển mã của bạn sang ES5 để đảm bảo nó sẽ chạy ở mọi nơi.


Lưu ý bên:

Bắt đầu từ IE8 +, bạn có thể sử dụng định dạng chuỗi cơ bản bên trong console.log:

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

57
Đừng bỏ lỡ thực tế là chuỗi mẫu được phân định bằng dấu tick ngược (`) thay vì các ký tự trích dẫn thông thường của bạn. "${foo}"nghĩa đen là $ {foo} `${foo}`là những gì bạn thực sự muốn
Hovis Biddle

1
Ngoài ra, có rất nhiều bộ chuyển đổi để biến ES6 thành ES5 để khắc phục vấn đề tương thích!
Nick

khi tôi thay đổi giá trị a hoặc b. console.log ( Fifteen is ${a + b}.); không thay đổi linh hoạt. nó luôn hiển thị Mười lăm là 15.
Dhara

168

Trước Firefox 34 / Chrome 41 / Safari 9 / Microsoft Edge, không, điều đó là không thể trong javascript. Bạn sẽ phải dùng đến:

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

2
Nó sẽ sớm có thể có trong javascript (ES6) với Chuỗi mẫu, xem câu trả lời chi tiết của tôi dưới đây.
bformet

Có thể nếu bạn muốn viết CoffeeScript, đây thực sự là javascript với cú pháp tốt hơn.
bformet

1
Tiếng hét tuyệt vời cho các trình duyệt cũ hơn :)
Kirsty Marks

1
Tôi thương hại FOO !!! thật tuyệt
Adam Hughes


32

tốt, bạn có thể làm điều này, nhưng nó không đặc biệt chung

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

Bạn có thể dễ dàng viết một hàm thực hiện điều này một cách thông minh nếu bạn thực sự cần


Khá tốt, thực sự.
Ông B

1
Câu trả lời này rất tốt khi bạn cần lưu trữ chuỗi mẫu trong cơ sở dữ liệu và xử lý nó theo yêu cầu
Dima Escaroda 16/07/18

Tốt, nó hoạt động tốt. rất đơn giản nhưng không xuất hiện trong tâm trí.
Sam

13

Câu trả lời đầy đủ, sẵn sàng để được sử dụng:

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

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

Gọi như

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

Để đính kèm nó vào String.prototype:

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

Sau đó sử dụng như:

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

10

Bạn có thể sử dụng chức năng javascript này để thực hiện kiểu tạo khuôn mẫu này. Không cần bao gồm toàn bộ thư viện.

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"
    }
);

Đầu ra :"I would like to receive email updates from this store FOO BAR BAZ."

Sử dụng hàm làm đối số cho hàm String.replace () là một phần của đặc tả ECMAScript v3. Xem câu trả lời SO này để biết thêm chi tiết.


Đây có phải là hiệu quả?
mmm

Hiệu quả sẽ phụ thuộc phần lớn vào trình duyệt của người dùng, vì giải pháp này ủy thác cho "sự nặng nề" của việc khớp với biểu thức chính quy và thực hiện thay thế chuỗi cho các chức năng gốc của trình duyệt. Trong mọi trường hợp, vì dù sao điều này cũng xảy ra ở phía trình duyệt, nên hiệu quả không phải là vấn đề quá lớn. Nếu bạn muốn tạo khuôn mẫu phía máy chủ (cho Node.JS hoặc tương tự), bạn nên sử dụng giải pháp bằng chữ mẫu ES6 được mô tả bởi @bformet, vì nó có thể hiệu quả hơn.
Eric Seastrand



3

Tôi đã viết chuỗi ký tự npm này https://www.npmjs.com/package/opesinject cho phép bạn thực hiện các thao tác sau

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

sẽ thay thế {0} và {1} bằng các mục mảng và trả về chuỗi sau

"this is a test string for stringInject"

hoặc bạn có thể thay thế trình giữ chỗ bằng các khóa đối tượng và giá trị như vậy:

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

"My username is tjcafferkey on Github" 

3

Tôi sẽ sử dụng back-tick ``.

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

Nhưng nếu bạn không biết name1khi bạn tạo msg1.

Ví dụ nếu msg1 đến từ API.

Bạn có thể dùng :

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'

Nó sẽ thay thế ${name2}bằng giá trị của mình.


2

Không thấy bất kỳ thư viện bên ngoài nào được đề cập ở đây, nhưng Lodash có _.template(),

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

Nếu bạn đang sử dụng thư viện, bạn nên kiểm tra và nếu bạn không sử dụng Lodash, bạn luôn có thể chọn phương pháp chọn cherry từ npm npm install lodash.templateđể bạn có thể cắt giảm chi phí.

Hình thức đơn giản nhất -

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

Có một loạt các tùy chọn cấu hình -

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

Tôi tìm thấy các dấu phân cách tùy chỉnh thú vị nhất.


0

Tạo một phương thức tương tự như String.format()của Java

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

sử dụng

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

0

Báo giá hòa bình năm 2020:

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

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

0

Đơn giản chỉ cần sử dụng:

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;
}

Còn lại

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_opes, xin chào)


1
Điều đó không trả lời câu hỏi. Bạn có thể đăng xuất cả hai chuỗi trong một dòng, nhưng điều đó không cung cấp cho bạn một chuỗi mới chứa cả hai chuỗi, đó là những gì OP đang yêu cầu.
Max Vollmer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.