ES6 Template Literals: How to pass a scope before they are interpreted?

后端 未结 3 356
清酒与你
清酒与你 2021-01-01 04:36

I am starting to use template literals to make a error generator.

I have working code, but I am forced to declare the list of possible errors inside the constr

相关标签:
3条回答
  • 2021-01-01 04:47

    My preferred solution to pass scope is using this wrapper:

    function defer([fisrt, ...rest]) {
      return (...values) => rest.reduce((acc, str, i) => acc + values[i] + str, fisrt);
    }
    

    That's all. When I want to reuse a template and defer the resolution of the substitutions, I just do:

    > 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'
    

    Applying this tag returns back a 'function' (instead of a 'string') that ignores any parameters passed to the literal. Then it can be called with new parameters later. If a parameter has no corresponding replace, it becomes 'undefined'.

    You can find more information in those other answers: this and that.

    0 讨论(0)
  • 2021-01-01 05:04

    String literals are evaluated immediately. They cannot be used as templates to be formatted later (Unlike for example Python's format strings that look similar).

    You could do what Leonid Beschastny suggests and use little functions that does the interpolation for you.

    Something like this:

    const error = {
        1001: () => 'No token',
        1002: (args) => `${args[1]}`,
        1003: (args) => `${args[1]} ! ${args[2]}`,
        1004: () => 'Missing data'
    };
    this.error = error[code](arguments);
    
    0 讨论(0)
  • 2021-01-01 05:14

    It's a darn shame that template literals aren't more flexible.

    Here are two methods that may be close to what you want.

    First:

    var s = (item, price) => {return `item: ${item}, price: $${price}`}
    s('pants', 10) // 'item: pants, price: $10'
    s('shirts', 15) // 'item: shirts, price: $15'
    

    To generalify:

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

    If you are not running E6, you could also do:

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

    This seems to be a bit more concise than the previous answers.

    https://repl.it/@abalter/reusable-JS-template-literal

    Second

    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
    

    https://repl.it/@abalter/late-evaluation-of-js-template-literal

    0 讨论(0)
提交回复
热议问题