JavaScript Fundamentals

JavaScript basics - from function definition over data types to error handling

For Python developers, JavaScript can feel can feel quite strange when trying to read it. Mostly due to its extensive usage of brackets. But once fundamental differences are understood, JavaScript becomes familiar and as easy to write and read.

Syntax and Language Structure

Key Differences from Python

Python emphasizes readability through indentation. JavaScript, by contrast, uses braces {} to define blocks and semicolons ; to terminate statements.

python

1
2
if x > 10:
    print("Large number")
javascript

1
2
3
if (x > 10) {
    console.log("Large number");
};

Key distinctions: - Parentheses () are required around conditions - Braces {} define code blocks - Semicolons are technically optional but strongly recommended

Indentation in JavaScript is stylistic, not syntactic. Poor formatting won’t break execution, but it will absolutely hurt readability. That's why semicolons are recommended. A semicolon marks the end of a statement. Modern browsers know how to interpret neatly formatted code that uses newlines to terminate blocks. However obfuscated code, something like this:

javascript

1
(function(){const _0x=['log','fromCharCode','length'];for(let i of _ox)...};);

needs semicolons to make it readable to the browser so it can interpret end of blocks (like if-statements and for-loops) properly.

Variables: var, let, const

Python variables are created via assignment, with no explicit declaration:

python

1
x = 10

JavaScript requires declaration keywords:

javascript

1
2
3
let x = 10;
const y = 20;
var z = 30;

Differences: - let: block-scoped, mutable (most commonly used) - const: block-scoped, immutable binding (preferred by default) - var: function-scoped, legacy (avoid in modern code)

Important nuance:

javascript

1
2
const obj = { name: "Alice" };
obj.name = "Bob"; // allowed

const prevents reassignment, not mutation of contents.

Naming Conventions and Idioms

Python uses snake_case:

python

1
user_name = "alice"

JavaScript uses camelCase:

javascript

1
let userName = "alice";

Conventions: - Variables/functions: camelCase - Classes: PascalCase - Constants: UPPER_CASE (less strictly enforced than Python)

Data Types and Structures

Primitive Types vs Python Equivalents

JavaScript Python Equivalent
number int, float
string str
boolean bool
null None
undefined (no direct equivalent)

Example:

python

1
2
3
4
5
let count = 42;
let name = "Alice";
let isActive = true;
let value = null;
let notAssigned;

undefined means a variable exists but has no value—this concept doesn’t really exist in Python.

Objects vs Python Dictionaries

JavaScript objects are conceptually similar to Python dictionaries:

javascript

1
2
user = {"name": "Alice", "age": 30}
print(user["name"])
python

1
2
const user = { name: "Alice", age: 30 };
console.log(user.name);

Differences: - Dot notation (user.name) is common in JavaScript - Keys are typically strings (even if not quoted)

The wording might be confusing since "object" means something entirely different in Python. Just remember that in JavaScript an object is a dictionary. Nothing more.

Arrays vs Python Lists

javascript

1
2
numbers = [1, 2, 3]
numbers.append(4)
javascript

1
2
let numbers = [1, 2, 3];
numbers.push(4);

JavaScript arrays are more flexible but less consistent - they are technically objects (javascript dictionaries) and can behave unexpectedly.


Type Coercion (Critical Concept)

JavaScript performs implicit type conversions:

javascript

1
2
console.log("5" + 1);  // "51"
console.log("5" - 1);  // 4

Python would raise an error: TypeError: "5" + 1

To avoid surprises, use strict equality:

javascript

1
2
console.log(5 == "5");   // true (coercion)
console.log(5 === "5");  // false (strict)

Rule of thumb: Always prefer === over ==. === does not just compare values, it also compares the value types. Only if value AND type match, === returns true.

Functions and Scope

Function Declarations vs Expressions

Function declaration:

javascript

1
2
3
function greet(name) {
    return `Hello, ${name}`;
}

Function expression:

javascript

1
2
3
const greet = function(name) {
    return `Hello, ${name}`;
};

Difference: - Declarations are hoisted (can be used before definition) - Expressions are not

Arrow Functions

Arrow functions provide a concise syntax:

javascript

1
2
3
const greet = (name) => {
    return `Hello, ${name}`;
};

Short form:

javascript

1
const greet = name => `Hello, ${name}`;

When to use: - Short, functional-style code - Callbacks

When to avoid: - When you need a dynamic this (arrow functions don’t bind their own this)

Scope: Global, Function, Block

Global scope:

javascript

1
let globalVar = "I am global";

Function scope:

javascript

1
2
3
function test() {
    let localVar = "Inside function";
};

Block scope (let and const only):

javascript

1
2
3
4
if (true) {
    let blockVar = "Inside block";
}
// blockVar is not accessible here

Important contrast:

javascript

1
2
3
4
5
if (true) {
    var x = 10;
}

console.log(x); // 10 (var ignores block scope)

This is why var is discouraged and let or const are preferred.

Closures (Compared to Python)

Closures occur when a function retains access to its outer scope.

python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
function outer() {
    let count = 0;

    return function inner() {
        count++;
        return count;
    };
}

const counter = outer();
console.log(counter()); // 1
console.log(counter()); // 2
javascript

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def outer():
    count = 0

    def inner():
        nonlocal count
        count += 1

        return count

    return inner

Key takeaway: JavaScript closures are more common and heavily used in callbacks and async patterns.

Control Flow

Conditionals

javascript

1
2
3
4
5
6
7
if (x > 10) {
    console.log("Large");
} else if (x > 5) {
    console.log("Medium");
} else {
    console.log("Small");
}

Switch statement (Python -> match, case):

javascript

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
switch (color) {
    case "red":
        console.log("Stop");
        break;
    case "green":
        console.log("Go");
        break;
    default:
        console.log("Unknown");
}

Loops

Classic for loop:

javascript

1
2
3
for (let i = 0; i < 5; i++) {
    console.log(i);
}

While loop:

javascript

1
2
3
4
5
let i = 0;
while (i < 5) {
    console.log(i);
    i++;
}

for...of (values) - iterating over i.e. arrays:

javascript

1
2
3
4
const nums = [1, 2, 3];
for (const num of nums) {
    console.log(num);
}

for...in (keys):

javascript

1
2
3
4
const user = { name: "Alice", age: 30 };
for (const key in user) {
    console.log(key, user[key]);
}

Python comparison: - for...of ≈ for x in list - for...in ≈ iterating over dict keys

Error Handling (try...catch)

python

1
2
3
4
5
6
7
try {
    let result = riskyFunction();
} catch (error) {
    console.log("Error occurred:", error.message);
} finally {
    console.log("Cleanup");
}
text

1
2
3
4
5
6
try:
    result = risky_function()
except Exception as e:
    print("Error occurred:", str(e))
finally:
    print("Cleanup")

JavaScript’s model is similar but less granular. There’s no built-in equivalent to multiple except types unless you manually inspect the error.

For Python developers, JavaScript’s fundamentals are less about learning entirely new concepts and more about recalibrating expectations. The syntax is different, but the deeper shift lies in: - Handling type coercion carefully - Understanding scope and closures - Adapting to JavaScript’s flexible (and sometimes inconsistent) structures

Once these are internalized, JavaScript becomes significantly more predictable and far more powerful as a complement to your Python skillset.

Join the Newsletter

Practical insights on Django, backend systems, deployment, architecture, and real-world development — delivered without noise.

Get updates when new guides, learning paths, cheat sheets, and field notes are published.

No spam. Unsubscribe anytime.



There is no third-party involved so don't worry - we won't share your details with anyone.