模板字面量

Avatar of Ryan Christiani
Ryan Christiani

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 $200 免费积分!

模板字面量是在 ES6 中引入的一种创建字符串的新方法。它带来了新的功能,使我们能够更好地控制程序中的动态字符串。告别冗长的字符串连接!

要创建模板字面量,我们使用反引号(`)字符,而不是单引号 (') 或双引号 (")。这将生成一个新的字符串,我们可以按需使用它。

基本用法

let newString = `A string`;

多行

模板字面量的优点是,我们现在可以创建多行字符串!过去,如果我们想要一个字符串跨越多行,我们必须使用\n 或换行符。

// The old way
var myMultiString = 'Some text that I want\nOn two lines!';

使用模板字面量字符串,我们只需在编写时将新行添加到字符串中即可。

var myMultiString= `This will be
on two lines!`;

这将生成一个包含新行的字符串。使用表达式实现此功能使模板字面量成为构建 HTML 片段的非常不错的模板语言,我们将在后面介绍。但是,连接怎么办?让我们看看如何将动态值添加到新的模板字面量中。

表达式

在新的模板字面量语法中,我们有称为表达式的项,它们看起来像这样:${expression}。考虑以下代码。

let name = `Ryan`;

console.log(`Hi my name is ${name}`);

${} 语法允许我们放入一个表达式,它将生成该值,在本例中只是一个包含字符串的变量!这里需要注意的是:如果您想添加值,如上所示,则不需要为name 变量使用模板字面量。它可以只是一个普通的字符串。

console.log(`Hi my name is ${'Ryan'}`);

这将生成相同的输出。这些表达式不仅允许我们放入包含字符串的变量。我们可以根据需要评估任何类型的表达式。

let price = 19.99;
let tax = 1.13;

let total = `The total prices is ${price * tax}`;

我们还可以将其与更复杂的对象一起使用。

let person = {
    firstName: `Ryan`,
    lastName: `Christiani`,
    sayName() {
        return `Hi my name is ${this.firstName} ${this.lastName}`;
    }
};

这里我们有一个person 对象,其中包含一个sayName() 方法。我们可以在${} 语法中访问对象中的属性。

HTML 模板

能够拥有多行字符串并使用模板表达式将内容添加到我们的字符串中,这使得它非常适合在我们的代码中使用 HTML 模板。

让我们假设我们从 API 获取了一些类似于此的数据

{
    "id": 1,
    "name": "Bulbasaur",
    "base_experience": 64,
    "height": 7,
    "is_default": true,
    "order": 1,
    "weight": 69,
    ...
}

这个“假想的”API 当然是 pokeapi!考虑到这种数据结构,让我们创建用于显示此神奇宝贝的标记。

function createMarkup(data) {
    return `
        <article class="pokemon">
            <h3>${data.name}</h3>
            <p>The Pokemon ${data.name} has a base experience of ${data.base_experience}, they also weigh ${data.weight}</p>
        </article>
    `
}

无需使用 Handlebars 或 Mustache 等库,我们就可以在 JavaScript 中创建简洁易用的模板!

标记模板

模板字面量的另一个功能是创建标记模板字面量。您可以创建一个函数,这个函数看起来和其他函数一样,但调用方式不同

function myTaggedLiteral(strings) {
    console.log(strings);
}

myTaggedLiteral`test`; 
// ["test"]

请注意,我们在调用函数时没有使用括号()!我们将模板字面量应用到括号的位置。作为函数的参数,我们得到字面量中字符串的数组。让我们扩展发送到函数的字符串,其中将包含一个表达式,我们还将在函数中包含一个新的参数。

function myTaggedLiteral(strings, value) {
    console.log(strings,value);
}

let someText = 'Neat';
myTaggedLiteral`test ${someText}`; 
// ["test", ""]
// "Neat"

当我们使用表达式时,我们可以从后续参数中访问该表达式,并且可以继续下去。假设我们添加了另一个表达式。

function myTaggedLiteral(strings, value, value2) {
    console.log(strings,value);
}

let someText = 'Neat';
myTaggedLiteral`test ${someText} ${2 + 3}`; 
// ["test", ""]
// "Neat"
// 5

这非常强大:它允许您获取字符串中使用的数据并根据需要进行操作。

可重复使用的模板

让我们看看模板字面量的一个简单用例。如果您还记得上面的内容,我们看到了模板字面量非常适合(好吧,非常适合)创建模板!让我们更进一步,创建一个函数,使我们能够创建可重复使用的模板。这里的想法是,我们可以创建初始模板,然后传入数据以供日后使用。

const student = {
    name: "Ryan Christiani",
    blogUrl: "http://ryanchristiani.com"
}

const studentTemplate = templater`<article>
    <h3>${'name'} is a student at HackerYou</h3>
    <p>You can find their work at ${'blogUrl'}.</p>

</article>`;

const myTemplate = studentTemplate(student);
console.log(myTemplate);
// Output will look like this!
// <article>
//    <h3>Ryan Christiani is a student at HackerYou</h3>
//    <p>You can find their work at http://ryanchristiani.com.</p>
// </article>

让我们看看如何实现我们的templater 函数。

const templater = function(strings, ...keys) {

}

您首先会注意到...keys 参数。... 语法被称为剩余参数;它将收集函数拥有的任何参数,并为我们创建一个数组。

接下来我们要做的是返回一个将访问我们对象的函数。返回函数是允许我们调用并传入学生数据的原因,例如:studentTemplate(student)

const templater = function(strings, ...keys) {
    return function(data) {

    } 
}

现在我们可以使用这些数据了,我们需要进行一些操作。过程如下。首先,我们需要创建strings 数组的副本。我们制作一个副本,以防我们以后想引用原始数组。然后,我们需要遍历keys 数组,并为其中的每一个,从与键匹配的对象中获取数据(请注意,在此示例中,我们在${} 中传入了一个字符串),并将其放置在我们需要的数组中。最后,我们需要将它们全部重新连接在一起作为字符串,并从函数中返回!

function templater(strings, ...keys) {
    return function(data) {
        let temp = strings.slice();
        keys.forEach((key, i) => {
            temp[i] = temp[i] + data[key];
        });
        return temp.join('');
    }
};

您会注意到,这不是一个详尽的例子。我们无法容纳嵌套数据或数组值;它仅仅是字符串。但我希望这个例子能帮助说明您可以用标记模板字面量开始做什么。


Cover of Let's Learn ES6

Ryan Christiani 是多伦多 HackerYou 的首席讲师兼开发主管,也是 Let’s Learn ES6 的作者,这是一本涵盖 JavaScript 最新语法的书籍。