<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Saumya Agrawal</title>
    <description>The latest articles on Forem by Saumya Agrawal (@idreamfyrei).</description>
    <link>https://forem.com/idreamfyrei</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1374089%2F0c5500eb-f4bb-47e4-88c7-94a78b87ddfc.png</url>
      <title>Forem: Saumya Agrawal</title>
      <link>https://forem.com/idreamfyrei</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/idreamfyrei"/>
    <language>en</language>
    <item>
      <title>The "Everything is a File" Tour of Linux</title>
      <dc:creator>Saumya Agrawal</dc:creator>
      <pubDate>Wed, 22 Apr 2026 13:48:08 +0000</pubDate>
      <link>https://forem.com/idreamfyrei/the-everything-is-a-file-tour-of-linux-5a8l</link>
      <guid>https://forem.com/idreamfyrei/the-everything-is-a-file-tour-of-linux-5a8l</guid>
      <description>&lt;p&gt;I wanted to overcome my command line phobia and join the 4% club of human bots who don't panic when they see the terminal, typing away in their plain terminal. I wanted to feel like a hacker. Not the movie kind with three keyboards and cascading green text, but the kind who actually understands what their computer is doing. So I googled "How to learn Linux" and landed on the most mundane, beige documentation website I have ever seen in my life. I dropped into forums next, expecting a more human approach. The first post I found had someone saying "just build your own kernel." I just wanted to learn things, not go on a spiritual journey.&lt;/p&gt;

&lt;p&gt;People told me Linux had a learning curve. Except this curve was a cliff.&lt;/p&gt;




&lt;p&gt;If you want a 12-minute brush through Linux basics before diving into the weird stuff, &lt;a href="https://www.youtube.com/watch?v=LKCVKw9CzFo" rel="noopener noreferrer"&gt;Fireship made a video for exactly that&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before we go into a rabbit hole, I will suggest to try all of this on a VPS, a VM, or a Docker container. Not your main machine. The reason is simple: some of what I will show you involves deliberately breaking things. Try to understand the command before copying, because imagine copying &lt;code&gt;rm -rf /&lt;/code&gt;. But if you are HIM, nobody is stopping you. On a throwaway container? You type &lt;code&gt;exit&lt;/code&gt;, spin up a fresh one, and try again. Freedom to destroy without consequences is genuinely how you learn Linux fastest.&lt;/p&gt;




&lt;h2&gt;
  
  
  Two tools that will save you more than any tutorial
&lt;/h2&gt;

&lt;p&gt;Before anything else: &lt;code&gt;man&lt;/code&gt; and &lt;code&gt;tldr&lt;/code&gt;. These are your cheat codes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;man&lt;/code&gt; is the built-in Linux manual. Every command, every system file, every config format has one. When you wonder what a flag does or what a file is for, &lt;code&gt;man&lt;/code&gt; has the answer written by the people who built the thing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;man &lt;span class="nb"&gt;ls
&lt;/span&gt;man &lt;span class="nb"&gt;chmod
&lt;/span&gt;man 5 passwd      &lt;span class="c"&gt;# the 5 means file format manual, not the command&lt;/span&gt;
man resolv.conf   &lt;span class="c"&gt;# the config file itself has a man page&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem with &lt;code&gt;man&lt;/code&gt; is density. It was written by engineers for engineers. Enter &lt;code&gt;tldr&lt;/code&gt;, a community-written alternative that gives you just the practical common cases.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;tldr
tldr &lt;span class="nb"&gt;ls
&lt;/span&gt;tldr &lt;span class="nb"&gt;chmod&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;tldr&lt;/code&gt; gives you five useful examples instead of fifty pages of specification. Use &lt;code&gt;tldr&lt;/code&gt; when you want to quickly understand what something does. Use &lt;code&gt;man&lt;/code&gt; when you need the full picture. If &lt;code&gt;man&lt;/code&gt; is the textbook, &lt;code&gt;tldr&lt;/code&gt; is the cheat sheet your classmate scribbled the night before the exam.&lt;/p&gt;

&lt;p&gt;One more habit worth building early: when something fails, read the actual error message before googling. "Permission denied" means permissions. "No such file or directory" means the path is wrong or the file doesn't exist. "Command not found" means it is not installed or not in your PATH. Linux error messages are not trying to confuse you. They are telling you what happened.&lt;/p&gt;




&lt;h2&gt;
  
  
  What even is &lt;code&gt;/etc&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;/etc&lt;/code&gt; is where Linux keeps its brain. Configuration for almost everything the system does lives here in plain text files you can open with any editor. I spent the first hour just running &lt;code&gt;ls /etc&lt;/code&gt; and opening random files, and breaking things up. That felt like finding an unlocked door in a building I thought was sealed.&lt;/p&gt;

&lt;h3&gt;
  
  
  DNS redirection or how I broke Google with one line
&lt;/h3&gt;

&lt;p&gt;The one thing I tried in &lt;code&gt;/etc&lt;/code&gt; was &lt;code&gt;/etc/hosts&lt;/code&gt;. I wanted to reach my local dev server by a name instead of &lt;code&gt;127.0.0.1:3000&lt;/code&gt;. Opening the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /etc/hosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;127.0.0.1   localhost
::1         localhost ip6-localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I added one line at the bottom and saved:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;127.0.0.1   myapp.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It worked immediately. No restart, no daemon reload. The file is read fresh on every single lookup because this check happens before Linux even thinks about asking a DNS server anything.&lt;/p&gt;

&lt;p&gt;Then I had an idea. What if I pointed &lt;code&gt;instagram.com&lt;/code&gt; at localhost?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /etc/hosts
&lt;span class="c"&gt;# add: 127.0.0.1   instagram.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ping instagram.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;PING instagram.com &lt;span class="o"&gt;(&lt;/span&gt;127.0.0.1&lt;span class="o"&gt;)&lt;/span&gt; 56 bytes of data.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is poor man's parental control. All of Meta's infrastructure, the entire DNS system, bypassed by one line in a text file on your machine. The whole internet is the fallback. This file runs first.&lt;/p&gt;

&lt;p&gt;Imagine making your friend slowly lose their mind on a shared Linux machine, redirect their most visited sites to &lt;code&gt;127.0.0.1&lt;/code&gt; in &lt;code&gt;/etc/hosts&lt;/code&gt;. They will restart their wifi three times, blame their ISP, factory reset their router, and spend an hour in a chat with customer support before anyone thinks to check a text file.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;/etc/resolv.conf&lt;/code&gt;: the file that keeps rewriting itself
&lt;/h2&gt;

&lt;p&gt;Once I understood &lt;code&gt;/etc/hosts&lt;/code&gt;, I wanted to know what happened when a hostname was not found there. That fallback is &lt;code&gt;/etc/resolv.conf&lt;/code&gt;, which holds the actual DNS server address the system asks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/resolv.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# This file is managed by man:systemd-resolved(8). Do not edit.&lt;/span&gt;
nameserver 127.0.0.53
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I had edited this on my machine and my changes kept vanishing. Now I understood why. &lt;code&gt;systemd-resolved&lt;/code&gt; is a local DNS middleman running at &lt;code&gt;127.0.0.53&lt;/code&gt;. It manages this file and rewrites it whenever it restarts.&lt;/p&gt;

