Rinvia esecuzione per i template letterali ES6

Sto giocando con la nuova funzione ES6 Template Literals e la prima cosa che mi è venuta in mente è stata una String.format per Javascript, quindi ho implementato un prototipo:

 String.prototype.format = function() { var self = this; arguments.forEach(function(val,idx) { self["p"+idx] = val; }); return this.toString(); }; console.log(`Hello, ${p0}. This is a ${p1}`.format("world", "test")); 

ES6Fiddle

Tuttavia, il modello letterale viene valutato prima che venga passato al mio metodo prototipo. C’è un modo in cui posso scrivere il codice sopra per posticipare il risultato fino a dopo aver creato dynamicmente gli elementi?

Posso vedere tre modi per aggirare questo:

  • Utilizza stringhe di template come se fossero progettate per essere utilizzate, senza alcuna funzione di format :

     console.log(`Hello, ${"world"}. This is a ${"test"}`); // might make more sense with variables: var p0 = "world", p1 = "test"; console.log(`Hello, ${p0}. This is a ${p1}`); // or even function parameters for actual deferral of the evaluation: const welcome = (p0, p1) => `Hello, ${p0}. This is a ${p1}`; console.log(welcome("world", "test")); 
  • Non utilizzare una stringa modello, ma una stringa letterale semplice:

     String.prototype.format = function() { var args = arguments; return this.replace(/\$\{p(\d)\}/g, function(match, id) { return args[id]; }); }; console.log("Hello, ${p0}. This is a ${p1}".format("world", "test")); 
  • Utilizza un modello letterale con tag. Si noti che le sostituzioni saranno ancora valutate senza intercettazioni da parte del gestore, quindi non è ansible utilizzare identificatori come p0 senza avere una variabile denominata così. Questo comportamento può cambiare se viene accettata una diversa proposta di syntax del corpo di sostituzione (Aggiornamento: non lo era).

     function formatter(literals, ...substitutions) { return { format: function() { var out = []; for(var i=0, k=0; i < literals.length; i++) { out[k++] = literals[i]; out[k++] = arguments[substitutions[i]]; } out[k] = literals[i]; return out.join(""); } }; } console.log(formatter`Hello, ${0}. This is a ${1}`.format("world", "test")); // Notice the number literals: ^ ^ 

Ho postato una risposta a una domanda simile che fornisce due approcci in cui l’esecuzione del modello letterale è ritardata. Quando il modello letterale si trova in una funzione, il modello letterale viene valutato solo quando viene chiamata la funzione e viene valutato utilizzando l’ambito della funzione.

https://stackoverflow.com/a/49539260/188963