Closures, call, bind, apply, spread
//Closures can improve memory efficiency
function heavyDuty() {
const bigArray = new Array(7000).fill('Task');
console.log('Created');
return bigArray[index];
}
//bigArray will be initialized 3 times
HeavyDuty(340);
HeavyDuty(557);
HeavyDuty(342);
function heavyDuty2() {
const bigArray = new Array(7000).fill('Task');
console.log('Created again');
return function(index) {
return bigArray[index];
}
}
//bigArray will be initialized only once
const getHeavyDuty = heavyDuty2();
getHeavyDuty(340);
getHeavyDuty(557);
getHeavyDuty(342);
//Eample od Closure
function generator(input) {
return function() {
return input * 2;
}
}
var calc = generator(500);
console.log(calc());
//Example of Closures
function callMe() {
const name = 'Peter';
setTimeout(function() {
console.log(name)
}, 3000);
}
callMe();
//Example of Closures
function name(name) {
return function name2(name2) {
return function name3(name3) {
console.log(`${name} ${name2} ${name3}`);
}
}
}
name('Peter')('Steven')('Arthur');
// Example of Closure
const multiply = (num1) => (num2) => num1 * num2
//Above example is equivalent of
const multiply = function(num1) {
return function(num2) {
return num1 * num2;
}
}
const arr = [1,2,3,4];
for(var i=0; i<arr.length; i++) {
setTimeout(function() {
console.log(`Round ${i}`);
});
} //This will give output Round 4 Round 4 Round 4 Round 4
//To fix it we can change "var" in for loop to "let". It will add scope to every iteration
const arr = [1,2,3,4];
for(let i=0; i<arr.length; i++) {
setTimeout(function() {
console.log(`Round ${i}`);
});
}
const points = [
[4, 5],
[1, 8],
[8, 12],
];
points.map( ([x, y]) => {
return {x, y}; //returns [{x: 4, y: 5}, {x: 1, y:8}, {x: 8, y:12}]
});
//Call
var john = {
name: 'John',
age: 26,
job: 'teacher',
presentation: function (style, timeOfDay) {
if(style === 'formal') {
console.log('Good' + timeOfDay + ', Ladies and gentlemen. I\'m' + this.name + ', I\'m ' + this.job);
} else if (style === 'friendly') {
console.log('Hey! What\'s up? I\'m ' + this.name + ', I\'m a ' + this.job + ' and I\'m ' + this.age + ' years old. Have a nice ' + timeOfDay + '.');
}
}
}
var emily = {
name: 'Emily',
age: 35,
job: 'designer'
};
john.presentation('formal', 'morning');
john.presentation.call(emily, 'friendly', 'afternoon');
//Apply
//Apply is the same as call but expects parameters in an array
//Bind
//Bind function assign the function that we call to a variable and we can preset some arguments in advance
var johnFriendly = john.presentation.bind(john, 'friendly');
johnFriendly('morning');
johnFriendly('night');
var emilyFormal = john.presentation.bind(emily, 'formal');
emilyFormal('afternoon');
// Another example of bind
var years = [1990, 1965, 1937, 2005, 1998];
function arrayCalc(arr, fn) {
var arrRes = [];
for (var i = 0; i < arr.length; i++) {
arrRes.push(fn(arr[i]));
}
return arrRes;
}
function calculateAge(el) {
return 2016 - el;
}
function isFullAge(limit, el) {
return el >= limit;
}
var ages = arrayCalc(years, calculateAge);
var fullJapan = arrayCalc(ages, isFullAge.bind(this, 20));
console.log(fullJapan);
state = {
contacts: [
{
id: 1,
name: 'John Doe',
email: 'jdoe@gmail.com',
phone: '555-555-5555'
},
{
id: 2,
name: 'Karen Williams',
email: 'karen@gmail.com',
phone: '555-555-5555'
},
{
id: 3,
name: 'Henry Johnson',
email: 'henry@gmail.com',
phone: '555-555-5555'
}
]
};
const newContact = {
id: 5,
name: 'Peter',
email: 'peter@email.com',
phone: '12355489556'
}
//Removing elements from object
/* const { contacts } = state;
const newState = {
contacts,
contacts: state.contacts.filter(contact => contact.id !== 1)
} */
//Adding new element to an object
const newState = {
...state,
contacts: [newContact, ...state.contacts]
}
console.log(newState);
const gradeCalc = function (score, totalScore) {
if (typeof score !== 'number' || typeof totalScore !== 'number') {
throw Error('Please provide numbers only')
}
const percent = (score / totalScore) * 100
let letterGrade = ''
if (percent >= 90) {
letterGrade = 'A'
} else if (percent >= 80) {
letterGrade = 'B'
} else if (percent >= 70) {
letterGrade = 'C'
} else if (percent >= 60) {
letterGrade = 'D'
} else {
letterGrade = 'F'
}
return `You got a ${letterGrade} (${percent}%)!`
}
try {
const result = gradeCalc(9, true)
console.log(result)
} catch (e) {
console.log(e.message)
}