const oneWord = function (str) {
return str.replace(/ /g, '').toLowerCase();
};
/ /g 기억하기! select all of the spaces
const upperFirstWord = function (str) {
const [first, ...others] = str.split(' ');
return [first.toUpperCase(), ...others].join(' ');
};
const transformer = function (str, fn) {
console.log(`Original string : ${str}`);
console.log(`Transformed string: ${fn(str)}`);
console.log(`Transformed by: ${fn.name}`);
};
// 위 함수는 어떻게 string이 transform 되는지 신경쓰지 않는다.
//오직 transform 하는 부분만 신경씀.
//관련 code를 다른 함수들로 abstract함.
//=> created a new level of abstraction
transformer('JavaScript is the best!', upperFirstWord);
//Original string : JavaScript is the best!
//Transformed string: JAVASCRIPT is the best!
//Transformed by: upperFirstWord
transformer('JavaScript is the best!', oneWord);
//Original string : JavaScript is the best!
//Transformed string: javascriptisthebest!
//Transformed by: oneWord
위의 transformer 함수는 Higher-order function이다. why? this function operates at a higher level of abstraction leaving the low level details to this low level functions.
oneWord, upperFirstWord => lover-level functions with lower level abstraction
const high5 = function () {
console.log('✋🏻');
};
document.body.addEventListener('click', high5);
// addEventListener : higher-order function, high5 : callback function
['Jonas', 'Martha', 'Adam'].forEach(high5); //✋🏻가 세번 출력된다.
매우매우 중요) JS uses callbacks all the time why? makes it easy to split up or code into more reusable and interconnected parts, allows us to create abstraction.
const greet = function (greeting) {
return function (name) {
console.log(`${greeting} ${name}`);
};
};
const greeterHey = greet('Hey');
greeterHey('Jonas'); //Hey Jonas
greeterHey('Steven'); //Hey Steven
greet('Hello')('Jonas'); //Hello Jonas
//Arrow function
const greetArr = greeting => name => console.log(`${greeting} ${name}`);
greetArr('Hi')('Jonas'); //Hi Jonas
const lufthansa = {
airline: 'Lufthansa',
iataCode: 'LH',
bookings: [],
book(flightNum, name) {
console.log(
`${name} booked a seat on ${this.airline} flight ${this.iataCode}${flightNum}`
);
this.bookings.push({ flight: `${this.iataCode} ${flightNum}`, name });
},
};
lufthansa.book(239, 'Jonas Schmedtmann'); //Jonas Schmedtmann booked a seat on Lufthansa flight LH239
lufthansa.book(635, 'John Smith'); //John Smith booked a seat on Lufthansa flight LH635
console.log(lufthansa);
// this = lufthansa
const eurowings = {
airline: 'Eurowings',
iataCode: 'EW',
bookings: [],
};
const book = lufthansa.book; // 이와 같은 표기 갸능함 why? JavaScript는 first class function 가지고 있으므로!
//book(23, 'Sarah Williams'); // error why? 이 함수는 a regular function call.
// In a regular function call, the this keywords points to undefined! (strict mode에서)
call은 function의 method
call을 부름으로써 첫번째 인자 eurowings에 book함수 내에 있는 this를 부여한다.
call method는 명확하게 어떤 object를 this로 할 것인지를 명시해주는 역할을 한다.
book.call(eurowings, 23, 'Sarah Williams'); // Sarah Williams booked a seat on eurowings flight EW23
console.log(eurowings);
// bookings : [{flight: "EW 23",name: "Sarah Williams"}] 추가됌!
book.call(lufthansa, 239, 'Mary Cooper');
console.log(lufthansa);
const swiss = {
airline: 'Swiss Air Lines',
iataCode: 'LX',
bookings: [],
};
book.call(swiss, 583, 'MaryCooper');
console.log(swiss);
call과 하는 일은 같음. call과의 차이점 : a list of arguments(ex 583, 'MaryCooper')를 받지 않는다. 그 대신 an array of arguments를 받는다.
modern js 에서 더이상 apply method는 쓰이지 않는다.
const flightData = [583, 'George Cooper'];
book.apply(swiss, flightData);
console.log(swiss);
book.call(swiss, ...flightData); // Modern JS (apply와 똑같음)
bind method는 바로 함수를 부르지 않는다. Instead it returns a new function where this keyword is bind.
const bookEW = book.bind(eurowings); // book 함수를 부르지 않음.
//This will return a new function where this keyword will always be set to Eurowings.
const bookLH = book.bind(lufthansa);
const bookLX = book.bind(swiss);
bookEW(23, 'Steven Williams'); //Steven Williams booked a seat on Eurowings flight EW23
const bookEW23 = book.bind(eurowings, 23);
bookEW23('Jonas Schmedtmann'); //Jonas Schmedtmann booked a seat on Eurowings flight EW23
bookEW23('Martha Cooper'); // Martha Cooper booked a seat on Eurowings flight EW23
//const bookEW23 = book.bind(eurowings, 23, 'Jonas'); 와 같은 형태도 가능
위와 같이 arguments의 일부만 적은 것을 partial application이라고 함.
lufthansa.planes = 300;
lufthansa.buyPlane = function () {
console.log(this);
this.planes++;
console.log(this.planes);
};
lufthansa.buyPlane(); //this = lufthansa / 301
document.querySelector('.buy').addEventListener('click', lufthansa.buyPlane);
// 여기서 this는 .buy element를 가리킨다. event listner에서 callback 함수 내의 this는 element 자체를 가리킨다. this Keyword 매우 동적.
document
.querySelector('.buy')
.addEventListener('click', lufthansa.buyPlane.bind(lufthansa));
// this = lufthansa
means that we can preset parameters.
const addTax = (rate, value) => value + value * rate;
console.log(addTax(0.1, 200));
// this가 따로 없기때문에 null이라 적어줌
const addVAT = addTax.bind(null, 0.23);
console.log(addVAT(100)); //123
const addTaxRate = function (rate) {
return function (value) {
return value + value * rate;
};
};
const addVAT2 = addTaxRate(0.23);
console.log(addVAT2(100)); //123