String.substitute
Le 12 août 2015 à 15:41, Edwin Reynoso <eorroe at gmail.com> a écrit :
Could we make the following possible, I can't seem to think of a way to do it, since template literals are evaluated with the current scope, also tried with
eval
but shouldn't even use that at all:
String.substitute( { year: 2015 }, `This year is ${year}` ); // Returns "This year is 2015"
Yes I'm aware I could do the following:
var obj = { year:2015 } `This year is ${obj.year}`
The point is to get rid of the part where I reference
obj
all the time.I could just use destructuring:
var { year } = { year: 2015 } `This year is ${year}`
So yes destructuring takes care of most of this just fine, but the point is to have a template literal evaluate as a pass reference and not right away.
You can't make your own function and pass in a template literal that's not evaluated when passed as a reference, I'm not sure if anyone will actually want this but me. Please let me know. Thanks
There is a general trick for deferring evaluation (of a template literal or of anything else): enclosing it in a function.
const myTemplate = ({ year }) => `This year is ${year}`
myTemplate({ year: 2015 })
Yes of course, still requires 1.Destructuring, and making a function for each type of string to return. Defeats the purpose.
I'd have to make different functions for each template:
const yearTemplate = ({ year }) => `This year is ${year}`;
const ageTemplate = ({ age}) => `I'm ${age} yrs old`;
Compare to:
let yearSentence = String.substitute({ year: 2015}, `This year is ${year}`);
let ageSentence = String.substitute({ age:100 }, `I'm ${age} yrs old`);
Am I being naive or could this just be written in user space?
Sent from my iPhone
function substitute(obj, str) {
return str.replace(/\${([^}]*)}/g, (m, p) => obj[p]);
}
substitute({ year: 2015 }, 'This is year ${year}'); // === 'This is year
2015'
With String.substitute()
you'd still be able to evaluate expressions,
it's kind of like changing scope, or passing an object to use for scoped
variables, which is not possible:
substitute({ year: 2015 }, 'Last year was year ${year-1}'); // Will throw
an error
You can't evaluate with your function
With String.substitute()
you would be able to:
String.substitute({ year: 2015}, `Last year was ${year-1}`);
You also miss New Lines which is another thing template literals
solved, so yes you could just add \n
but that's the point of why template
literals take care of that for you
Template literals evaluate to simple strings, there is no way to pass a reference to an un-evaluated template literal. The function method is the only way. Programmatically
String.substitute({ year: 2015}, `Last year was ${year-1}`);
is identical to
var str = `Last year was ${year-1}`
String.substitute({ year: 2015}, str);
How would it ever know that it was supposed to skip evaluating the template string first before calling the function?
On Wed, Aug 12, 2015 at 7:31 AM, Edwin Reynoso <eorroe at gmail.com> wrote:
Yes of course, still requires 1.Destructuring, and making a function for each type of string to return. Defeats the purpose.
I'd have to make different functions for each template:
const yearTemplate = ({ year }) => `This year is ${year}`; const ageTemplate = ({ age}) => `I'm ${age} yrs old`;
Compare to:
let yearSentence = String.substitute({ year: 2015}, `This year is ${year}`); let ageSentence = String.substitute({ age:100 }, `I'm ${age} yrs old`);
let yearSentence = ({year:2015}=>This year is ${year}
)();
should work, or
let yearSentence = (year=>This year is ${year}
)(2015);
You don't have to save the templates in variables. You can just call them immediately.
let yearSentence = ({year:2015}=>
This year is ${year}
)();
Enclosing the template string inside of a function is the way to go. Let's call this one done.
@logan that's an interesting thought, which is why I posted this for discussion, Thinking of that, I'm kind of doubting most will like the function to only be able to take the literal instead as a variable because that's just messing with the way Javascript itself.
Could be possible to pass a string with "" instead of ``
String.substitute({year: 2015}, "This year is ${year}");
Which is giving javascript a way to allow writing a Template Literal without evaluating by using "" instead of ``
@Tab atkin
Your still making a function yourself. You may ask what's wrong with that?
Well then I'd say what's the point of ES6
having "Hi".includes("H")
when we could of just did:
function includes(str, included) {
return str.indexOf(included) > -1;
}
Le 12 août 2015 à 15:41, Edwin Reynoso <eorroe at gmail.com> a écrit :
Could we make the following possible, I can't seem to think of a way to do it, since template literals are evaluated with the current scope, also tried with
eval
but shouldn't even use that at all:
String.substitute( { year: 2015 }, `This year is ${year}` ); // Returns "This year is 2015"
If you look closely, String.substitute
is just the with
statement resurrected:
with ({ year: 2015 }) {
`This year is ${year}`
}
At first glance, the with
statement looked like a great idea, but in fact, it makes static analysis difficult for both human and machines: In short: What do you expect from:
let shift = 1;
String.substitute( obj, `This year is ${year + shift}` );
when you don’t know a priori whether obj
has a year
property, and whether it has a shift
property?
Could be possible to pass a string with "" instead of ``
At that point, you are implementing a templating language that happens to
match up syntactically with template literals. You'd also then be moving
parsing of the template to runtime instead of compile time, which will slow
things down. It would also only be possible to implement using eval
.
You can certainly do that, but it doesn't seem like something that should be included in the language. It's no different from using Handlebars or Mustache at that point. The primary benefit of template literals is that they have access to variables in-scope, which seems to be what you are trying to avoid.
Yes I'm aware @claude that its kind of like the with
statement
@Logan instead it would allow a way for a developer to parse the template on call.
What's wrong with that?
And also will allow me to not use Handlebars or Mustache
I don't see anything wrong with having a method to do this and this discussion led me to know that this could allow a way to interact with the parser on call, which IMO could be useful.
Le 12 août 2015 à 17:35, Edwin Reynoso <eorroe at gmail.com> a écrit :
(...) and this discussion led me to know that this could allow a way to interact with the parser on call, which IMO could be useful.
JavaScript has already a built-in feature for interacting with the parser at runtime: It’s called eval
. (And note that, since placeholders in template literals can contain arbitrary code, you do need the full power of eval
.)
Could we make the following possible, I can't seem to think of a way to do it, since template literals are evaluated with the current scope, also tried with
eval
but shouldn't even use that at all:String.substitute( { year: 2015 }, `This year is ${year}` ); // Returns "This year is 2015"
Yes I'm aware I could do the following:
var obj = { year:2015 } `This year is ${obj.year}`
The point is to get rid of the part where I reference
obj
all the time.I could just use destructuring:
var { year } = { year: 2015 } `This year is ${year}`
So yes destructuring takes care of most of this just fine, but the point is to have a template literal evaluate as a pass reference and not right away.
You can't make your own function and pass in a template literal that's not evaluated when passed as a reference, I'm not sure if anyone will actually want this but me. Please let me know.