&lt;p&gt;Let's break the internet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"nameserver 0.0.0.0"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/resolv.conf
ping google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ping: google.com: Temporary failure &lt;span class="k"&gt;in &lt;/span&gt;name resolution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The machine is still connected to the network. It just cannot resolve any names because it is asking a DNS server that does not exist. &lt;code&gt;apt update&lt;/code&gt; fails, &lt;code&gt;curl&lt;/code&gt; fails, package installs fail. The network is fine, only name resolution is dead. This is what a misconfigured DNS server looks like from the inside.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fix it immediately&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"nameserver 8.8.8.8"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/resolv.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The permanent fix without the file fighting back is editing &lt;code&gt;systemd-resolved&lt;/code&gt;'s own config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /etc/systemd/resolved.conf
&lt;span class="c"&gt;# under [Resolve]:&lt;/span&gt;
&lt;span class="c"&gt;# DNS=1.1.1.1&lt;/span&gt;
&lt;span class="c"&gt;# FallbackDNS=8.8.8.8&lt;/span&gt;
systemctl restart systemd-resolved
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;code&gt;/etc/passwd&lt;/code&gt; and &lt;code&gt;/etc/shadow&lt;/code&gt;: the user accounts are just a text file
&lt;/h2&gt;

&lt;p&gt;I heard that everything in Linux is treated as a file, from hardware device to system configurations, just a file. This in itself was surprising to me, till I started exploring it through &lt;code&gt;/etc/passwd&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
saumya:x:1001:1001::/home/saumya:/bin/bash

&lt;span class="c"&gt;# the above is in the form of name:password:UID:GID:GECOS:directory:shell (root:x:0:0:root:/root:/bin/bash)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seven colon-separated fields per line: username, password placeholder, user ID, group ID, comment, home directory, login shell. The &lt;code&gt;x&lt;/code&gt; in the second field means the actual password hash is stored in &lt;code&gt;/etc/shadow&lt;/code&gt;, which only root can read.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cat&lt;/span&gt; /etc/shadow | &lt;span class="nb"&gt;grep &lt;/span&gt;saumya
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;saumya:&lt;span class="nv"&gt;$6$rounds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4096&lt;span class="nv"&gt;$saltstring$hashedpassword&lt;/span&gt;:19820:0:99999:7:::

&lt;span class="c"&gt;# 9 fields separated by ':'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The 9 fields are username, encrypted password, last change, minimum age, maximum age, warning, activity, expiration and reserved.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$6$&lt;/code&gt; means SHA-512. The &lt;code&gt;rounds=4096&lt;/code&gt; deliberately makes hashing slow. Slow hashing means brute-force attacks take longer. Your password is protected partly by intentional computational expense.&lt;/p&gt;

&lt;p&gt;Now the interesting part. Every account with &lt;code&gt;/usr/sbin/nologin&lt;/code&gt; as its login shell cannot open an interactive session. Try to SSH in as &lt;code&gt;www-data&lt;/code&gt; and the connection closes immediately. No password prompt, no shell, nothing. These accounts exist only so the processes running as them have a numeric user identity for permissions. They are not meant for humans to log into.&lt;/p&gt;

&lt;p&gt;Now, i wanted to try breaking it and hence, changed my login shell to &lt;code&gt;/bin/false&lt;/code&gt; in &lt;code&gt;/etc/passwd&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /etc/passwd

&lt;span class="c"&gt;# find your line, change /bin/bash to /bin/false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When i tried to connect in a new terminal, the session closes the instant the shell starts because &lt;code&gt;/bin/false&lt;/code&gt; exits immediately with a failure code. My account exists, password is correct, the SSH connection succeeds, but I am immediately disconnected. I have locked yourself out without deleting the account or changing the password.&lt;/p&gt;

&lt;p&gt;I fixed the current session by changing &lt;code&gt;/bin/false&lt;/code&gt; back to &lt;code&gt;/bin/bash&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;: watching bots try your front door
&lt;/h2&gt;

&lt;p&gt;On any internet-facing VPS, run this after it has been up for a day:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Failed password"&lt;/span&gt; /var/log/auth.log | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On a fresh VPS after few hours, that number is usually in the thousands. Automated bots scan every IP address on the internet looking for open port 22 and trying common username and password combinations. &lt;code&gt;root&lt;/code&gt;, &lt;code&gt;admin&lt;/code&gt;, &lt;code&gt;ubuntu&lt;/code&gt;, &lt;code&gt;123456&lt;/code&gt;. Constantly, from everywhere.&lt;/p&gt;

&lt;p&gt;All SSH behavior is controlled by &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would see a file with multiple lines with Port info, permits and authentications. Two lines that matter immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;PasswordAuthentication no
PermitRootLogin no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setting &lt;code&gt;PasswordAuthentication no&lt;/code&gt; means SSH only accepts key-based authentication. The bots still knock but there is nothing to brute-force. No password means no attack surface. &lt;code&gt;PermitRootLogin no&lt;/code&gt; means even with valid root credentials, nobody SSHs directly into root.&lt;/p&gt;

&lt;p&gt;Want to watch the bots in real time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/auth.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run that for five minutes on a fresh VPS. The attempts come in constantly from IP addresses across dozens of countries. It is mildly unsettling and also clarifying. This is just what the internet is like all the time.&lt;/p&gt;

&lt;p&gt;After disabling passwords:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl restart sshd
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Failed password"&lt;/span&gt; /var/log/auth.log | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;
&lt;span class="c"&gt;# bots still try, still fail, but now they fail faster&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whenever the bots try a password, the server tells them 'NO', not even letting them trying the password to authenticate.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;/etc/fstab&lt;/code&gt;: the file that can stop your machine from booting
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;/etc/fstab&lt;/code&gt; is read at boot. Linux mounts everything listed here. USB drives, additional partitions, network shares. Get an entry wrong and the machine may not boot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/fstab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# in the order&lt;/span&gt;
&lt;span class="c"&gt;# file system, mount point, type, options, dump and pass&lt;/span&gt;


&lt;span class="nv"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;abc123   /        ext4    defaults    0 1
&lt;span class="nv"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;def456   /boot    ext4    defaults    0 2
tmpfs         /tmp     tmpfs   defaults    0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;UUID is used instead of the device name because the name might change but the UUID won't. This acts as the Aadhar Number of the device.&lt;/p&gt;

&lt;p&gt;The experiment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /etc/fstab
&lt;span class="c"&gt;# add at the bottom:&lt;/span&gt;
broken-entry-here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;'broken-entry-here' is a string of text without the columns. When the mount command encounters it, it has no idea what the device is, and where it should be mounted.&lt;/p&gt;

&lt;p&gt;Now test without rebooting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mount &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command is essentially the dry run of the boot process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mount: /: can&lt;span class="s1"&gt;'t find broken-entry-here.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Error. Exactly what you would get on boot if you saved this and restarted. Fix it by removing or commenting out the broken line, then run &lt;code&gt;mount -a&lt;/code&gt; again to confirm it passes.&lt;/p&gt;

&lt;p&gt;The rule: always test with &lt;code&gt;mount -a&lt;/code&gt; before rebooting when you touch &lt;code&gt;/etc/fstab&lt;/code&gt;. Always. A bad fstab entry drops you into recovery mode or an emergency shell with no obvious explanation. Keep a mental note that this file exists and kills boots if you get it wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;/proc&lt;/code&gt;: the folder that is not actually on disk
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;/proc&lt;/code&gt; is a virtual filesystem. There are no files here stored on disk anywhere. When you read something from &lt;code&gt;/proc&lt;/code&gt;, the kernel generates the content on the spot from its own live internal data. It is a window into running system state, not stored data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/meminfo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it twice, ten seconds apart. The numbers change. Because it is live.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/cpuinfo | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"flags"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The flags like vmx, aes and sse which details the CPU capability the processor supports. &lt;code&gt;vmx&lt;/code&gt; means hardware virtualization is available. If you try to run KVM and it refuses, check for this flag. &lt;code&gt;aes&lt;/code&gt; means the CPU has built-in AES hardware acceleration. Disk encryption and TLS are genuinely faster because of this single flag. sse/avx means CPU has Streaming SIMD Extensions which can boost performance for heavy computations, and video encoding.&lt;/p&gt;

