Template Literals and First Class Citizens
String Interpolation with Template Literals
As we dig deeper into HTML-in-JavaScript, you'll notice that standard String concatenation gets to be a bit cumbersome. Instead of using the concatenation operator (+
), most String manipulation in modern JS is done with template literals and String interpolation. The idea is that we can inject variables or expressions directly into a template, rather than piecing together substrings manually. The template literal version of the exercise above would look like this:
const firstName = prompt("Hi there! What's your first name?")";
const lastName = prompt("What's your last name?")";
const output = document.querySelector("#greeting");
output.innerHTML = `<p>Thanks for visiting, ${firstName} ${lastName}.</p>`;
Notice how this syntax maintains the structure of our HTML more accurately. This is true of multi-line HTML chunks as well, since template strings take newlines into account! If we wanted to make our output
's innerHTML
' a bit more fancy, we could have re-written that last line like so:
output.innerHTML = `
<div>
<p>
Thanks for visiting,
<span class="some-class">
${firstName} ${lastName}
</span>
</p>
</div>
`;
Which is much nicer, don't you think? You can imagine how we might be able to turn all of our existing HTML into a set of fancier templates using this method. Try refactoring all of your concatenated Strings into interpolated template literals instead!
Fun With Functions
Review
We've already seen a variety of functions, from built-in functions like console.log()
, to a few of our own built using function functionName() {}
. We've also already learned how to invoke or execute functions with ()
, as well as passing in a few simple arguments (like we've done with prompt("some string")
).
function sayingGenerator() {
const phrase = "Heeey, it's the Fonz.";
return phrase;
}
// What is the return value?
const saying = sayingGenerator();
function valueLogger(value) {
console.log(value);
}
valueLogger("Howdy ho, neighborino!");
// parameters and variables defined in function invocations are local to that invocation
value; // ReferenceError: No variable 'value' exists
valueLogger(3 + 7);
// where's the seven?
valueLogger(3, 7);
function doubler(num) {
return num * 2;
}
// is it ten?
const shouldBeTen = doubler(5);
function doubleValueLogger(value1, value2) {
console.log(value1, value2);
}
doubleValueLogger("hello", "how are you");
// what is value2?
doubleValueLogger("hello");
function add(num1, num2) {
return num1 + num2;
}
const sum = add(7, 12);
a new syntax (part 1)
Up to this point, we've been writing functions like this:
const someFunction = function someFunction() {};
While there are some technical differences between the two ways of declaring functions, the latter is used much more widely than the former, and is generally a bit easier to read. As long as we treat the functional expression the same way we were treating it's const
-based cousin, we should be fine (and save ourselves a few keystrokes in the process).
the return
keyword
return
keywordHere's a function that return
s a value without any side effects, meaning that invoking the function
will have no affect anything outside of that function
's _scope. (nothing outside of the {
and }
).
function greeter() {
return "Hello";
}
// saving the return value
const greeting = greeter();
// using the return value to compose larger expressions
console.log(`${greeting}, nice to meet you.`);
// what's the difference here?
console.log(`${greeter()}, nice to meet you.`);
function tripler(num) {
return num * 3;
}
function multiply(num1, num2) {
return num1 * num2;
}
function divide(num1, num2) {
return num1 / num2;
}
function remainder(num1, num2) {
return num1 % num2;
}
// TODO: Using only the functions above, and no operators, calculate the value of tripling 5, multiplying that by 12, dividing by 2 and then finding the remainder of dividing that by 3.
Functions are First Class Citizens
Functions are ‘first-class citizens’ afforded all of the rights and privileges of other data types. This means that they can be assigned as variables (function declarations - like variable declarations):
const greeter = function() {
return 'hello world'`
}
More importantly, they can be passed into other functions as arguments!
function adder(1, 2) {
return 1 + 2;
}
/**
* `doMath` is a HIGHER ORDER FUNCTION.
* `operation` is passed in as an argument (as any other data type could be).
* Whichever function is passed in as `operation`,
* is INVOKED by 'doMath`
*/
function doMath(operation, num1, num2) {
return operation(num1, num2);
}
Last updated
Was this helpful?