Skip to main content

Menu

System onlineAI Tutorials / 2026

AI Tutorials
Knowledge search

Recent · Popular · Tutorials

  • dart3 tutorials
  • java1 tutorial
  • Javascript3 tutorials
  • Node.js Introduction2 tutorials
  • dartdart · General · In depth
  • JavascriptJavascript · Advanced · In depth
  • JavascriptJavascript · Advanced · Mid
  • JavascriptJavascript · Advanced · Short

Find a tutorial

Tell the assistant what you want to learn. It suggests published chapters.

For example: “I want to learn Rust ownership from the start.” The conversation is kept only in this tab.

0 / 2,000 characters

Enter to send, Shift+Enter for a new line. Do not include personal information.

Chapter 1

Values and Types

Advanced framing: you already read JavaScript fluently. This chapter covers the semantic sharp edges through closures and `this`.
Level: AdvancedLength: Short1 min read

Read at another depth

Values and Types

Advanced framing: you already read JavaScript fluently. This chapter covers the semantic sharp edges through closures and this.

Values and Scope

JavaScript has seven primitives (number, string, boolean, null, undefined, symbol, bigint) and everything else is an object. Primitives are immutable; binding them with const freezes the binding, not the value.

Code example in javascript
const a = { n: 1 };
a.n = 2;        // fine: const freezes the binding
// a = {};      // TypeError

var is function-scoped and hoisted-initialized to undefined; let/const are lexically block-scoped with a temporal dead zone. Prefer let/const; var survives mainly in legacy code and its hoisting interaction with closures in loops.

Coercion and Equality

== performs abstract equality (coercion); === does not. Internal algorithms matter: Object.is distinguishes -0 from 0 and treats NaN as equal to itself — the correct primitive for algorithms like Array.prototype.indexOf on sentinel values.

Code example in javascript
0 == '';        // true
0 === '';       // false
NaN === NaN;    // false
Object.is(NaN, NaN); // true
+0 === -0;      // true
Object.is(+0, -0);   // false

Control Flow and Functions

switch uses strict comparison with fall-through; for...in enumerates keys (including inherited enumerables), for...of iterates via the iterator protocol. Hoisting differs by form: declarations are hoisted wholly; expressions and arrows are not.

Code example in javascript
function makeCounter() {
  let count = 0;
  return function () { count += 1; return count; };
}
const next = makeCounter();
console.log(next()); // 1
console.log(next()); // 2

The closure retains count — a live binding to the creating scope, which is also the main memory-retention hazard (see the memory chapter).

this Binding

this is resolved at call time, not definition time: implicit receiver (obj.m()), default (undefined in strict mode, global otherwise), explicit (call/apply/bind), and new binding. Arrow functions have no this — they close over it lexically, which makes them ideal callbacks and unusable as methods or constructors.

Code example in javascript
const g = {
  name: 'Ada',
  hi() { return `hi ${this.name}`; },
  hiArrow: () => `hi ${globalThis.name}`, // wrong receiver
};
console.log(g.hi()); // hi Ada

Exercise

Why does the classic for (var i...) + setTimeout loop log the final value for every callback, while let logs increasing values?

Show answer

var i is one function-scoped binding shared by every closure; let creates a fresh per-iteration binding, so each closure captures its own copy.

Spotted a mistake, or code that does not work?

Report an issue

Chapter: Values and Types

0 / 2,000 characters

Plain text, for example: the second code sample does not compile. Do not include personal information.

You can't do that