Index Ai Academy
Phase 8 · APIs · JavaScript

JavaScript for Python programmers

Variables, functions, arrays and objects mapped from Python, and the traps: truthy empty arrays, for...in and string sort.

About 30 minutes · A free account opens the whole lesson

Create a free account Try part of it here

Already have an account? Sign in to open this lesson

Why it matters

Every AI product has a front end, and browsers run one language: JavaScript. Chat interfaces, streaming replies, MCP servers written in TypeScript and the serverless functions that glue services together are all JavaScript. You already know how to program, so this lesson doesn't start over: it maps each Python idea to its JavaScript form, and spends its time on the places where your Python instincts give the wrong answer.

What you'll be able to do

  • Read and write JavaScript variables, functions, arrays and objects by mapping them to what you know in Python
  • Use === and know which values are falsy, including the ones that differ from Python
  • Transform data with map, filter and reduce, destructuring and spread
  • Avoid the classic traps: for...in, default sort, + with strings, and one number type

What it covers

  1. Running JavaScript, and the first differences
  2. Variables: const and let
  3. Comparing and testing: === and falsy values
  4. Functions, arrows and template literals
  5. A price label
  6. Arrays: map, filter and reduce
  7. Objects, destructuring and JSON
  8. Find the bug: the empty cart
  9. Three more traps
  10. A map to keep
Quick check
A guess before anything else. Python raises TypeError for "5" + 3. What does JavaScript print here?
console.log("5" + 3, "5" * 3);
  1. TypeError: can't add a string and a number
  2. 53 53
  3. 53 15
  4. 8 15
Show the answer

53 15

With a string on either side, + joins text, so 3 becomes "3". The other arithmetic operators turn strings into numbers, so "5" * 3 is 15. JavaScript converts quietly where Python would stop you.

Running JavaScript, and the first differences

console.log is print: it takes any number of values and prints them separated by spaces. Blocks use braces instead of indentation, statements end with semicolons by convention, and comments start with //. The code on this page runs in your browser, in a sandbox that formats output the way Node, the JavaScript runtime for servers, does.

// Prices in dollars, as in the shop's catalog
const tent = 189;
const mug = 12;
console.log("Total:", tent + mug);
console.log(7 / 2, Math.floor(7 / 2), 2 ** 10);

Notice 7 / 2 is 3.5. JavaScript has one number type, a 64-bit float like Python's float, so there's no separate integer division operator: use Math.floor (or Math.trunc for negatives toward zero). Very large whole numbers need BigInt, written with an n suffix, which you'll rarely need.

Variables: const and let

Python names are just names. JavaScript asks you to declare them: const for a name you'll never point at something else, let for one you will. Use const by default; reaching for let then signals "this changes". You'll see var in old code, which has confusing scoping rules; don't write it.

const protects the name, not the value. A const array can still grow, and a const object's fields can still change. Reassigning the name itself is the error.

JavaScript has two kinds of nothing. undefined is what you get for a variable with no value, a missing object field or a function with no return. null is the value you write on purpose to mean "empty". Python's None covers both jobs.

Quick check
What does this print?
const tent = { sku: "TENT-2P", price: 189 };
tent.price = 179;
console.log(tent.price);
  1. undefined
  2. TypeError: Assignment to constant variable.
  3. 179
  4. 189
Show the answer

179

const stops tent from naming a different object; it doesn't freeze the object. Changing a field is fine. tent = {} would be the error.

Comparing and testing: === and falsy values

Always compare with === and !==. The double-equals == converts types first, so 0 == "" and "1" == 1 are both true, which hides bugs. Triple-equals compares type and value, like Python's == on simple values.

In an if, JavaScript treats six values as false: false, 0, "", null, undefined and NaN. Everything else is true, and here is the trap for Python programmers: an empty array [] and an empty object {} are true. In Python if items: skips an empty list; in JavaScript if (items) runs for one. Test the length instead: if (items.length === 0).

Objects compare by identity: [1] === [1] is false because they're two different arrays, as with Python's is. To compare contents, compare the fields you care about, or the JSON text of small values.

Quick check
A cart is an empty array, cart = []. Which test is true in JavaScript but false in Python?
  1. if (cart.length > 0)
  2. if (cart)
  3. if (cart.length)
  4. if (cart.includes("tent"))
Show the answer

if (cart)

An empty array is truthy in JavaScript, so if (cart) runs. The other three test the contents and are false for an empty cart in both languages.

In your own words
What does JavaScript do with "5" + 3, and what's truthy that isn't in Python?

Write a sentence or two, then compare it with a good answer in the lesson.

Functions, arrows and template literals

A function declaration looks like Python's def with braces: function total(items) { ... }. Arrow functions are the short form you'll see everywhere, much like lambda but allowed to have a body:

const double = (x) => x * 2;
const label = (name, price = 0) => `${name}: ${price} dollars`;
function shipping(total) {
  if (total >= 100) return 0;
  return 7.5;
}
console.log(double(21), label("Trail mug", 12), shipping(189));

Backtick strings are template literals, JavaScript's f-strings: ${...} holds any expression. Default parameters work as in Python. One difference to remember: a function that reaches its end without return gives back undefined, and calling it with too few arguments doesn't raise. The missing ones are undefined.

Drill

A price label

Write priceLabel(product) for products like { name: "Ridge tent", price: 189, stock: 4 }. It returns "Ridge tent: 189 dollars", and adds " (sold out)" when stock is 0, as in "Trail mug: 12 dollars (sold out)". Use a template literal.

