A data structure that always returns a new value when the old one is getting modified.
Hence, the data structures are immutable.
//mutable
var a = 10;
a = 10 * 2
//immutable
var a = 10;
var b = a * 2;
//mutable
var a = 10;
a = 10 * 2
//immutable
const a = 10;
const b = a * 2;
var changeable = 1;
function bad (n, fn) {
changeable = changeable * 2;
return fn(changeable, n);
}
bad(1, multiply) // 2
bad(1, multiply) // 4
var changeable = 1;
function bad (n, fn) {
changeable = changeable * 2;
changeable = unknown(changeable);
return fn(changeable, n);
}
bad(1, multiply) //16
bad(1, multiply) // 253
- Same inputs, same output
- Every single time the function is being called
- Regardless of outside changes
Pssh, why do I need to care about that?
(why-is-this-important-ception)
- Guarantee the result is always what you expected
- No side effects
- Reduce #s of unit tests needed
- Fewer bugs
A data structure that always returns a new value when the old one is getting modified.
Hence, the data structures are immutable.
Only when the data can be mutated
- A dialect of Lisp
- Immutable Data Structure
- Memory Sharing
(def v [1 2 3]) -> [1 2 3]
(conj v 4) -> [1 2 3 4]
v -> [1 2 3]
> let a = toList [1, 2, 3]
> let y = insertAt 1 3 a
> a
Cons (1) (Cons (2) (Cons (3) (Nil)))
> y
Just (Cons (1) (Cons (3) (Cons (2) (Cons (3) (Nil)))))
Those sound awesome,
but I'm still using JavaScript
const regularMap = new Map()
regularMap.set(1, “hi”) // Map {1 => "hi"}
regularMap.set(2, “bye”) // Map {1 => "hi", 2 => "bye"}
regularMap.size // 2
const immuMap = Immutable.Map({1 : “hi”})
const immuMap2 = immuMap.set({2 : “bye”})
immuMap2.size // 2
immuMap.size // 1
const nested = Immutable.fromJS({z:{b:{y:[35,2,42]}}})
-- nested: {'z': {'b': {'y': [35, 2, 42]}}}
nested.set('z', 4)
-- nested: {'z':{'b':{'y':[35,2,42]}}}
const nestedTwo = nested.set('z', 4)
-- nestedTwo: {'z': 4}
Angular Immutable:
https://github.com/mgechev/angular-immutable
Ok...but what if I don't like to import additional libraries
Let & Const
- Block scoped
- No more hoisting
- Const values can't be changed
- (there are exceptions)
function varExample() {
var a = 1
if (a === 1) {
var a = 2
}
console.log('add has a: ' + a)
}
function letExample() {
'use strict'
let b = 1
if (b === 1) {
let b = 2
}
console.log('add2 has b: ' + b)
}
varExample() // 2
letExample() // 1
function constExample() {
const a = 1;
a = 2; // Attempting to override ‘a’ which is a constant
console.log('add has a: ' + a);
}
function add() {
const a; // const ‘a’ is initialized to ‘undefined’
console.log('add has a: ' + a);
}
- Const values can't be changed
const foo = {}
foo.bar = 1
console.log(foo.bar) // 1
let xs = ['a', 'b', 'c', 'd', 'e']
xs.splice(0, 2) // ['a', 'b']
xs // ['c', 'd', 'e']
let ys = ['a', 'b', 'c', 'd', 'e']
ys.slice(0, 2) // ['a', 'b']
ys // ['a', 'b', 'c', 'd', 'e']
function increment (person) {
person.age += 1
return person
}
function getOlder(person) {
return Object.assign(
{},
person,
{age: person.age + 1}
)
}
function getOlder({age, ...other}) {
return {age: age + 1, ...other}
}
function randomPlus (n) {
return n + Math.random() * 100
}
Things that worked on Friday but no longer on Monday
Use recursion instead of for/while loops
function sum (n) {
let result = 0
for (let i = n; i >= 1; i--) {
result += i
}
return result
}
function sum (n) {
if (n === 1) return n
return n + sum(n - 1)
}