BooleannullundefinedStringNumberArrayFunctionObjectwhen you assign non-primitive types to variables, javascript references them, therefore changes to the reference will change all other variables referencing it.
let arr = [1]
let arr2 = arr
console.log(arr) // [1]
console.log(arr2) // [1] -> this is a reference
arr.push(2)
console.log(arr) // [1,2]
console.log(arr2) // [1,2] -> and it got affected by arr.push()= to assign variables for use in functionslet one = 1
let two = 2
function add(x, y) {
return x + y
}
add(one, two)in the above code, the function add does this internally:
let x = one // thereby copying the value, NOT referencing it
let y = twotherefore functions that take primitives as parameters are pure functions
it does NOT copy values, but references them. therefore when you update values inside the parameters, e.g.:
param.push()param.prop = "new stuff"the original gets changed (usually this is not your intention)
example from the article:
function changeAgeImpure(person) {
person.age = 25
return person
}
var alex = {
name: 'Alex',
age: 30,
}
var changedAlex = changeAgeImpure(alex)
console.log(alex) // -> { name: 'Alex', age: 25 }
console.log(changedAlex) // -> { name: 'Alex', age: 25 }A function that takes in an Object, however, can mutate the state of its surrounding scope. If a function takes in an array reference and alters the array that it points to, perhaps by pushing to it, variables in the surrounding scope that reference that array see that change. After the function returns, the changes it makes persist in the outer scope. This can cause undesired side effects that can be difficult to track down. ref
Array.map and Array.filter are written as pure functionsto do the same thing as a pure function:
function changeAgePure(person) {
var newPersonObj = JSON.parse(JSON.stringify(person))
newPersonObj.age = 25
return newPersonObj
}
var alex = {
name: 'Alex',
age: 30,
}
var alexChanged = changeAgePure(alex)
console.log(alex) // -> { name: 'Alex', age: 30 }
console.log(alexChanged) // -> { name: 'Alex', age: 25 }function changeAgeAndReference(person) {
person.age = 25 // this affects the passed in object
person = {
name: 'John',
age: 50,
} // this is a brand new object that is reassigned to the variable 'person'
return person // what gets passed out is the new object (John)
// while the original object also has its age altered
}
var personObj1 = {
name: 'Alex',
age: 30,
}
var personObj2 = changeAgeAndReference(personObj1)
console.log(personObj1) // -> { name: "Alex", age: 25 }
console.log(personObj2) // -> { name: "John", age: 50}the author explains it in a very clear way with this equivalent code
var personObj1 = {
name: 'Alex',
age: 30,
}
var person = personObj1
person.age = 25
person = {
name: 'john',
age: 50,
}
var personObj2 = person
console.log(personObj1) // -> { name: 'Alex', age: 25 }
console.log(personObj2) // -> { name: 'John', age: '50' }and:
The only difference is that when we use the function, person is no longer in scope once the function ends.