&lt;p&gt;The per-process data is where things get interesting. Every running process gets its own directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find something running&lt;/span&gt;
ps aux | &lt;span class="nb"&gt;grep &lt;/span&gt;nginx
&lt;span class="c"&gt;# Say it's PID 1234&lt;/span&gt;

&lt;span class="nb"&gt;ls&lt;/span&gt; /proc/1234/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cmdline  cwd  environ  exe  fd  maps  mem  net  status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;fd/&lt;/code&gt; lists every file descriptor the process has open right now. Log files, sockets, pipes, all of it as symlinks. &lt;code&gt;environ&lt;/code&gt; has the exact environment variables the process launched with. &lt;code&gt;cmdline&lt;/code&gt; shows the full command that started it. &lt;code&gt;status&lt;/code&gt; has memory use, current state, which user it runs as.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/1234/cmdline | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'\0'&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /proc/1234/fd/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The kernel stores command arguments separated by null bytes (&lt;code&gt;\0&lt;/code&gt;) to avoid confusion with spaces inside arguments. &lt;code&gt;tr&lt;/code&gt; swaps those null spaces to make it readable.&lt;/p&gt;

&lt;p&gt;When you delete a file while a process holds it open, the data stays on disk. The file is gone from &lt;code&gt;ls&lt;/code&gt; but the space is allocated until the process releases its file descriptor. In Linux, file is a link to a block of data, you are only removing the name. If the process has file descriptor open, data block will be kept alive. By redirecting to the FD in &lt;code&gt;/proc&lt;/code&gt;, you're telling the kernel to wipe the actual data blocks while leaving the 'ghost' handle intact.&lt;br&gt;&lt;br&gt;
Find these with &lt;code&gt;lsof | grep deleted&lt;/code&gt;. Fix without restarting the process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /proc/1234/fd/4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That truncates the held-open file to zero bytes through the process's own descriptor. Disk space reclaimed, process uninterrupted.&lt;/p&gt;




&lt;h2&gt;
  
  
  Routing: where packets actually go
&lt;/h2&gt;

&lt;p&gt;The routing table is what your machine consults before sending any packet. It decides which network interface and which gateway to use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ip route show
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;default via 192.168.1.1 dev eth0 proto dhcp src 192.168.1.100 metric 100
&lt;span class="c"&gt;# local lane&lt;/span&gt;
192.168.1.0/24 dev eth0 proto kernel scope &lt;span class="nb"&gt;link &lt;/span&gt;src 192.168.1.100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;default&lt;/code&gt; line handles everything. It says "for any destination I don't have a specific rule for, send it to 192.168.1.1." That is your router. Every internet-bound packet passes through that rule.&lt;/p&gt;

&lt;p&gt;Delete it and watch what happens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ip route del default
ping google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;connect: Network is unreachable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The machine is still on the network. It just cannot reach anything outside the local subnet because there is no default route. This is one of the first things to check when a server cannot reach the internet. The default route may simply not exist, perhaps because a VPN misconfigured it, or because someone ran &lt;code&gt;ip route flush&lt;/code&gt; without knowing what it did.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ip route add default via 192.168.1.1   
&lt;span class="c"&gt;# put it back&lt;/span&gt;

&lt;span class="c"&gt;# Most useful debugging command for routing&lt;/span&gt;
ip route get 8.8.8.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;8.8.8.8 via 192.168.1.1 dev eth0 src 192.168.1.100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One line is the complete answer about which interface and gateway any packet would use to reach any destination.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;/dev&lt;/code&gt;: the devices that are not devices
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;/dev/null&lt;/code&gt;, &lt;code&gt;/dev/zero&lt;/code&gt;, &lt;code&gt;/dev/random&lt;/code&gt; all live in the same directory as actual hardware. They have the same character device type marker. None of them are physical hardware.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/dev/null&lt;/code&gt; is a black hole. Write anything to it, and it is gone silently. Read from it, you get immediate end-of-file. This is what &lt;code&gt;command &amp;gt; /dev/null 2&amp;gt;&amp;amp;1&lt;/code&gt; does: stdout goes to the black hole, &lt;code&gt;2&amp;gt;&amp;amp;1&lt;/code&gt; sends stderr to wherever stdout is going (also the black hole).&lt;br&gt;&lt;br&gt;
The numbers represent 'streams.' &lt;code&gt;1&lt;/code&gt; is standard output (normal text), and &lt;code&gt;2&lt;/code&gt; is standard error. &lt;code&gt;2&amp;gt;&amp;amp;1&lt;/code&gt; means, take all the errors and send them into the same pipe where the normal text is going. Since that pipe leads to &lt;code&gt;/dev/null&lt;/code&gt;, the command becomes perfectly silent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Silence all output but still check if it worked&lt;/span&gt;
some_noisy_command &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null 2&amp;gt;&amp;amp;1
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt;     &lt;span class="c"&gt;# 0 means success, anything else means it failed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;/dev/zero&lt;/code&gt; produces infinite zero bytes. Good for filling disks or creating blank test files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fallocate &lt;span class="nt"&gt;-l&lt;/span&gt; 500M bigfile   &lt;span class="c"&gt;# faster for large files&lt;/span&gt;
&lt;span class="c"&gt;# or the /dev/zero version:&lt;/span&gt;
&lt;span class="nb"&gt;dd &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/zero &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bigfile &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1M &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;500

&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt;    &lt;span class="c"&gt;# watch disk fill up&lt;/span&gt;
&lt;span class="nb"&gt;rm &lt;/span&gt;bigfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;fallocate&lt;/code&gt; is instant because it just tells the filesystem to reserve the space without actually writing anything to the disk. &lt;code&gt;dd if=/dev/zero&lt;/code&gt; forces the CPU to actually churn out millions of zeros and write them one by one.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/dev/urandom&lt;/code&gt; produces cryptographically random bytes collected from hardware entropy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /dev/urandom | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-dc&lt;/span&gt; &lt;span class="s1"&gt;'a-zA-Z0-9'&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; 24
&lt;span class="nb"&gt;echo&lt;/span&gt;
&lt;span class="c"&gt;# or the cleaner version:&lt;/span&gt;
openssl rand &lt;span class="nt"&gt;-base64&lt;/span&gt; 18
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The thing that made this concrete for me: the same &lt;code&gt;read()&lt;/code&gt; system call your code uses to open a text file reads random bytes from &lt;code&gt;/dev/urandom&lt;/code&gt;. Same interface but completely different behavior underneath. That is the "everything is a file" idea became real.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;/boot&lt;/code&gt;: where the kernel lives
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /boot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vmlinuz-5.15.0-91-generic
initrd.img-5.15.0-91-generic
grub/
config-5.15.0-91-generic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;vmlinuz&lt;/code&gt; is the compressed Linux kernel (vm = virtual machine, z- compressed like .zip). The actual operating system, stored as a file. &lt;code&gt;initrd.img&lt;/code&gt; is a temporary RAM filesystem that acts as a bridge, which loads before the real filesystem mounts at boot. &lt;code&gt;grub/&lt;/code&gt; has the bootloader that lets you choose between operating systems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /boot/config-&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;CONFIG_EXT4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;CONFIG_EXT4_FS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That file is the kernel build configuration. Every driver, every feature, listed. Most of it is cryptic without context but searching it teaches you what the kernel actually supports.&lt;/p&gt;

