함수는 1급 객체
이다.
전역 객체
를 가리킨다.function func() {
return this;
}
호출된 객체
(자기자신)를 가리킨다.const obj = {
method(){
return this;
}
}
생성될 인스턴스
를 가리킨다.function Func() {
return this;
}
arguments
라고 한다. (Actual Parameter)parameters
라고 한다. (Formal Parameter)function example(parameter) {
console.log(parameter); // Output = foo
}
const argument = "foo";
example(argument);
인자가 많다고 무조건 나쁜 것은 아니고, 맥락을 파악하기 쉬워야 한다.
function createCar(name, brand, color, type){
return {
name,
brand,
color,
type,
}
}
function createCar(name, { brand, color, type }){
if(!name) {
throw new Error('name is a required');
}
}
함수를 안전하게 사용하는 방법 -> 기본값 설정해주기
= {}
부분은 아무 값도 들어오지 않았을 때 {}로 설정하는 것이다.function createCarousel({ margin = 0, center = false, navElement = 'div' } = {}) {
return {
margin,
center,
navElement
};
}
const required = (argName) => {
throw new Error('required is' + argName);
}
function createCarousel({ items = required('items'), margin = 0, center = false, navElement = 'div' } = {}) {
return {
margin,
center,
navElement
};
}
function sumTotal(initValue, ...args){
console.log(initValue); // 100
return args.reduce((acc,cur) => acc + cur)
}
sumTotal(100, 1, 2, 3, 4, 5);
void 값을 return 하는 것은 좋지 않다.
-> 반환하는 값이 있을 때만 return 하기!
function handleClick(){
return setState(false); // undefined를 반환함.
}
function showAlert(message){
return alert(message); // undefined를 반환함.
// alert(message) 그냥 이렇게 쓰면 된다.
}
화살표 함수는 렉시컬 스코프를 가진다.
const user = {
name: 'poco',
getName: () => {
return this.name;
}
}
user.getName(); // undefined
화살표 함수로 만든 함수는 생성자로 사용할 수 없다.
const Person = (name, city) => {
this.name = name;
this.city = city;
}
const person = new Person('poco', 'korea');
function register(){
const isConfirm = confirm('회원가입에 성공했습니다.')
if(isConfirm) {
redirectUserInfoPage();
}
}
function login(){
const isConfirm = confirm('로그인에 성공했습니다.')
if(isConfirm) {
redirectIndexPage();
}
}
아래처럼 메세지와 콜백함수를 받도록 리팩토링 할 수 있다.
function confirmModal(message, cbFunc){
const isConfirm = confirm(message);
if(isConfirm && cbFunc) {
cbFunc();
}
}
부작용을 일으키지 않는 함수.
(콘솔에 값 나타내지 않기, 비동기 처리하지 않기 등)
변수를 매개변수로 받지 않고 밖에 선언되어 있어서 영향을 받음.(예측 불가)
let num1 = 10;
let num2 = 20;
function impureSum1(){
return num1 + num2; // num1, num2가 제어되지 않음.
}
function impureSum2(newNum){
return num1 + newNum; // num1이 제어되지 않음.
}
변수를 전부 매개변수로 받아 예측 가능하도록 만든다.
function pureSum(num1, num2){
return num1 + num2; // num1, num2가 제어되지 않음.
}
배열/객체를 변경하면 기존 값이 변경되기 때문에 새로운 배열/객체를 생성해서 반환해야 한다.
(primitive type과 reference type의 차이)
const obj = { one: 1 };
function changeObj(targetObj){
targetObj.one = 100;
return targetObj;
}
changeObj(obj); // { one: 100 }
obj; // { one: 100 }
리팩토링
const obj = { one: 1 };
function changeObj(targetObj){
targetObj.one = 100;
return { ...targetObj, one: 100 };
}
changeObj(obj); // { one: 100 }
obj; // { one: 1 }
function add(num1){
return function sum(num2){
return num1 + num2;
}
}
const addOne = add(1); // sum 함수를 가지고 있음. -> 아직 실행x
addOne(2); // 3
// const addOne = add(1)(2); 위와 똑같음.
클로저 활용 예시
const arr = [1,2,3,'A','B','C'];
function isTypeOf(type){
return function (value){
return typeof value === type;
}
}
const isNumber = isTypeOf('number');
const isString = isTypeOf('string');
arr.filter(isNumber);
arr.filter(isString);