模板字符串 您所在的位置:网站首页 js单引号变双引号的方法有哪些 模板字符串

模板字符串

2024-07-09 15:23| 来源: 网络整理| 查看: 265

带标签的模板是模板字面量的一种更高级的形式,它允许你使用函数解析模板字面量。标签函数的第一个参数包含一个字符串数组,其余的参数与表达式相关。你可以用标签函数对这些参数执行任何操作,并返回被操作过的字符串(或者,也可返回完全不同的内容,见下面的示例)。用作标签的函数名没有限制。

jsconst person = "Mike"; const age = 28; function myTag(strings, personExp, ageExp) { const str0 = strings[0]; // "That " const str1 = strings[1]; // " is a " const str2 = strings[2]; // "." const ageStr = ageExp > 99 ? "centenarian" : "youngster"; // 我们甚至可以返回使用模板字面量构建的字符串 return `${str0}${personExp}${str1}${ageStr}${str2}`; } const output = myTag`That ${person} is a ${age}.`; console.log(output); // That Mike is a youngster.

标签不必是普通的标识符,你可以使用任何优先级大于 16 的表达式,包括属性访问、函数调用、new 表达式,甚至其他带标签的模板字面量。

jsconsole.log`Hello`; // [ 'Hello' ] console.log.bind(1, 2)`Hello`; // 2 [ 'Hello' ] new Function("console.log(arguments)")`Hello`; // [Arguments] { '0': [ 'Hello' ] } function recursive(strings, ...values) { console.log(strings, values); return recursive; } recursive`Hello``World`; // [ 'Hello' ] [] // [ 'World' ] []

虽然语法从技术上允许这么做,但不带标签的模板字面量是字符串,并且在链式调用时会抛出 TypeError。

jsconsole.log(`Hello``World`); // TypeError: "Hello" is not a function

唯一的例外是可选链,这将抛出语法错误。

jsconsole.log?.`Hello`; // SyntaxError: Invalid tagged template on optional chain console?.log`Hello`; // SyntaxError: Invalid tagged template on optional chain

请注意,这两个表达式仍然是可解析的。这意味着它们将不受自动分号补全的影响,其只会插入分号来修复无法解析的代码。

js// 仍是语法错误 const a = console?.log `Hello`

标签函数甚至不需要返回字符串!

jsfunction template(strings, ...keys) { return (...values) => { const dict = values[values.length - 1] || {}; const result = [strings[0]]; keys.forEach((key, i) => { const value = Number.isInteger(key) ? values[key] : dict[key]; result.push(value, strings[i + 1]); }); return result.join(""); }; } const t1Closure = template`${0}${1}${0}!`; // const t1Closure = template(["","","","!"],0,1,0); t1Closure("Y", "A"); // "YAY!" const t2Closure = template`${0} ${"foo"}!`; // const t2Closure = template([""," ","!"],0,"foo"); t2Closure("Hello", { foo: "World" }); // "Hello World!" const t3Closure = template`I'm ${"name"}. I'm almost ${"age"} years old.`; // const t3Closure = template(["I'm ", ". I'm almost ", " years old."], "name", "age"); t3Closure("foo", { name: "MDN", age: 30 }); // "I'm MDN. I'm almost 30 years old." t3Closure({ name: "MDN", age: 30 }); // "I'm MDN. I'm almost 30 years old."

标签函数接收到的第一个参数是一个字符串数组。对于任何模板字面量,其长度等于替换次数(${…} 出现次数)加一,因此总是非空的。对于任何特定的带标签的模板字面量表达式,无论对字面量求值多少次,都将始终使用完全相同的字面量数组调用标签函数。

jsconst callHistory = []; function tag(strings, ...values) { callHistory.push(strings); // Return a freshly made object return {}; } function evaluateLiteral() { return tag`Hello, ${"world"}!`; } console.log(evaluateLiteral() === evaluateLiteral()); // false; each time `tag` is called, it returns a new object console.log(callHistory[0] === callHistory[1]); // true; all evaluations of the same tagged literal would pass in the same strings array

这允许标签函数以其第一个参数作为标识来缓存结果。为了进一步确保数组值不变,第一个参数及其 raw 属性都会被冻结,因此你将无法改变它们。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有