&lt;p&gt;The only advice here: do not delete anything from &lt;code&gt;/boot&lt;/code&gt;. Deleting &lt;code&gt;vmlinuz&lt;/code&gt; means the computer cannot boot at all. Recovery requires a live USB. This is the one folder in the filesystem where curiosity should not turn into experiments.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Consider &lt;code&gt;/etc&lt;/code&gt; is the brain and &lt;code&gt;/proc&lt;/code&gt; is the nervous system, &lt;code&gt;/boot&lt;/code&gt; is the &lt;strong&gt;heart&lt;/strong&gt; of Linux.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;/var/log&lt;/code&gt;: the system's diary
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;/var/log&lt;/code&gt; is where the machine writes what happened. Everything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /var/log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;auth.log    syslog    kern.log    dpkg.log
nginx/      apt/      journal/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;auth.log&lt;/code&gt; records every login, failed or successful. &lt;code&gt;syslog&lt;/code&gt; is the general system log. &lt;code&gt;kern.log&lt;/code&gt; has kernel messages. &lt;code&gt;dpkg.log&lt;/code&gt; records every package installed or removed and when.&lt;/p&gt;

&lt;p&gt;Some logs are plain text files you can &lt;code&gt;cat&lt;/code&gt; like &lt;code&gt;syslog&lt;/code&gt;, while others live in the &lt;code&gt;journal/&lt;/code&gt; directory stores logs in a binary format to make them searchable and faster to filter. The &lt;code&gt;journalctl&lt;/code&gt; command is used to read these binary logs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/syslog           &lt;span class="c"&gt;# live system events&lt;/span&gt;
journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; nginx &lt;span class="nt"&gt;-f&lt;/span&gt;            &lt;span class="c"&gt;# live logs for a specific service&lt;/span&gt;
journalctl &lt;span class="nt"&gt;-xe&lt;/span&gt;                    &lt;span class="c"&gt;# recent journal with explanations&lt;/span&gt;
journalctl &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"1 hour ago"&lt;/span&gt;   &lt;span class="c"&gt;# last hour of everything&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When something breaks, look for the log file for the specific thing that broke. It almost always contains the exact error. If logs kept growing forever, they’d fill your entire disk. Linux uses a tool called &lt;code&gt;logrotate&lt;/code&gt; that periodically takes the old log, compresses it in the &lt;code&gt;.gz&lt;/code&gt; files, and eventually deletes it&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;/etc/systemd/system/&lt;/code&gt; writing a service that survives crashes
&lt;/h2&gt;

&lt;p&gt;Systemd starts everything on boot and manages services. Unit files in &lt;code&gt;/etc/systemd/system/&lt;/code&gt; tell it what to run.&lt;/p&gt;

&lt;p&gt;I wanted a script running on boot that restarted if it crashed. Cron can run on boot with &lt;code&gt;@reboot&lt;/code&gt; but has no crash recovery. A service file does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /etc/systemd/system/myapp.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;Unit]
&lt;span class="nv"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;My app
&lt;span class="nv"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;network.target

&lt;span class="o"&gt;[&lt;/span&gt;Service]
&lt;span class="nv"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;simple
&lt;span class="nv"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;saumya
&lt;span class="nv"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/saumya/app
&lt;span class="nv"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/node server.js
&lt;span class="nv"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;on-failure
&lt;span class="nv"&gt;RestartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5
&lt;span class="nv"&gt;StandardOutput&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;journal
&lt;span class="nv"&gt;StandardError&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;journal

&lt;span class="o"&gt;[&lt;/span&gt;Install]
&lt;span class="nv"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;After=&lt;/code&gt;&lt;a href="http://network.target" rel="noopener noreferrer"&gt;&lt;code&gt;network.target&lt;/code&gt;&lt;/a&gt; line is a safety check that tells Linux to not start this app until the network is actually up.&lt;br&gt;&lt;br&gt;
By default, system services want to run as &lt;code&gt;root&lt;/code&gt; and can be a security risk. If the app gets hacked, &lt;code&gt;User=&lt;/code&gt; makes sure the attacker is trapped in the user account and doesn't get access to keys. &lt;code&gt;WorkingDirectory&lt;/code&gt; ensures that if the code looks for a file in &lt;code&gt;./config&lt;/code&gt;, it's looking in the right folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl daemon-reload
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;myapp
systemctl start myapp
systemctl status myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Restart=on-failure&lt;/code&gt; is the important line. The process crashes, it comes back in 5 seconds because of &lt;code&gt;RestartSec=5&lt;/code&gt; which can be adjusted. You stop it with &lt;code&gt;systemctl stop&lt;/code&gt;. The distinction between a crash and an intentional stop is handled automatically.&lt;/p&gt;

&lt;p&gt;Logs for this service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; myapp &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;code&gt;PATH&lt;/code&gt; why commands vanish when you break one variable
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;PATH&lt;/code&gt; tells the shell where to look for executables. When you type &lt;code&gt;ls&lt;/code&gt;, the shell searches every directory in PATH until it finds a file named &lt;code&gt;ls&lt;/code&gt;. If PATH is wrong, every command fails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash: &lt;span class="nb"&gt;ls&lt;/span&gt;: &lt;span class="nb"&gt;command &lt;/span&gt;not found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything is gone. The binaries still exist on disk but the shell just lost its map. It can be fixed with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin:/bin:/usr/sbin:/sbin
&lt;span class="nb"&gt;ls&lt;/span&gt;    &lt;span class="c"&gt;# back&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why this matters beyond the experiment: cron jobs run with a stripped PATH by default. If your script calls something in &lt;code&gt;/usr/local/bin&lt;/code&gt; and cron's PATH does not include that directory, the cron job silently fails with "command not found" while the exact same script works fine in your terminal. Set PATH explicitly in your crontab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/local/bin:/usr/bin:/bin
&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /home/saumya/myscript.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re ever unsure where a command is actually coming from, use &lt;code&gt;which&lt;/code&gt;. Running &lt;code&gt;which ls&lt;/code&gt; shows the exact path the shell found. It also helps to verify if the map is working.&lt;/p&gt;




&lt;h2&gt;
  
  
  Permissions
&lt;/h2&gt;

&lt;p&gt;Permissions in theory is &lt;code&gt;chmod&lt;/code&gt;, &lt;code&gt;rwx&lt;/code&gt;, octal numbers. In practice I kept getting them wrong until I broke something on purpose.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'#!/bin/bash
echo "this ran"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; myscript.sh
./myscript.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash: ./myscript.sh: Permission denied
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file exists and the content is correct, but newly created files have no execute permission. Check with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; myscript.sh
&lt;span class="c"&gt;# -rw-r--r-- 1 saumya saumya 30 myscript.sh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;x&lt;/code&gt; anywhere. Add it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x myscript.sh
./myscript.sh
&lt;span class="c"&gt;# this ran&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the more interesting break. Remove execute from &lt;code&gt;ls&lt;/code&gt; itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; &lt;span class="nt"&gt;-x&lt;/span&gt; /bin/ls
&lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash: /bin/ls: Permission denied
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ls&lt;/code&gt; still exists on disk. It just cannot be executed. From the shell's perspective it might as well not be there. Fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /bin/ls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The three positions: owner, group, others mean the same permissions behave differently depending on who runs the command. When your web server returns 403 errors and logs say "permission denied," this is why. The files exist, the server is running, but &lt;code&gt;www-data&lt;/code&gt; does not have the permission to read them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; www-data:www-data /var/www/html
&lt;span class="nb"&gt;chmod&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 755 /var/www/html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a file: +x means you can run it; But for a directory: +x means you can view it using &lt;code&gt;cd&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
Linux works on &lt;strong&gt;Principle of Least Privilege(PoLP)&lt;/strong&gt;, hence avoid the temptation to run &lt;code&gt;chmod 777&lt;/code&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Environment variables
&lt;/h2&gt;

