|
17 | 17 | - [Execution Stack](#execution-stack)
|
18 | 18 | - [Creation of Execution Stack](#creation-of-execution-stack)
|
19 | 19 | - [Lexical Environment](#lexical-environment)
|
20 | | - - [Hoisting](#hoisting) |
21 | | - - [Hoisting in var](#hoisting-in-var) |
22 | | - - [Hoisting with let/const](#hoisting-with-letconst) |
23 | | - - [Temproal Dead Zone](#temproal-dead-zone) |
24 | 20 |
|
25 | 21 | # JavaScript Engine
|
26 | 22 |
|
@@ -209,125 +205,3 @@ Each Lexical Environment has three component:
|
209 | 205 | - Environment Record
|
210 | 206 | - Reference to outer environment
|
211 | 207 | - _this_ binding
|
212 | | - |
213 | | -## Hoisting |
214 | | - |
215 | | -Hoisting is the default behavior of JavaScript where it defines all the declarations at the top of scope before code execution. JavaScript only hoists declarations, not initialization. |
216 | | - |
217 | | -JavaScript engine treats all variable declarations using _var_ as if they are declared at the top of global scope (if declared outside function) or at the top of functional scope (if declared inside function) regardless of where the actual declaration is made. This simply is **_Hoisting_**. |
218 | | - |
219 | | -### Hoisting in var |
220 | | - |
221 | | -```js |
222 | | -console.log(name); //OUTPUT: undefined |
223 | | - |
224 | | -var name = "Prabesh"; |
225 | | - |
226 | | -console.log(name); //OUTPUT: "Prabesh" |
227 | | -``` |
228 | | - |
229 | | -Normally, we would expect to get an error (ReferenceError) in the first _console.log_ since the variable name wasn't already declared before. But JavaScript hoists all variable declarations at the top. |
230 | | - |
231 | | -**Behind the Scene in interpreter** |
232 | | - |
233 | | -```js |
234 | | -//variable declaration gets hoisted at top |
235 | | -var name; |
236 | | - |
237 | | -console.log(name); //OUTPUT: undefined |
238 | | - |
239 | | -name = "Prabesh"; |
240 | | - |
241 | | -console.log(name); //OUTPUT: "Prabesh" |
242 | | -``` |
243 | | - |
244 | | -_In JavaScript, undeclared variable is assigned as type of undefined while ReferenceError is thrown when trying to access undeclared variable._ |
245 | | - |
246 | | -**Hoisting in Functional Scope** |
247 | | - |
248 | | -Variables declared within function are in the local scope. variables in the local scope are only accessible within the function in which they are defined. Hence, we can use variable with same name and use it in different function. |
249 | | - |
250 | | -If we declare local variable and a global variable with same name, the local variable will take precedence when we use it inside a function. In simple words, local variable shadows global variables. |
251 | | - |
252 | | -```js |
253 | | -function getName() { |
254 | | - console.log(name); |
255 | | - var name = "Prabesh"; |
256 | | -} |
257 | | - |
258 | | -getName(); |
259 | | - |
260 | | -//OUTPUT: undefined |
261 | | -``` |
262 | | - |
263 | | -**Behind the Scene in interpreter** |
264 | | - |
265 | | -```js |
266 | | -function getName() { |
267 | | - var name; |
268 | | - console.log(name); //OUTPUT: "Prabesh" |
269 | | - name = "Prabesh"; |
270 | | -} |
271 | | - |
272 | | -getName(); |
273 | | -``` |
274 | | - |
275 | | -To avoid such inconvinence, we need to declare and initialize the variable before we use it. |
276 | | - |
277 | | -**_Note to Remember: JavaScript declares the variable first in the background, then initialize them._** |
278 | | - |
279 | | -ALl of the undeclared variables are global varibles. |
280 | | - |
281 | | -```js |
282 | | -// Example of Hoisting |
283 | | -function hoisting() { |
284 | | - let name = "Prabesh"; |
285 | | - age = 23; |
286 | | -} |
287 | | -hoisting(); |
288 | | - |
289 | | -console.log(name); // Reference Error: name is not defined. |
290 | | -console.log(age); // Output: 23 |
291 | | -``` |
292 | | - |
293 | | -**So what exactly happened here?** |
294 | | - |
295 | | -In the above code, we have a function called hoisting() where we did not declare a variable using let/var/const and another variable declared with let. As mentioned above, _assigning the undeclared variable to the global scope is done by JavaScript_. Hence, age variable is availabe even outsode of scope(globally) but the scope of name variable is within the function, so we get the ReferenceError. |
296 | | - |
297 | | -### Hoisting with let/const |
298 | | - |
299 | | -In ES6, _let_ does not allow us to use undeclard variables and throws a ReferenceError. This makes sure that we always declare our variable first. |
300 | | - |
301 | | -**Example 1:** |
302 | | - |
303 | | -```js |
304 | | -console.log(num); |
305 | | -//OUTPUT: ReferenceError: Cannot access 'num' before initialization |
306 | | - |
307 | | -let num = 20; |
308 | | - |
309 | | -console.log(num); //OUTPUT: 20 |
310 | | -``` |
311 | | - |
312 | | -Let's have a look at another example: |
313 | | -**Example 2:** |
314 | | - |
315 | | -```js |
316 | | -console.log(number2); |
317 | | -//OUTPUT: ReferenceError: number2 is not defined. |
318 | | - |
319 | | -let number = 20; |
320 | | -``` |
321 | | - |
322 | | -**_Do you notice something different in example 1 and 2?_** |
323 | | - |
324 | | -The error in example 1 says: _ReferenceError: Cannot access 'num' before initialization_ but the error in example 2 is _ReferenceError: number2 is not defined_ |
325 | | - |
326 | | -The error "is not defined" means our JavaScript engine has no idea what _number2_ variable is because we never defined it. |
327 | | -But the error "cannot access before initialization" means our JS engine knows the "num" variable since "num" is hoisted to the top of global scope. |
328 | | - |
329 | | -_To summarize, variables declared with **let** or **const** are hoisted **without** a default initialization but the variables declared with **var** are hoisted **with** default initialization of undefined._ |
330 | | - |
331 | | -### Temproal Dead Zone |
332 | | - |
333 | | -This is a period during execution where _let/const_ variables are hoisted but not accessible. |
0 commit comments