Javascript ES6标记模板的实用性
我理解ES6的语法。我没有看到的是实用性。什么时候比传递对象参数(如中的设置)更好Javascript ES6标记模板的实用性,javascript,ecmascript-6,template-strings,tagged-templates,Javascript,Ecmascript 6,Template Strings,Tagged Templates,我理解ES6的语法。我没有看到的是实用性。什么时候比传递对象参数(如中的设置)更好$.ajax('url',{/*这个家伙在这里*/}) 现在我只看到了复杂的语法,但我不明白为什么我需要/使用它。我还发现TypeScript团队选择在其他重要特性之前实现它(在1.5中)。标记字符串模板背后的概念是什么 见: 模板字符串规范的最后一个阶段是在字符串本身之前添加自定义函数,以创建带标记的模板字符串 例如,下面是一段代码,用于阻止尝试注入自定义DOM元素的字符串: var items = []; i
$.ajax('url',{/*这个家伙在这里*/})
现在我只看到了复杂的语法,但我不明白为什么我需要/使用它。我还发现TypeScript团队选择在其他重要特性之前实现它(在1.5中)。标记字符串模板背后的概念是什么 见:
模板字符串规范的最后一个阶段是在字符串本身之前添加自定义函数,以创建带标记的模板字符串
例如,下面是一段代码,用于阻止尝试注入自定义DOM元素的字符串:
var items = [];
items.push("banana");
items.push("tomato");
items.push("light saber");
var total = "Trying to hijack your site <BR>";
var myTagFunction = function (strings,...values) {
var output = "";
for (var index = 0; index < values.length; index++) {
var valueString = values[index].toString();
if (valueString.indexOf(">") !== -1) {
// Far more complex tests can be implemented here :)
return "String analyzed and refused!";
}
output += strings[index] + values[index];
}
output += strings[index]
return output;
}
result.innerHTML = myTagFunction `You have ${items.length} item(s) in your basket for a total of $${total}`;
var项目=[];
推送(“香蕉”);
项目。推(“西红柿”);
物品。推(“光剑”);
var total=“试图劫持您的网站
”;
var myTagFunction=函数(字符串,…值){
var输出=”;
对于(var index=0;index”)!=-1){
//更复杂的测试可以在这里实现:)
返回“字符串已分析并被拒绝!”;
}
输出+=字符串[索引]+值[索引];
}
输出+=字符串[索引]
返回输出;
}
result.innerHTML=myTagFunction`您的篮子中有${items.length}个项目,总共$${total}`;
标记的模板字符串可以用于很多事情,如安全性、本地化、创建自己的领域特定语言等
见:
模板字符串规范的最后一个阶段是在字符串本身之前添加自定义函数,以创建带标记的模板字符串
例如,下面是一段代码,用于阻止尝试注入自定义DOM元素的字符串:
var items = [];
items.push("banana");
items.push("tomato");
items.push("light saber");
var total = "Trying to hijack your site <BR>";
var myTagFunction = function (strings,...values) {
var output = "";
for (var index = 0; index < values.length; index++) {
var valueString = values[index].toString();
if (valueString.indexOf(">") !== -1) {
// Far more complex tests can be implemented here :)
return "String analyzed and refused!";
}
output += strings[index] + values[index];
}
output += strings[index]
return output;
}
result.innerHTML = myTagFunction `You have ${items.length} item(s) in your basket for a total of $${total}`;
var项目=[];
推送(“香蕉”);
项目。推(“西红柿”);
物品。推(“光剑”);
var total=“试图劫持您的网站
”;
var myTagFunction=函数(字符串,…值){
var输出=”;
对于(var index=0;index”)!=-1){
//更复杂的测试可以在这里实现:)
返回“字符串已分析并被拒绝!”;
}
输出+=字符串[索引]+值[索引];
}
输出+=字符串[索引]
返回输出;
}
result.innerHTML=myTagFunction`您的篮子中有${items.length}个项目,总共$${total}`;
标记的模板字符串可以用于很多事情,如安全性、本地化、创建自己的领域特定语言等
您可以使用标记模板来构建比常规函数调用更具表现力的API 例如,我正在为JS阵列上的SQL查询开发一个:
let admins = sql`SELECT name, id FROM ${users}
WHERE ${user => user.roles.indexOf('admin') >= 0}`
注意,它与字符串插值无关;它使用带标签的模板以提高可读性。很难用简单的函数调用构造出直观的东西-我想你会有这样的东西:
let admins = sql("SELECT name, id FROM $users WHERE $filter",
{ $users: users, $filter: (user) => user.roles.contains('admin') })
这个例子只是一个有趣的项目,但我认为它展示了标记模板的一些好处
另一个可能更明显的例子是i18n—标记模板可以插入输入的区域设置敏感版本。您可以使用标记模板构建比常规函数调用更具表现力的API 例如,我正在为JS阵列上的SQL查询开发一个:
let admins = sql`SELECT name, id FROM ${users}
WHERE ${user => user.roles.indexOf('admin') >= 0}`
注意,它与字符串插值无关;它使用带标签的模板以提高可读性。很难用简单的函数调用构造出直观的东西-我想你会有这样的东西:
let admins = sql("SELECT name, id FROM $users WHERE $filter",
{ $users: users, $filter: (user) => user.roles.contains('admin') })
这个例子只是一个有趣的项目,但我认为它展示了标记模板的一些好处
另一个可能更明显的例子是i18n-带标签的模板可以插入对区域设置敏感的输入版本。它们很有用,因为函数可以(几乎)完全定义其中文本的含义(几乎=除占位符外)。我喜欢用史蒂文·莱维坦的例子。使用定义为字符串的正则表达式很尴尬,因为必须进行双重转义:一次用于字符串文本,一次用于正则表达式。这是我们在JavaScript中使用正则表达式文本的原因之一 例如,假设我在一个站点上进行维护,我发现:
var isSingleUnicodeWord = /^\w+$/;
…这意味着检查字符串是否只包含“字母”。有两个问题:a)人类语言中有数千个“单词”字符,\w
无法识别,因为其定义以英语为中心;B)它包括。
,许多人(包括Unicode联盟)认为这不是一个“字母”
假设在我的工作中,我将XRegExp
引入了代码库。因为我知道它支持\pL
(\p
用于Unicode类别,而L
用于“字母”),我可能会很快将其替换为:
var isSingleUnicodeWord = XRegExp("^\pL+$"); // WRONG
然后我想知道为什么它不起作用,*facepalm*,返回并退出反斜杠,因为它被字符串文字消耗:
var isSingleUnicodeWord = XRegExp("^\\pL+$");
// ---------------------------------^
多痛苦啊。假设我可以编写实际的正则表达式而不必担心双重转义
我可以:使用标记模板函数。我可以把它放在我的标准库中:
function xrex(strings, ...values) {
const raw = strings.raw;
let result = "";
for (let i = 0; i < raw.length; ++i) {
result += raw[i];
if (i < values.length) { // `values` always has one fewer entry
result += values[i];
}
}
return XRegExp(result);
}
然后我可以高兴地写:
const isSingleUnicodeWord = xrex`^\pL+$`;
例如:
//我的标记函数(定义一次,然后重新使用)
函数xrex({raw},…值){
const result=raw.reduce(
(acc,str,index)=>acc+str+(index