&lt;p&gt;A friend set a variable in &lt;code&gt;~/.bashrc&lt;/code&gt;. It worked in his terminal. His systemd service couldn't see it which is followed by hours of debugging.&lt;/p&gt;

&lt;p&gt;Every process inherits environment variables from its parent. The terminal is started by the login process, which sources &lt;code&gt;~/.bashrc&lt;/code&gt;, which sets your variables. Systemd (PID 1) starts services. Systemd never read your &lt;code&gt;~/.bashrc&lt;/code&gt;. The variables your terminal has, the service has never heard of.&lt;/p&gt;

&lt;p&gt;Your terminal reads &lt;code&gt;~/.bashrc&lt;/code&gt; and &lt;code&gt;/etc/profile&lt;/code&gt; and has everything you configured. A cron job reads almost nothing. PATH is &lt;code&gt;/usr/bin:/bin&lt;/code&gt;. Your tools in &lt;code&gt;/usr/local/bin&lt;/code&gt; are invisible. A systemd service reads only what you explicitly declare in its unit file under &lt;code&gt;[Service]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For services, declare variables in the unit file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;Service]
&lt;span class="nv"&gt;Environment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production
&lt;span class="nv"&gt;EnvironmentFile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/etc/myapp/.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For cron, set PATH at the top of the crontab or use absolute paths everywhere. For your own sessions, &lt;code&gt;~/.bashrc&lt;/code&gt; works. The confusion only happens when you expect one environment to be visible in another. In Linux, explicit is better than implicit. If a service needs a variable, tell the service directly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Terminal shortcuts worth memorizing now
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Ctrl+R&lt;/code&gt; searches command history interactively. Start typing any part of a command you ran before. This is faster than retyping long paths.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd -&lt;/code&gt; goes to the last directory you were in. Jump between two locations without retyping either path.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;!!&lt;/code&gt; repeats the last command. The classic use is &lt;code&gt;sudo !!&lt;/code&gt; when you forgot sudo.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Ctrl+A&lt;/code&gt; and &lt;code&gt;Ctrl+E&lt;/code&gt; jump to the start and end of the current line. &lt;code&gt;Ctrl+W&lt;/code&gt; deletes the last word backwards. These three reduce terminal frustration noticeably.&lt;/p&gt;

&lt;p&gt;When a config file edit breaks something and you want to know exactly what changed: &lt;code&gt;diff /etc/nginx/nginx.conf.backup /etc/nginx/nginx.conf&lt;/code&gt;. Keep backups before editing important files. &lt;code&gt;cp nginx.conf nginx.conf.bak&lt;/code&gt; takes two seconds.&lt;/p&gt;

&lt;p&gt;I found two resources that can be helpful in the learning curve of Linux:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://labex.io/linuxjourney" rel="noopener noreferrer"&gt;Linux Journey&lt;/a&gt; : This has organized learning path that breaks down the complexities of the Linux operating system into digestible stages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://overthewire.org/wargames/bandit/" rel="noopener noreferrer"&gt;Bandit&lt;/a&gt; : It is wargame designed to teach the fundamentals of the Linux command line. Visually looks boring, but is really interesting to follow through.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=LKCVKw9CzFo" rel="noopener noreferrer"&gt;Fireship: Linux in 100 Seconds&lt;/a&gt; : start here if you haven't&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://man7.org/linux/man-pages/" rel="noopener noreferrer"&gt;Linux man pages&lt;/a&gt; : every file and command has one&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://tldr.sh/" rel="noopener noreferrer"&gt;tldr pages&lt;/a&gt; : install with &lt;code&gt;apt install tldr&lt;/code&gt;, use it for every new command&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://wiki.archlinux.org/" rel="noopener noreferrer"&gt;Arch Wiki&lt;/a&gt; : the best Linux documentation on the internet, works for all distros regardless of what you're running&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://explainshell.com/" rel="noopener noreferrer"&gt;explainshell.com&lt;/a&gt; : paste any command and it breaks down every flag visually&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.kernel.org/doc/html/latest/filesystems/index.html" rel="noopener noreferrer"&gt;The filesystem docs&lt;/a&gt; : official kernel documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>linux</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Beyond window: Understanding global and globalThis in JavaScript</title>
      <dc:creator>Saumya Agrawal</dc:creator>
      <pubDate>Fri, 13 Mar 2026 08:50:15 +0000</pubDate>
      <link>https://forem.com/idreamfyrei/beyond-window-understanding-global-and-globalthis-in-javascript-593p</link>
      <guid>https://forem.com/idreamfyrei/beyond-window-understanding-global-and-globalthis-in-javascript-593p</guid>
      <description>&lt;p&gt;When you wrote your first code in Node.js, you used &lt;code&gt;console&lt;/code&gt; and &lt;code&gt;setTimeout&lt;/code&gt; without the need for import or declaration. They are present in your IDE, ready to be used. Have you ever wondered where they came from?&lt;/p&gt;

&lt;p&gt;It is all the work of &lt;code&gt;global&lt;/code&gt;, an object that Node.js creates way before the code even starts to run. An object that holds everything the runtime gives you for free.&lt;/p&gt;

&lt;p&gt;JavaScript then introduced &lt;code&gt;globalThis&lt;/code&gt;, which is a story in itself about the growth of Node.js.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is Node.js?
&lt;/h2&gt;

&lt;p&gt;Before we dive into &lt;code&gt;global&lt;/code&gt;, let's understand what Node.js is.&lt;/p&gt;

&lt;p&gt;JavaScript was initially intended for browsers to run inside Chrome, Firefox, and Safari. The browsers provided a runtime, an engine to execute the code, along with a set of built-in tools like &lt;code&gt;document&lt;/code&gt;, &lt;code&gt;window&lt;/code&gt;, and &lt;code&gt;fetch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Node.js wanted to take the JavaScript engine, V8, out of the browser and make it run anywhere.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtrgl75v9raw824505sq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtrgl75v9raw824505sq.png" alt="Difference in Browser and Node.js" width="800" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same language running on a different environment, but they have their own version of an object that holds everything a code needs without the need to import.&lt;/p&gt;

&lt;p&gt;In the browser: the object is &lt;code&gt;window.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In Node.js: the object is called &lt;code&gt;global&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;global&lt;/code&gt;: The Node.js Global Object
&lt;/h2&gt;

&lt;p&gt;When Node.js starts, it creates a &lt;code&gt;global&lt;/code&gt; object and provides it with every tool the code needs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// When the code is written:&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I am global&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Javascript does this in the background:&lt;/span&gt;
&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I am global&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But Node.js allows us to skip adding &lt;code&gt;global&lt;/code&gt; every time, and looks things up on &lt;code&gt;global&lt;/code&gt; automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTimeout&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They are the same objects, &lt;code&gt;global&lt;/code&gt; is where they are stored.&lt;/p&gt;

&lt;h3&gt;
  
  
  What lives on &lt;code&gt;global&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8096l1hkpw0profzwwxb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8096l1hkpw0profzwwxb.png" alt="Web API native to global and Node" width="800" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;this&lt;/code&gt; in Node.js
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// At the top of a Node.js file:&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;          
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By looking at the code above, you might expect &lt;code&gt;this&lt;/code&gt; to be &lt;code&gt;global&lt;/code&gt;. Surprisingly, it is not. The output of &lt;code&gt;console.log(this)&lt;/code&gt; is &lt;code&gt;{}&lt;/code&gt; which is not &lt;code&gt;global&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Node.js wraps every single file in a function before running it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//  Node.js silently wraps your file in this&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                     
            &lt;span class="nx"&gt;__filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                      

    &lt;span class="c1"&gt;// everything you write goes in here                  &lt;/span&gt;

  &lt;span class="p"&gt;});&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code is not at the true top level, but it is inside a function. And &lt;code&gt;this&lt;/code&gt; inside that function points to &lt;code&gt;module.exports&lt;/code&gt; (which starts as &lt;code&gt;{}&lt;/code&gt;), not to &lt;code&gt;global&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// {}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Node.js, &lt;code&gt;this&lt;/code&gt; returns &lt;code&gt;global&lt;/code&gt; when a function is called.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// Object [global].... (in not-strict mode)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// in browser&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// window&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;this&lt;/code&gt; reference note:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Where code runs&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;
