Just JavaScript

https://justjavascript.com

The JavaScript Universe

The Abramov's mental model represents primitive values as distant stars, floating farthest form our code. We can point to them, but they will always stay where they are, unchanged.

Values

From 1 to 7, they are the primitive values.

Note: things like arrays, dates and regular expressions are fundamentally Objects.

Inspect type of something with typeof

Note: typeof(null) == 'object'. It's a known historical bug in the language. Here's an explanation: https://2ality.com/2013/10/typeof-null.html

I like to look the image below and think "the further a type is from the center, the less manipulable it is"

Just JavaScript - celestial spheres.png

Expressions always return a value.

Values and Variables

Primitive values are immutable (objects and functions are mutable).

Code where the results is not what is expected:

let reaction = 'yikes'
reaction[0] = 'l'
console.log(reaction) // "yikes"

Variables are not values. Variables point to values.

let pet = 'Narwhal';
pet = 'The Kraken';
console.log(pet); // "The Kraken"

In JavaScript variables don't have types, only values do.

Rules of Assignment

The right side of an assignment must be an expression, so it always result in a value.

// "connects" x with 10
let x = 10;

// x is evaluated to 10
// connects y with 10
let y = x;

// connects x with 0
x = 0;

// x is connected with 0
// y is connected with 10

Note that y = x did not mean point y to x. We can’t point variables to each other! Variables always point to values.

When we call a function, we're always passing the value.

function double(x) {
  x = x * 2;
}

let money = 10;

// money is an expression resulting in 10
// therefore we're passing the value 10 to the function
double(money);

console.log(money); // 10

If the the value being passed is a primitive value, it can't be changed. However, if it's a mutable value (like an array, which is an Object) it can be changed!

Primitive Values

undefined

undefined is a type and a value.

It represents the concept of an unintentionally missing value.

When you declare a variable and don't assign any value to it, then it points to the undefined value, by default.

null

null is also a type and a value.

Note

null is the only value of its own type, but it's also a liar, as it pretends to be an object:

console.log(typeof(null)); // "object"

You must understand that it's a lie! null is a primitive value, and is NOT an object at all.

Unfortunately, typeof(null) is a historical accident that we'll have to live with forever. 🙁

null is used for intentionally missing values.

booleans

Only two boolean values: true and false.

numbers

console.log(0.1 + 0.2 === 0.3); // false
console.log(0.1 + 0.2 === 0.30000000000000004); // true

As we move from 0 in either direction, we start losing precision. At some point, even two closes JavaScript numbers stay further apart than by 1:

onsole.log(Number.MAX_SAFE_INTEGER);     // 9007199254740991
console.log(Number.MAX_SAFE_INTEGER + 1); // 9007199254740992
console.log(Number.MAX_SAFE_INTEGER + 2); // 9007199254740992 (again!)
console.log(Number.MAX_SAFE_INTEGER + 3); // 9007199254740994
console.log(Number.MAX_SAFE_INTEGER + 4); // 9007199254740996
console.log(Number.MAX_SAFE_INTEGER + 5); // 9007199254740996 (again!)

learn more about floating-point math

special numbers

examples

let scale = 0;
let a = 1 / scale; // Infinity
let b = 0 / scale; // NaN
let c = -a; // -Infinity
let d = 1 / c; // -0

// fun-fact
console.log(typeof(NaN)); // "number"

BigInt

Not much used...

let alot = 9007199254740991n; // n at the end makes it a BigInt!
console.log(alot + 1n); // 9007199254740992n
console.log(alot + 2n); // 9007199254740993n
console.log(alot + 3n); // 9007199254740994n
console.log(alot + 4n); // 9007199254740995n
console.log(alot + 5n); // 9007199254740996n

Strings

Three ways to write strings: "double quotes", 'single quotes', `backticks`.

console.log(typeof("こんにちは")); // "string"
console.log(typeof('こんにちは')); // "string"
console.log(typeof(`こんにちは`)); // "string"

Strings are NOT objects.

All strings have a few built-in properties, but that doesn't mean they are objects!

let cat = 'Cheshire'
console.log(cat.length)
console.log(cat[0])
console.log(cat[1])

You can't assign anything to cat[0]. Strings are primitives, and all primitives are immutable.

Objects and Functions

Non-primitive types: types that let us make our own values.

Object are not primitive values, it means they're mutable.

Every time we use the {} object literal, we create a brand new object value:

let shrek = {};
let donkey = {};

Just JavaScript - new objects.png

Note how this 👆 is different from what happens with primitive values.

An object literal creates a brand new distinct object value

// in this loop we're passing the very
// same value, `2`, to console.log
for (let i = 0; i < 5; i++) {
  console.log(2)
}

// in this loop we're passing a completely
// distinct object value in each iteration
for (let i = 0; i < 5; i++) {
  console.log({}) // <-- creates a brand new object
}

Technically, functions are objects in JavaScript. We’ll keep treating them as a separate fundamental type because they have unique capabilities compared to regular objects. But, generally speaking, if you can do something to an object, you can also do that to a function too. They are very special objects

Important

Primitive values (strings, numbers, etc...) have always existed in our universe. For example, writing 2 or "hello" always “summons” the same number or a string value. Objects and functions behave differently and allow us to generate our own values. Writing {} or function() {} always creates a brand new, different value. This idea is crucial to understanding equality in JavaScript.

Equality of Values

Kinds of equality:

Fun

Despite the Object in the method name, Object.is is not specific to objects.

Exceptions:

Important

NaN is the only value that's not equal to itself.

Since NaN === NaN is always false, never check if a variable is NaN through strict equality. Use this insteaad: Number.isNaN(variable)

From https://dorey.github.io/JavaScript-Equality-Table/unified/

Just JavaScript - equality table.png

Properties

This example shows how effective is our mental model to detect potential unexpected bugs:

// Sherlock Holmes live in london
let sherlock = {
  surname: 'Holmes',
  address: { city: 'London' }
};

// John Watson go live with Mr. Holmes
let john = {
  surname: 'Watson',
  address: sherlock.address
};

// then Watson decided to change his name and live in Malibu
john.surname = 'Lennon'
john.address.city = 'Malibu'

// now let's check
console.log(john.surname); // "Lennon"
console.log(john.address.city); // "Malibu"
console.log(sherlock.surname); // "Holmes"
console.log(sherlock.address.city); // "Malibu"
// 👆 this is unexpected! -------------👆

Unlike variables, properties belong to a particular object.

In our JavaScript mental model, both variables and properties act like "wires".

Importantly, properties don't contain values - they point to them!
Just JavaScript - object wires.png

Simplified set of rules that JavaScript uses when parsing an expression like sherlock.boat:

  1. Figure out the value of the part before the dot .
  2. If that value is null or undefined, throw an error immediately.
  3. Check whether a property with that name exists on our object:
    1. If it exists, answer with the value this property points to.
    2. If it doesn't exist, answer with the undefined value.

Mutation

No Nested Objects

let sherlock = {
  surname: 'Holmes',
  address: { city: 'London' }
};

In the code above, we have not one, but two completely separate objects. Two pairs of curly braces mean two objects.

Just JavaScript - sherlock object.png

Important

Objects might appear "nested" in code, but in our universe each object is completely separate. An object cannot be "inside" of another object!

let vs const

Remember: const prevents variable reassignment, not object mutation.

const shrek = { species: 'ogre' };

shrek = fiona; // TypeError

shrek.species = 'human';
console.log(shrek.species); // 'human'

Prototypes

link