function priceLabel(product) {
  // return a string like "Ridge tent: 189 dollars"
}

console.log(priceLabel({ name: "Ridge tent", price: 189, stock: 4 }));
In the lesson, your code is checked as you write it.

Arrays: map, filter and reduce

Arrays are Python lists: items.length, items.push(x), items.includes(x), items.slice(1, 3) and [...a, ...b] to join two. Instead of list comprehensions, you chain methods that each take a function:

  • filter(fn) keeps the items where fn returns something truthy, like [p for p in ps if ...];
  • map(fn) turns each item into a new one, like [f(p) for p in ps];
  • reduce((acc, x) => ..., start) folds the array into one value, the way a running total does;
  • find(fn) returns the first match or undefined, and some and every are any and all.

To loop yourself, use for (const p of products). Note the word of: for...in also exists, but it walks an object's keys, and on an array those keys are the indexes as strings. It's the most common loop bug for people arriving from Python.

Try it now

Read each line as a Python comprehension: which items, then what from each.

Quick check
What does this print?
const seen = [];
for (const x in ["tent", "mug"]) seen.push(x);
console.log(seen);
  1. [ 0, 1 ]
  2. [ 'tent', 'mug' ]
  3. [ '0', '1' ]
  4. []
Show the answer

[ '0', '1' ]

for...in gives keys, and an array's keys are its indexes as strings. for...of gives the values, which is almost always what you want.

In your own words
What's the difference between for...of and for...in on an array?

Write a sentence or two, then compare it with a good answer in the lesson.

Objects, destructuring and JSON

Objects are JavaScript's dictionaries, written with unquoted keys: { sku: "MUG-01", price: 12 }. Read fields with a dot, p.price, or brackets for a key in a variable, p[key]. A missing field is undefined, not a KeyError, and order.customer?.email stops at the first null or undefined instead of crashing. ?? gives a default only for those two: p.discount ?? 0.

Destructuring pulls fields into names, and spread copies with changes:

const product = { sku: "MUG-01", name: "Trail mug", price: 12, stock: 0 };
const { name, price } = product;
const onSale = { ...product, price: 9 };
console.log(name, price, onSale.price, product.price);
console.log(JSON.stringify({ sku: product.sku, price }));
console.log(Object.entries({ tent: 4, mug: 0 }));

JSON.stringify and JSON.parse are json.dumps and json.loads. Because objects are JSON's own shape, data from an API is ready to use the moment it's parsed.

Quick check
A reminder from Python dictionaries. In Python, what does stock.get("lamp", 0) return when the dictionary has no "lamp" key?
  1. An empty string
  2. 0, the default you passed
  3. None
  4. It raises KeyError
Show the answer

0, the default you passed

.get returns the default when the key is missing. In JavaScript the same idea is stock.lamp ?? 0, because a missing field reads as undefined.

Drill

Find the bug: the empty cart

This function should say "Your cart is empty" for an empty cart, but for [] it says "0 items, 0 dollars". Find the Python habit that causes it and fix it.

function cartSummary(items) {
  if (!items) return "Your cart is empty";
  const total = items.reduce((sum, it) => sum + it.price * it.qty, 0);
  return `${items.length} items, ${total} dollars`;
}

console.log(cartSummary([]));
console.log(cartSummary([{ price: 12, qty: 2 }, { price: 79, qty: 1 }]));
In the lesson, your code is checked as you write it.

Three more traps

Sorting. sort() with no argument converts items to strings and sorts those, so numbers come out in dictionary order. Pass a comparison: prices.sort((a, b) => a - b) sorts numbers from low to high. sort also changes the array in place; toSorted returns a sorted copy, like Python's sorted.

Floats. 0.1 + 0.2 is 0.30000000000000004 here too. For money, count in cents as whole numbers, or round when you display with total.toFixed(2), which returns a string.

Strings and numbers. + joins as soon as either side is a string, which matters for anything read from a form or a URL: "2" + 1 is "21". Convert first with Number(text), and check the result with Number.isNaN, because a bad number becomes NaN instead of raising.

Quick check
What does this print?
console.log([10, 9, 1, 100].sort());
  1. [ 1, 10, 100, 9 ]
  2. [ 10, 9, 1, 100 ]
  3. [ 1, 9, 10, 100 ]
  4. [ 100, 10, 9, 1 ]
Show the answer

[ 1, 10, 100, 9 ]

With no comparison function, sort compares the items as strings, and "100" comes before "9" because "1" is less than "9". Pass (a, b) => a - b for numeric order.

A map to keep

PythonJavaScript
print(a, b)console.log(a, b)
f"{x} items"${x} items between backticks
Nonenull (on purpose) or undefined (missing)
=====
[f(x) for x in xs if g(x)]xs.filter(g).map(f)
for x in xs:for (const x of xs)
d.get(k, 0)d[k] ?? 0
json.loads(s)JSON.parse(s)

Two habits carry the rest: declare with const unless the name must change, and when something surprises you, print it with console.log and its type with typeof. The next lesson adds the part of JavaScript with no direct Python twin in everyday code: everything that waits, from timers to network calls.

In your own words
Name three JavaScript traps a Python programmer meets.

Write a sentence or two, then compare it with a good answer in the lesson.

Practice what you just read

  • a practice exercise that checks your code
  • a 6-question quiz
  • 6 review cards for spaced repetition

Create a free account

Try a quiz question

Which declaration should you reach for first in modern JavaScript?

  1. const
  2. let
  3. var
  4. No keyword, as in Python

Answer it at the end of the lesson to see if you're right, and why.

Before this lesson