&lt;strong&gt;What&lt;/strong&gt; &lt;code&gt;this&lt;/code&gt; &lt;strong&gt;becomes&lt;/strong&gt;
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Browser top-level&lt;/td&gt;
&lt;td&gt;&lt;code&gt;window&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node top level&lt;/td&gt;
&lt;td&gt;&lt;code&gt;module.exports&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Function call (non-strict)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;global&lt;/code&gt; object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strict mode function&lt;/td&gt;
&lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Method call&lt;/td&gt;
&lt;td&gt;the object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Every environment global&lt;/td&gt;
&lt;td&gt;&lt;code&gt;globalThis&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The Problem That Needed Solving
&lt;/h2&gt;

&lt;p&gt;For years, Node.js developers just used &lt;code&gt;global&lt;/code&gt; and browser developers used &lt;code&gt;window&lt;/code&gt;. The problem here was the need to access &lt;code&gt;global&lt;/code&gt; object in both environments. If you build a utility library that formats dates, handles errors, or adds a bit of logging, and publish it on npm so both browser apps and Node.js apps can use it, it would be difficult because of the different &lt;code&gt;global&lt;/code&gt; object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This crashes in Node.js as window does not exist here&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ReferenceError: window is not defined&lt;/span&gt;

&lt;span class="c1"&gt;// This crashes in a browser as global does not exist here&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ReferenceError: global is not defined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neither name works in both places. So developers started writing workarounds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The only solution was:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;globalObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nb"&gt;global&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nb"&gt;global&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;   &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;   &lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This solved the problem of &lt;code&gt;global&lt;/code&gt;. Hence, there came a need to introduce a fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;globalThis&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;ES2020 introduced &lt;code&gt;globalThis&lt;/code&gt; as the standard, universal way to access the global object in any JavaScript environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Works in Node.js:&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;globalThis&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="c1"&gt;// Works in a browser:&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;globalThis&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="c1"&gt;// Works in a Web Worker:&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;globalThis&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2n8rzwwpuknt7et8jsmi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2n8rzwwpuknt7et8jsmi.png" alt="global object in different environment" width="800" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hence, the solution the devs used was replaced by a single line of code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;globalObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;globalThis&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;globalThis&lt;/code&gt; did not replace &lt;code&gt;global&lt;/code&gt; in Node.js. &lt;code&gt;global&lt;/code&gt; is still there and valid Node.js code. But &lt;code&gt;globalThis&lt;/code&gt; is now the recommended way, especially in the code that might run outside of Node.js.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;global&lt;/code&gt; vs &lt;code&gt;globalThis&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// These do exactly the same thing in Node.js&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// 3.141592653589793&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;globalThis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// 3.141592653589793&lt;/span&gt;

&lt;span class="c1"&gt;// These are the same object&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;global&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;globalThis&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="c1"&gt;// Both let you access anything on the global scope&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTimeout&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;globalThis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTimeout&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference is:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;global&lt;/code&gt; works&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;globalThis&lt;/code&gt; works&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Node.js&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workers&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deno&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;globalThis&lt;/code&gt; is used when a package, utility, or library is created that is meant to be shared.&lt;/p&gt;




&lt;h2&gt;
  
  
  Do Not Add Things to &lt;code&gt;global&lt;/code&gt; Yourself
&lt;/h2&gt;

&lt;p&gt;Node.js will not stop you from putting your own values on &lt;code&gt;global&lt;/code&gt;. However, it is not recommended to use them, and the following example illustrates why.&lt;/p&gt;

&lt;p&gt;If you had a small application that required a username and were about to use that username in multiple files throughout the application, you might think that it would be beneficial to place the username into a global variable so that you can reference it throughout the entire application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app.js — your main file&lt;/span&gt;
&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App started&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="c1"&gt;// greet.js — a separate file&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// no import, just works&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// "Hello, User"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As your application grows and you eventually have ten files, then there is a potential that after months of work on your application, you will have a situation wherein you will have printed a username incorrectly and upon opening the file where the erroneous user name was printed (greet.js), you would notice there was no import statement for this username, thus you would be required to search through all of the files to locate the source of the incorrect username.&lt;/p&gt;

&lt;p&gt;This is what makes variables defined as global variables invisible, and therefore, there is no trail leading to their origin.&lt;/p&gt;

&lt;p&gt;When done correctly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// user.js: one place where username lives&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// greet.js: it's clear exactly where username comes from&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// "Hello, User"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hence, if instead of globally defining your username, you had created an import statement for the username and used the import in greet.js to define the username, then anyone who looks at greet.js immediately sees where the username is declared, and there is no need to search. This type of coding is much easier to work with, especially when the size of your application increases, or someone new to the project is introduced.&lt;/p&gt;




&lt;p&gt;JavaScript was originally designed to run on the browser. However, Node.js took it outside the browser environment and runs JavaScript without the need for a browser.&lt;/p&gt;

&lt;p&gt;The way to access that global object was through the variable &lt;code&gt;global&lt;/code&gt;. Likewise, browsers have a built-in global variable called &lt;code&gt;window&lt;/code&gt; and Web Workers have a built-in global variable called &lt;code&gt;self&lt;/code&gt;, which performs the same function as the global variable.&lt;/p&gt;

&lt;p&gt;As JavaScript expanded into other environments, developers wanted to write code that worked across all of those environments, like Node.js, Windows, etc., with fewer modifications. However, because there was no consistent name for the global object, this was difficult for developers.&lt;/p&gt;

&lt;p&gt;Fortunately, ES2020 introduced the &lt;code&gt;globalThis&lt;/code&gt; variable as the global reference for JavaScript in all environments, it will point to the same object no matter what environment your JavaScript code runs in.&lt;/p&gt;

&lt;p&gt;In the case of Node.js, &lt;code&gt;global&lt;/code&gt; and &lt;code&gt;globalThis&lt;/code&gt; both point to the same place. You would use &lt;code&gt;global&lt;/code&gt; if you wanted to write code that was specific to Node.js and you want to explicitly reference &lt;code&gt;global&lt;/code&gt;. You would use &lt;code&gt;globalThis&lt;/code&gt; if you needed to write code that may eventually run in a different environment.&lt;/p&gt;




&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nodejs.org/api/globals.html" rel="noopener noreferrer"&gt;Node.js : Global Objects&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis" rel="noopener noreferrer"&gt;MDN : globalThis&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://javascript.info" rel="noopener noreferrer"&gt;javascript.info&lt;/a&gt; &lt;a href="https://javascript.info/global-object" rel="noopener noreferrer"&gt;: Global Object&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Understanding JavaScript Variables and Data Types Through Game Design</title>
      <dc:creator>Saumya Agrawal</dc:creator>
      <pubDate>Sun, 08 Mar 2026 04:19:29 +0000</pubDate>
      <link>https://forem.com/idreamfyrei/understanding-javascript-variables-and-data-types-through-game-design-12n5</link>
      <guid>https://forem.com/idreamfyrei/understanding-javascript-variables-and-data-types-through-game-design-12n5</guid>
      <description>&lt;p&gt;Whenever you start learning a programming language, be it Python, Java, C++, or JavaScript, one concept is common to all of them: &lt;strong&gt;variables&lt;/strong&gt; and &lt;strong&gt;data types&lt;/strong&gt;. Variables and Data Types are the building blocks of a programming language. Variables solve a simple yet important problem: the memory. When a user types their name into a login form, your code needs to hold onto that name long enough to display it, validate it, or send it to a server. When a game tracks your score, it stores that number somewhere so it can update it every time you earn points. Without variables, every piece of data would vanish the moment it appeared. Your program would have no memory, no state, and no way to make decisions based on what happened before.&lt;br&gt;&lt;br&gt;
