Javascript ES6模板文本:如何在解释它们之前传递作用域?

Javascript ES6模板文本:如何在解释它们之前传递作用域?,javascript,node.js,ecmascript-6,Javascript,Node.js,Ecmascript 6,我开始使用模板文本来生成错误生成器 我有工作代码,但我不得不声明构造函数范围内可能出现的错误列表,对此我不满意 有没有一种方法可以复制一个模板文本而不计算它,这样我就可以在正确的范围内计算它?或者将作用域传递给模板文本 工作错误.js: 'use strict'; class Error { constructor(code) { const error = { //... //API 1001:

我开始使用模板文本来生成错误生成器

我有工作代码,但我不得不声明
构造函数
范围内可能出现的错误列表,对此我不满意

有没有一种方法可以复制一个模板文本而不计算它,这样我就可以在正确的范围内计算它?或者将作用域传递给模板文本

工作
错误.js

'use strict';

class Error {
    constructor(code) {
        const error = {
            //...
            //API
            1001: 'No token',
            1002: `${arguments[1]}`,
            1003: `${arguments[1]} ! ${arguments[2]}`,
            1004: 'Missing data'
            //...
        };
        let i = 0;
        this.code = code;
        this.error = error[code];
        //...
    }
}

// export default Error;
module.exports = Error;
被称为:

'use strict';
const Error = require('./error.js');

console.log(new Error(1002, 'var'));

我想要的是能够在模块范围内声明
const error
,或者更好的是,在我
需要的它自己的文件中声明
const error
。但是现在这样做会导致
参数
不是
构造函数的参数
,而是模块的参数。

字符串文本会立即计算。它们不能用作稍后格式化的模板(例如,Python的格式字符串看起来类似)

你可以按照Leonid Beschastny的建议做,并使用一些函数为你做插值

大概是这样的:

const error = {
    1001: () => 'No token',
    1002: (args) => `${args[1]}`,
    1003: (args) => `${args[1]} ! ${args[2]}`,
    1004: () => 'Missing data'
};
this.error = error[code](arguments);

模板文本没有更灵活,这真是太可惜了

这里有两种方法可能接近您想要的

第一: 概括如下:

var s = (<variable names you want>) => {return `<template with those variables>`}

我想要通过scope的首选解决方案是使用此包装器:

function defer([fisrt, ...rest]) {
  return (...values) => rest.reduce((acc, str, i) => acc + values[i] + str, fisrt);
}
就这些。当我想重用模板并推迟替换的解决方案时,我只需执行以下操作:

> t = defer`My template is: ${null} and ${null}`;
> t('simple', 'reusable');          // 'My template is: simple and reusable'
> t('obvious', 'late to the party'; // 'My template is: obvious and late to the party'
> t(null);                          // 'My template is: null and undefined'
>
> defer`Choose: ${'ignore'} / ${undefined}`(true, false); // 'Choose: true / false'
应用此标记将返回一个忽略传递给文本的任何参数的
'function'
(而不是
'string'
)。之后可以使用新参数调用它。如果某个参数没有相应的替换,它将变为
“未定义”


您可以在这些其他答案中找到更多信息。

您可以将模板字符串包装在一个工厂函数中。所有这些都需要记住,如果
参数[1]
是字符串,那么“1002:
${arguments[1]}
,”这些是模板文本,不是字符串文字。基本上是的副本,重点是模板文字应该用编译器函数包装或重新实现。在这一点上,这个模板语法并不比其他任何JS模板引擎更有吸引力。最好使用spread/rest语法。传递
参数
对象效率很低。@jaap3,据我所知,有一个实例没有立即计算它们:当它们在函数中时。看看我下面的答案。事实上,这是个好主意!当您有对象时,这比使用模板标记和关联/渲染阵列要好。。更一般地说,您可以简单地对任何给定对象进行
let template=(o)=>`${o.first}${o.last}`
等渲染
class Person
{

  constructor (first, last)
  {
    this.first = first;
    this.last = last;
  }

  sayName ()
  {
        return `Hi my name is ${this.first} ${this.last}`;
  }
}

var bob = new Person("Bob", "Jones")
console.log(bob.sayName()) // Hi my name is Bob Jones

console.log(new Person("Mary", "Smith").sayName()) // Hi my name is Mary Smith
function defer([fisrt, ...rest]) {
  return (...values) => rest.reduce((acc, str, i) => acc + values[i] + str, fisrt);
}
> t = defer`My template is: ${null} and ${null}`;
> t('simple', 'reusable');          // 'My template is: simple and reusable'
> t('obvious', 'late to the party'; // 'My template is: obvious and late to the party'
> t(null);                          // 'My template is: null and undefined'
>
> defer`Choose: ${'ignore'} / ${undefined}`(true, false); // 'Choose: true / false'