Asked  7 Months ago    Answers:  5   Viewed   26 times

I'm not sure how to explain this, but when I run

console.log`1`

In google chrome, I get output like

console.log`1`
VM12380:2 ["1", raw: Array[1]]

Why is the backtick calling the log function, and why is it making a index of raw: Array[1]?

Question brought up in the JS room by Catgocat, but no answers made sense besides something about templating strings that didn't really fit why this is happening.

 Answers

67

It is called Tagged Template in ES-6 more could be read about them Here, funny I found the link in the starred section of the very chat.

But the relevant part of the code is below (you can basically create a filtered sort).

function tag(strings, ...values) {
  assert(strings[0] === 'a');
  assert(strings[1] === 'b');
  assert(values[0] === 42);
  return 'whatever';
}
tag `a${ 42 }b`  // "whatever"

Basically, its merely tagging the "1" with console.log function, as it would do with any other function. The tagging functions accept parsed values of template strings and the values separately upon which further tasks can be performed.

Babel transpiles the above code to

var _taggedTemplateLiteralLoose = function (strings, raw) { strings.raw = raw; return strings; };

console.log(_taggedTemplateLiteralLoose(["1"], ["1"]));

As you can see it in the example above, after being transpiled by babel, the tagging function (console.log) is being passed the return value of the following es6->5 transpiled code.

_taggedTemplateLiteralLoose( ["1"], ["1"] );

The return value of this function is passed to console.log which will then print the array.

Tuesday, June 1, 2021
 
TheCarver
answered 7 Months ago
55

Yes. You can use reflection. Something like this:

Type thisType = this.GetType();
MethodInfo theMethod = thisType.GetMethod(TheCommandString);
theMethod.Invoke(this, userParameters);

With the above code, the method which is invoked must have access modifier public. If calling a non-public method, one needs to use the BindingFlags parameter, e.g. BindingFlags.NonPublic | BindingFlags.Instance:

Type thisType = this.GetType();
MethodInfo theMethod = thisType
    .GetMethod(TheCommandString, BindingFlags.NonPublic | BindingFlags.Instance);
theMethod.Invoke(this, userParameters);
Tuesday, June 1, 2021
 
Deyson
answered 7 Months ago
11

Is there a way to programmatically construct a Template literal?

No. "programmatically" and "literal" are antithetic (except you are in the realms of compilers).

Template strings should better have been named interpolated string literals or so. Please do not confuse them with templates. If you want to use dynamically created strings for templates, use a template engine of your choice.

Of course template literals might help with the implementation of such, and you might get away with something simple as

function assemble(literal, params) {
    return new Function(params, "return `"+literal+"`;"); // TODO: Proper escaping
//             ^^^^^^^^ working in real ES6 environments only, of course
}
var template = assemble("Hello, my name is ${name}", "name");
template("Chaim"); // Hello, my name is Chaim
Thursday, June 3, 2021
 
Magnanimity
answered 6 Months ago
59

This:

`The area of a circle of radius 4 is ${circle.area(4)}`

is an example of ES2015 template strings.

It interpolates whatever circle.area(4) represents directly into the string. If you're curious about this or other ES2015 features, I recommend checking out Babel and playing around in the REPL.

Here's a very simple example to get you started.

You can see this ES2015 code:

const foo = 'some text';
console.log(`${foo} is interpolated.`);

is transpiled to its ES5 equivalent - a simple + concatenation:

var foo = 'some text';
console.log(foo + ' is interpolated.');
Friday, June 11, 2021
 
Juicy
answered 6 Months ago
88

The scope of the function is the core issue here, as Zeychin and Trevor have said. I thought I'd offer another way of handling it. Basically, you can set your function to a variable that's in a higher scope (that is, accessible to both the onload and function_two functions), while defining it inside the onload function as you originally have:

var myFunction; //This is the placeholder which sets the scope

window.onload() = function() {
   myFunction = function() { //Assign the function to the myFunction variable
      print('blah');
   }
}

function function_two() {
   myFunction();
}

This might be handy if you only know the information you need for myFunction once you're in the onload event.

Thursday, July 29, 2021
 
joostvandriel
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share