But storing data is only half the story. A program also needs to understand what kind of data it is working with. This is where data types come in. Imagine storing the value 50. Is it a number representing age? A score in a game? Or is it the string "50" typed by a user in a form? The program needs to know this difference because it determines what operations can be performed on that value. Numbers can be added, divided, or compared mathematically, while strings are treated as text that can be concatenated, sliced, or formatted. Data types give meaning and structure to the values stored in variables.&lt;/p&gt;

&lt;p&gt;Let's explore the two with the concept of games.&lt;/p&gt;
&lt;h2&gt;
  
  
  Variables: The Save File
&lt;/h2&gt;

&lt;p&gt;Imagine playing an RPG with no save files. Whenever you launch the game, your character is gone, the item in your bag disappears, your world resets. The world has no idea who you are in every single run.&lt;/p&gt;

&lt;p&gt;That would be unbearable, exactly what code would be like without variables.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;variable&lt;/strong&gt; is JavaScript's save file. It's a named space in memory where your program stores a piece of information and can look it up later by that name.&lt;/p&gt;


💡
A variable is a named save slot in memory that can store values, so it can be used later.


&lt;p&gt;Hence, every RPG has a save file, where the game save your progress, the character name, the inventory, current HP, upgrades, map, level, character progression. Later when you load your save file, you start from where you left off.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Variable Mapping of Save File&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;fileName&lt;/th&gt;
&lt;th&gt;Store&lt;/th&gt;
&lt;th&gt;JS Syntax&lt;/th&gt;
&lt;th&gt;Data Type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;playerName&lt;/td&gt;
&lt;td&gt;Caraxes&lt;/td&gt;
&lt;td&gt;let playerName = 'Caraxes'&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;health&lt;/td&gt;
&lt;td&gt;70&lt;/td&gt;
&lt;td&gt;let health = 70&lt;/td&gt;
&lt;td&gt;Number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BOSS_LEVEL&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;const BOSS_LEVEL = 14&lt;/td&gt;
&lt;td&gt;Number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;swordAcquired&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;let swordAcquired = false&lt;/td&gt;
&lt;td&gt;Boolean&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In JavaScript code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Creating save file for a game character&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;playerName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Caraxes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="c1"&gt;// slot: name&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;health&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                 &lt;span class="c1"&gt;// slot: current HP&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;bossLevel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;               &lt;span class="c1"&gt;// slot: starts at 0&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;swordAcquired&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BOSS_LEVEL&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;         &lt;span class="c1"&gt;// locked: Number of Boss remains same&lt;/span&gt;

&lt;span class="c1"&gt;// Reading from save slots&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;playerName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// "Caraxes"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;           &lt;span class="c1"&gt;// 100&lt;/span&gt;

&lt;span class="c1"&gt;// The game progresses update the slots&lt;/span&gt;
&lt;span class="nx"&gt;health&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                 &lt;span class="c1"&gt;// player took damage&lt;/span&gt;
&lt;span class="nx"&gt;bossLevel&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              &lt;span class="c1"&gt;// progression on map&lt;/span&gt;
&lt;span class="nx"&gt;swordAcquired&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;         &lt;span class="c1"&gt;// sword found&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;          &lt;span class="c1"&gt;// 70&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bossLevel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;swordAcquired&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Declaring Variables: var, let and const
&lt;/h2&gt;

&lt;p&gt;In games, not all save slots work the same way. Some hold your main campaign state, updated regularly. Some are locked achievement records you can only read, never modify.&lt;/p&gt;

&lt;p&gt;JavaScript offers &lt;strong&gt;three keywords&lt;/strong&gt; through which variables can be declared:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;code&gt;var:&lt;/code&gt; The original way to declare variables which is now deprecated. It can be redeclared and has no scope. It introduces a lot of bugs to the code by not following the modern rules and concepts introduced to JavaScript.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;playerName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Caraxes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;playerName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;            &lt;span class="c1"&gt;//Caraxes&lt;/span&gt;

&lt;span class="c1"&gt;//Redeclared&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;playerName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Neoz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;playerName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;            &lt;span class="c1"&gt;//Neoz&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡&lt;br&gt;
The problem with &lt;code&gt;var&lt;/code&gt; is that it can be &lt;strong&gt;redeclared&lt;/strong&gt; without any warning, which makes it easy to accidentally overwrite a value and create bugs which are difficult to spot.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;code&gt;let:&lt;/code&gt; This keyword is used when the variables are expected to see change overtime.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;health&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;healthPotion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// 60&lt;/span&gt;

&lt;span class="c1"&gt;// update value&lt;/span&gt;
&lt;span class="nx"&gt;health&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;health&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;healthPotion&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// 80&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;health&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;         &lt;span class="c1"&gt;// SyntaxError:'health' has already been declared&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡&lt;br&gt;
You can update it freely but you cannot &lt;em&gt;redeclare&lt;/em&gt; the same variable in the same scope&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;code&gt;const:&lt;/code&gt; This keyword is used when the variables are not supposed to change.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;maxHealth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;maxHealth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;         &lt;span class="c1"&gt;//TypeError: Assignment to constant variable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡&lt;br&gt;
Default to &lt;code&gt;const&lt;/code&gt;. Only switch to &lt;code&gt;let&lt;/code&gt; if you know the value will change. Never use &lt;code&gt;var&lt;/code&gt; in your code.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var&lt;/code&gt; vs &lt;code&gt;let&lt;/code&gt; vs &lt;code&gt;const&lt;/code&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;&lt;code&gt;var&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;let&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;const&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Redeclared&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reassigned&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;Function&lt;/td&gt;
&lt;td&gt;Block&lt;/td&gt;
&lt;td&gt;Block&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hoisted&lt;/td&gt;
&lt;td&gt;Yes, as &lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Yes but not initialized&lt;/td&gt;
&lt;td&gt;Yes, but not initialized&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use&lt;/td&gt;
&lt;td&gt;Avoid&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes, preferred&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Primitive Data Types: What Goes In The Slot?
&lt;/h2&gt;

&lt;p&gt;A save file aka variable stores value, and every value has a &lt;strong&gt;type&lt;/strong&gt;. Some slots hold text (a character name), some hold numbers (HP), some hold a simple yes/no flag (does the character have a sword?). In JavaScript, the type of the value determines what it is, how it would behave and what operations can be performed.&lt;/p&gt;

&lt;p&gt;There are &lt;em&gt;five&lt;/em&gt; primitive data types:&lt;/p&gt;

&lt;h3&gt;
  
  
  String
&lt;/h3&gt;

&lt;p&gt;Any text placed between quotes, which can be single, double or backticks are treated as string type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Caraxes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;greeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Welcome to Neverland, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Template literal&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Caraxes&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Hello&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// Welcome to Neverland, Caraxes!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡&lt;br&gt;
Backtick strings or template literals lets you embed variables using &lt;code&gt;${}&lt;/code&gt;. Prefer them over string concatenation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Number
&lt;/h3&gt;

