Your example
var template=`I am a ${temp}`;
is an example of a template literal, called as such since the update of ES2015 / ES6 (They were called template strings but this has been updated, see the docs).
From MDN
Template literals are string literals allowing embedded expressions. You can use multi-line strings and string interpolation features with them. They were called "template strings" in prior editions of the ES2015 / ES6 specification.
Template literals are a function that take both the expressions inside the placeholders (such as in your example ${temp}
) and the string literals as arguments into a function that concatenates them into a single string.
The same scoping rules that apply to javascript in general usage applies here. In your case the compiler will first run through the code and scope the LHS references var temp
and var template
, but assignment will happen at run time.
As the second assignment of the variable temp
(here declared a second time using an anti-pattern var temp
) occurs after the template literal runs to concatenate the string, the var template
is assigned the string "I am a "
because it uses the RHS assignment of var temp
that is in scope at the time the template literal function runs i.e. var temp = ''
.
The docs for template literals can be found here.
Back to your (modified) code
This demonstrates the steps taken by the compiler both in the first pass and at run time, showing why the ES6 template literal is not updated and why.
First pass:
var temp='';
^^^^^^^^ compiler makes first pass LHS reference temp
var template=`I am a ${temp}`;
^^^^^^^^^^^^ compiler makes first pass LHS reference template
temp='developer';
^^^^ compiler recognises temp has already been allocated
Second pass:
var temp='';
^^^^^^^^^^^ compiler makes an RHS assignment to the variable temp
// => temp === ''
var template=`I am a ${temp}`;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compiler makes an RHS assignment to variable template
// => template === "I am a "
temp='developer';
^^^^^^^^^^^^^^^^ compiler makes an RHS assignment to variable temp
// => temp === "developer'