{"id":9267,"date":"2022-10-23T18:48:00","date_gmt":"2022-10-23T17:48:00","guid":{"rendered":"https:\/\/stevepedwards.today\/DebianAdmin\/?p=9267"},"modified":"2022-10-23T21:09:44","modified_gmt":"2022-10-23T20:09:44","slug":"js-behind-the-scenes-hoisting-and-the-tdz-temporal-dead-zone","status":"publish","type":"post","link":"https:\/\/stevepedwards.today\/DebianAdmin\/js-behind-the-scenes-hoisting-and-the-tdz-temporal-dead-zone\/","title":{"rendered":"JS Behind The Scenes : Hoisting and the TDZ &#8211; Temporal Dead Zone"},"content":{"rendered":"<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_9267\" class=\"pvc_stats all  \" data-element-id=\"9267\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/stevepedwards.today\/DebianAdmin\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n<p>Hoisting by the JS Engine makes some variables available for use before they are declared by the JS engine creating a \"variable environment object\" as the code is initially scanned before being run.<\/p>\n<p>It is best to experiment with the various variable type to understand which get hoisted and which don't, as behaviour varies markedly.<\/p>\n<table width=\"100%\">\n<thead>\n<tr>\n<td style=\"text-align: center;\" width=\"161\"><\/td>\n<td style=\"text-align: center;\" width=\"241\"><span style=\"color: #0000ff;\">HOISTED?<\/span><\/td>\n<td style=\"text-align: center;\" width=\"154\"><span style=\"color: #0000ff;\">Initial Value<\/span><\/td>\n<td style=\"text-align: center;\" width=\"146\"><span style=\"color: #0000ff;\">scope<\/span><\/td>\n<\/tr>\n<\/thead>\n<\/table>\n<p>&nbsp;<\/p>\n<table width=\"100%\">\n<tbody>\n<tr>\n<td style=\"text-align: center;\" width=\"144\"><span style=\"color: #00ff00;\">Function declarations<\/span><\/td>\n<td style=\"text-align: center;\" width=\"202\"><span style=\"color: #00ff00;\">Yes<\/span><\/td>\n<td style=\"text-align: center;\" width=\"133\"><span style=\"color: #339966;\">Actual function<\/span><\/td>\n<td style=\"text-align: center;\" width=\"128\"><span style=\"color: #339966;\">block<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\" width=\"144\"><span style=\"color: #00ff00;\">var<\/span><\/td>\n<td style=\"text-align: center;\" width=\"202\"><span style=\"color: #00ff00;\">Yes<\/span><\/td>\n<td style=\"text-align: center;\" width=\"133\">undefined<\/td>\n<td style=\"text-align: center;\" width=\"128\"><span style=\"color: #339966;\">function<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\" width=\"144\">Let\/const<\/td>\n<td style=\"text-align: center;\" width=\"202\">Not in practice, technically Yes<\/td>\n<td style=\"text-align: center;\" width=\"133\"><span style=\"color: #ff0000;\">Uninitialized,<\/span><\/p>\n<p><span style=\"color: #ff0000;\">Temporal Dead Zone<\/span><\/td>\n<td style=\"text-align: center;\" width=\"128\"><span style=\"color: #ff0000;\">block<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\" width=\"144\"><span style=\"color: #ff0000;\">Func expressions\/Arrows<\/span><\/td>\n<td style=\"text-align: center;\" width=\"202\"><span style=\"color: #ff0000;\">Depends if var or let\/const used<\/span><\/td>\n<td style=\"text-align: center;\" width=\"133\"><\/td>\n<td style=\"text-align: center;\" width=\"128\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\/\/ Temporal Dead Zone, Let and Const: Function Declarations (function blah = {} etc) are hoisted \r\nconst myName = 'Jonas'\r\n\r\n\/\/ var \"job\" is defined but inaccesible - and VS code does not highlight ${} as a var either\r\nif (myName === 'Jonas') {\r\n  \/\/ -------------TDZ for job var-----------\r\n  console.log(`${job}`);\r\n  const job = \"teacher\"\r\n  \/\/ Uncaught ReferenceError: Cannot access 'job' before initialization - because of unhoisted variable const - if lines are reversed (Alt ^ arrow) then it works. Initially it is treated as not existing\r\n\r\n  \/\/ const age = 2037 - 1989\r\n  \/\/ console.log(age);\r\n  \/\/ 48\r\n  \/\/--------------TDZ for job var-----------\r\n  \r\n  \/\/ \r\n  \/\/-------------x is in TDZ until initialised _________\r\n  \/\/ console.log(x)\r\n  \/\/ Uncaught ReferenceError: x is not defined yet - it is in TDZ as uninitialized from JS initial code scan, so it is expected to be defined at some future point\r\n \/\/-------------x is in TDZ until initialised _________\r\n\r\n\r\n<\/pre>\n<div>\n<div>\n<p>So what is and why a TDZ? It was created in the JS Engine so that variables would not be accessible before they are declared to prevent bugs, bad programming practises and catch errors. So the JS engine in the browser F12 console flags an error and prevents continuation of the running code until fixed.<\/p>\n<p>It also makes const variables constant! They cannot be re-assigned later, else flag an error, unlike \"let\", partly.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\/\/ basic assignment behaviour:\r\nlet a = 1\r\na = 2\r\n\/\/ no prob so far...!\r\n<span style=\"color: #ff0000;\">\/\/ let a = 3<\/span>\r\n<span style=\"color: #ff0000;\">\/\/ Identifier 'a' has already been declared<\/span>\r\n\r\nconst b = 2\r\n<span style=\"color: #ff0000;\">\/\/ b = 3<\/span>\r\n<span style=\"color: #ff0000;\">\/\/ Uncaught TypeError: Assignment to constant variable.<\/span>\r\n\r\nvar c = 1\r\nc = 2\r\nvar c = 3\r\n\/\/ no probs at all!! var is a wildcard that allows re-assignment at any point so makes keeping track of a var difficult across all scopes, whether global, local, functional or block scopes. It should not be used, but will exist in older code.<\/pre>\n<p>&nbsp;<\/p>\n<p>Hoisting was created to make certain programming requirements possible even if it causes some confusion, a by product of which was the neccesity for var also being hoisted (and now still allowed to be defined as \"undefined\" instead of uninitialised, if not declared - a bad idea)\u00a0 in older versions of JS, which is why var should not be used any more, but let or const instead. The original JS design never intended or foresaw JS being used as it is now as such a powerful manipulator of CSS and HTML, due to Internet requirements.<\/p>\n<\/div>\n<div>So, how are variables hoisted or not if called before declaration?<\/div>\n<\/div>\n<div><\/div>\n<div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\"><span style=\"color: #00ff00;\">\/\/ console.log(me); \/\/ hoisted ok but undefined yet\r\n\/\/ undefined<\/span>\r\n<span style=\"color: #ff0000;\">\/\/ console.log(job); \/\/ in TDZ here\r\n\/\/ Uncaught ReferenceError: Cannot access 'job' before initialization<\/span>\r\n<span style=\"color: #0000ff;\">\/\/ console.log(year); \/\/ in TDZ here\r\n\/\/ Uncaught ReferenceError: Cannot access 'year' before initialization<\/span>\r\n\r\n\/\/ The let and const issues can be fixed by reversing their Top To Bottom order of being called\r\n\r\n<span style=\"color: #00ff00;\">\/\/\u00a0var\u00a0me\u00a0=\u00a0\"Fred\"<\/span>\r\n<span style=\"color: #ff0000;\">\/\/\u00a0let\u00a0job\u00a0=\u00a0\"teacher\"<\/span>\r\n<span style=\"color: #0000ff;\">\/\/\u00a0const\u00a0year\u00a0=\u00a01992<\/span><\/pre>\n<p>So how does <em>function<\/em> hoisting behave?<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\"><span style=\"color: #00ff00;\">\/\/ Hoisting functions - declaration, expression and arrow:\r\nconsole.log(addDecl(2,3));\r\n\/\/ 5\r\n<strong>\/\/ declaration hoisted ok<\/strong><\/span>\r\n\r\n<span style=\"color: #00ff00;\">function addDecl(a,b) {\r\n  return a + b \r\n}<\/span>\r\n\r\n<span style=\"color: #ff0000;\">\/\/ console.log(addExpr(2,3));\r\n\/\/ Uncaught ReferenceError: Cannot access 'addExpr' before initialization\r\n\r\nconst addExpr = function (a,b) {\r\n  return a +b \r\n}\r\nAs with the variables defined by const and let above before, const functions are in the TDZ until their Top To Bottom order has changed places <\/span>\r\n<span style=\"color: #0000ff;\">console.log(addArrow(2,3));\r\n\/\/ Uncaught ReferenceError: Cannot access 'addArrow' before initialization\r\n\r\nconst addArrow = (a,b) =&gt; a + b\r\n\r\n<span style=\"color: #ff0000;\"><span style=\"color: #0000ff;\">As with the variables defined by const and let above before, const functions are in the TDZ until their Top To Bottom order has changed places<\/span><\/span>\r\n<\/span><\/pre>\n<div>\n<div>The situation with var is different for 2 reasons - first, the expression alone IS hoisted but undefined, as the variable examples above.<\/div>\n<\/div>\n<div><\/div>\n<div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\"><span style=\"color: #00ff00;\">\/\/ console.log(addExpr);\r\n\/\/ undefined\r\n\r\n\/\/ but if arguments are given:\r\n\/\/ console.log(addExpr(1,2));\r\n\/\/ Uncaught TypeError: addExpr is not a function. This is because it is like using; \r\n\/\/ console.log(undefined(1,2));\r\n\/\/ Uncaught TypeError: undefined is not a function\r\n\r\nvar addExpr = function (a, b) {\r\n  return a + b;\r\n};<\/span>\r\n\r\n\/\/ Obviously, the same applies to an Arrow func\r\n<span style=\"color: #0000ff;\">console.log(addArrow(1,2));\r\n\/\/ Uncaught ReferenceError: Cannot access 'addArrow' before initialization\r\nlet addArrow = (a, b) =&gt; a + b;<\/span><\/pre>\n<p><strong>SUMMARY:<span style=\"color: #ff0000;\"> ONLY function Declarations are hoisted<\/span> by the JS Engine so work, no matter where - above or below each other - in the code the variable or declaration is placed.<\/strong><\/p>\n<\/div>\n<div>\n<div>\/\/ One last aspect of var is that it creates it's variables or functions as actual window objects, which may not be desireable:<\/div>\n<div><span style=\"color: #ff0000;\">var x \u00a0= 1<\/span><\/div>\n<div>console.log(x \u00a0=== window.x);<\/div>\n<div>\/\/ true<\/div>\n<div><span style=\"color: #ffffff;\">\/\/ Window {window: Window, self: Window, document: document, name: '', location: Location, \u2026}<\/span><\/div>\n<div><span style=\"color: #ff0000;\">\/\/ x: 1<\/span><\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_9267\" class=\"pvc_stats all  \" data-element-id=\"9267\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/stevepedwards.today\/DebianAdmin\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n<p>Hoisting by the JS Engine makes some variables available for use before they are declared by the JS engine creating a \"variable environment object\" as the code is initially scanned before being run. It is best to experiment with the various variable type to understand which get hoisted and which don't, as behaviour varies markedly. <a href=\"https:\/\/stevepedwards.today\/DebianAdmin\/js-behind-the-scenes-hoisting-and-the-tdz-temporal-dead-zone\/\" class=\"more-link\">...<span class=\"screen-reader-text\">\u00a0 JS Behind The Scenes : Hoisting and the TDZ &#8211; Temporal Dead Zone<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-9267","post","type-post","status-publish","format-standard","hentry","category-post"],"a3_pvc":{"activated":true,"total_views":4,"today_views":0},"_links":{"self":[{"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/posts\/9267","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/comments?post=9267"}],"version-history":[{"count":17,"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/posts\/9267\/revisions"}],"predecessor-version":[{"id":9284,"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/posts\/9267\/revisions\/9284"}],"wp:attachment":[{"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/media?parent=9267"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/categories?post=9267"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/tags?post=9267"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}