&lt;p&gt;Integers and decimals are &lt;code&gt;number&lt;/code&gt; in JavaScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;health&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                 
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;healthPotion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// 90&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;level&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡&lt;br&gt;
Watch out for floating-point quirks: &lt;code&gt;console.log(0.1 + 0.2);&lt;/code&gt; results in &lt;code&gt;0.30000000000000004&lt;/code&gt; as JS uses &lt;strong&gt;IEEE 754&lt;/strong&gt; standard. use &lt;code&gt;toFixed()&lt;/code&gt; to solve this problem or make use of library in case of sensitive data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Boolean
&lt;/h3&gt;

&lt;p&gt;They have two states: either yes/true or no/false. They are used in logic and consitions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isAlive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;hasArmour&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isAlive&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hasArmour&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// false&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;hasArmour&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You are vulnerable in Boss fight&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// You are vulnerable in Boss fight&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡&lt;br&gt;
Boolean variables often start with &lt;code&gt;is&lt;/code&gt;, &lt;code&gt;has&lt;/code&gt;, or &lt;code&gt;can&lt;/code&gt; — like &lt;code&gt;isLoggedIn&lt;/code&gt;, &lt;code&gt;hasPermission&lt;/code&gt;, &lt;code&gt;canUpdate&lt;/code&gt;. This makes the intent immediately clear.&lt;/p&gt;

&lt;h3&gt;
  
  
  Null
&lt;/h3&gt;

&lt;p&gt;It is used to make an intentional empty slot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;weaponEquipped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;weaponEquipped&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Undefined
&lt;/h3&gt;

&lt;p&gt;When a variable or slot exist but a value is not stored in that slot. JavaScript does it automatically when you declare a variable without assigning a value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;conquest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;conquest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Highlights:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;playerName&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Caraxes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// String. Text in quotes&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;health&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="c1"&gt;// Number. No quotes&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;hasShield&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="c1"&gt;// Boolean. true or false&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;equippedGun&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="c1"&gt;// Null. Empty on purpose&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;questReward&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="c1"&gt;// Undefined. Slot exists, nothing saved yet&lt;/span&gt;

&lt;span class="c1"&gt;// typeof reveals the type stored in each slot&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;playerName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// "string"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// "number"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;hasShield&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// "boolean"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;equippedGun&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// "object"  JS bug&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;questReward&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// "undefined"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡&lt;br&gt;
&lt;code&gt;typeof null&lt;/code&gt; returns &lt;code&gt;"object"&lt;/code&gt; — this is a &lt;a rel="noopener noreferrer nofollow" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof#typeof_null"&gt;bug in JavaScript&lt;/a&gt; that was never fixed for backward compatibility reasons.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;weapon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;weapon&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// "object" which is confusing&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;weapon&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// true. use this instead&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Scope: Who can access which slot?
&lt;/h2&gt;

&lt;p&gt;Some game data is global. Your player name shows in every menu, every screen. Other data only exists during a specific fight, a boss's HP bar lives only for that encounter. When you leave the arena, it's gone.&lt;/p&gt;

&lt;p&gt;That's &lt;strong&gt;scope&lt;/strong&gt;. It determines where in your code a variable is accessible. &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; are block-scoped, they live only inside the &lt;code&gt;{ }&lt;/code&gt; where they were created. &lt;code&gt;var&lt;/code&gt; ignores blocks and leaks out, which is exactly the problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Global Scope
&lt;/h3&gt;

&lt;p&gt;A variable declared outside any function or block is &lt;strong&gt;global&lt;/strong&gt;. It can be accessed anywhere in your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Block Scope
&lt;/h3&gt;

&lt;p&gt;Variables declared with &lt;code&gt;let&lt;/code&gt; or &lt;code&gt;const&lt;/code&gt; inside curly braces &lt;code&gt;{ }&lt;/code&gt; only exist &lt;em&gt;within&lt;/em&gt; those braces.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GAME_TITLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dark Soul&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// Global scope but cant be changed&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;playerName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Caraxes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="c1"&gt;// Global scope but can be changed&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                        &lt;span class="c1"&gt;// entering the boss arena&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;bossHealth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;         &lt;span class="c1"&gt;// block-scoped: stays here&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bossName&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Nameless King&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// block-scoped: stays here&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;narrator&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You can't trap me&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// leaks out!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;playerName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// "Caraxes" &lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;narrator&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// "You can't trap me" | var leaked out&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bossHealth&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// ReferenceError: bossHealth is not defined&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bossName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// ReferenceError: bossName is not defined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxuxv8720vi076hfy2f2h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxuxv8720vi076hfy2f2h.png" alt=" " width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡&lt;br&gt;
&lt;code&gt;var&lt;/code&gt; was designed before block scope existed. It ignores &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt;, and &lt;code&gt;while&lt;/code&gt; blocks. This means a &lt;code&gt;var&lt;/code&gt; declared inside an &lt;code&gt;if&lt;/code&gt; statement is accessible outside it. It is a real source of bugs. &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; were created specifically to fix this.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript Glitches
&lt;/h2&gt;

&lt;p&gt;Every game ships with a few unintended bugs. JavaScript is no different, it had certain behaviour in its early days. As the language evolved, new features were introduced to help in fixing those issues, but the older issues cannot be patched because as too much of the web depends on them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;"5" + 3 equals "53", not 8&lt;/strong&gt;
The &lt;code&gt;+&lt;/code&gt; operator does two different things: math addition and string joining. If either side is a string, JS concatenates instead of adding. This surprises almost every beginner, especially when user input (from forms, URLs, etc.) arrives as a string that looks like a number.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bonus points come in from a form, they're a STRING&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;bonus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// looks like a number, has quotes = string&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;bonus&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;           &lt;span class="c1"&gt;// "50100" | string concat&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bonus&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;   &lt;span class="c1"&gt;// 150 | explicit conversion&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;bonus&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;         &lt;span class="c1"&gt;// 150 | unary + shorthand&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;const doesn't lock object contents&lt;/strong&gt;
&lt;code&gt;const&lt;/code&gt; prevents &lt;em&gt;reassigning the slot&lt;/em&gt;, but if the slot holds an object, the object's properties can still change. Think of it as locking the locker door, not what's stored inside it.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Neoz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;health&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;health&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// changing a property is allowed&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// { name: "Neoz", health: 80 }&lt;/span&gt;

&lt;span class="nx"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;             &lt;span class="c1"&gt;// TypeError | can't swap the whole object&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Save File
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;variable&lt;/strong&gt; stores a named value in memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;code&gt;const&lt;/code&gt; by default. Switch to &lt;code&gt;let&lt;/code&gt; only if the value needs to change. Avoid &lt;code&gt;var&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The 5 primitive types are: &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;boolean&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt;, and &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scope&lt;/strong&gt; controls where a variable is accessible. &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; are block-scoped; &lt;code&gt;var&lt;/code&gt; is not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;code&gt;typeof&lt;/code&gt; to inspect what type a variable holds.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Continue Your Quest
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#declarations" rel="noopener noreferrer"&gt;MDN : Variables&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://javascript.info" rel="noopener noreferrer"&gt;javascript.info&lt;/a&gt;&lt;a href="https://javascript.info/variables" rel="noopener noreferrer"&gt;: Variables&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures" rel="noopener noreferrer"&gt;MDN: JavaScript Data Types&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://javascript.info" rel="noopener noreferrer"&gt;javascript.info&lt;/a&gt;&lt;a href="https://javascript.info/types" rel="noopener noreferrer"&gt;: Data Types&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof" rel="noopener noreferrer"&gt;MDN: typeof operator&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var" rel="noopener noreferrer"&gt;MDN: var&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let" rel="noopener noreferrer"&gt;MDN: let&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const" rel="noopener noreferrer"&gt;MDN: const&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
