28일차 - javascript (sort, 배열구조분해할당, 클로저)

Yohan·2024년 3월 29일
0

코딩기록

목록 보기
38/156
post-custom-banner

sort()

  • 배열 데이터를 정렬할 때 사용
  • 아래와 같이 그냥 사용하게되면 제대로 정렬되지 않음 (아스키 코드에 따라 정리되기 때문에)
const nums = [6, 11, 3 ,7, 9, 10, 2, 4];

// nums.sort();
// console.log(nums); // [ 10, 11, 2, 3, 4, 6, 7, 9 ]

오름차순, 내림차순

  • a-b가 양수이면 오름차순, 반대면 내림차순이 된다.
nums.sort((a, b) => a - b); // 오름차순
console.log(nums);

nums.sort((a, b) => b - a); // 내림차순
console.log(nums);

오름차순, 내림차순 활용

const userList = [
  {
    account: 'abc1234',
    userName: '대길이',
    job: '추노',
    address: '서울',
    hobbys: ['수영', '축구', '테니스'],
    salary: 5400000,
    age: 35,
  },
  {
    account: 'banana',
    userName: '빠나나',
    job: '과일',
    address: '서울',
    hobbys: ['푸드파이팅', '테니스'],
    salary: 9700000,
    age: 18,
  },
  {
    account: 'park1234',
    userName: '주차왕',
    job: '발렛파킹',
    address: '경기',
    hobbys: ['족구', '축구', '테니스', '영화감상'],
    salary: 3900000,
    age: 56,
  },
  {
    account: 'fire',
    userName: '불꽃남자카리스마',
    job: '게이머',
    address: '서울',
    hobbys: ['독서', '테니스'],
    salary: 7900000,
    age: 42,
  },
];

console.log('==============================');

console.log(userList);
console.log('==============================');

// userList.sort((a, b) => a.age - b.age); // 나이 오름차순
// userList.sort((a, b) => b.salary - a.salary); // 급여 내림차순
userList.sort((a, b) =>{
  if (a.name > b.userName) return 1;
  else if (a.name < b.userName) return -1;
  else return 0;
}); // 이름 오름차순
console.log(userList);
  • 이름 같은경우에는 문자열이기 때문에 if문을 통해 숫자 1, -1을 리턴하는 것에 따라 정렬 (1은 양수에 해당하므로 오름차순, -1은 음수에 해당하므로 내림차순)

구조 분해 할당(destructuring)

구조 분해 할당이란 객체나 배열을 다시 기본 데이터로 해체하는 것을 의미

배열구조분해할당 (배열 디스트럭처링)

  • 아래처럼 하나씩 꺼내서 구조분해할 수 있지만 번거로운 단점이 있다.
const userNames = ['김철수', '강감찬', '박영희'];

// userNames에서 각각의 요소들을 다시 변수에 집어넣고 싶다.
// const kim = userNames[0];
// const kang = userNames[1];
// const park = userNames[2];
  • 이럴 때 구조 분해 할당을 사용

// 0번, 1번, 2번이 순서대로 kim, park, hong에 저장
const [kim, park, hong] = arr;

// 0번에 kim이 2번에 hong이 저장
const [kim, , hong] = arr;

구조 분해 할당을 통한 변수 교환

  • 원래는 임시변수가 필요했다.
let first = 10;
let second = 20;

// first 와 second의 값 교환
let temp = first;
first = second;
second = temp;
  • 하지만 구조분해할당을 이용하면 쉽게 가능!
let first = 10, second = 20;
[first, second] = [second, first];
console.log(`first: ${first}, second: ${second}`);

스프레드로 나머지 요소 가져오기

const arr = [1, 3, 5, 7, 9, 11];

const [one, three, ...others] = arr;

console.log(one);    // 1
console.log(three);  // 3
console.log(others); // [5, 7, 9, 11]

스프레드로 배열 안전하게 복사하기 (완전 복사)

  • slice() 도 동일하게 복사됨
  • 중간에 들어가는 것도 가능
const foods = ['감튀', '햄버거', '콜라'];

// const copyFoods = foods.slice(); // 동일
const copyFoods = [...foods];
console.log(copyFoods);

console.log('===================================');
// 중간에 들어가는 것도 가능,
// a.concat(b) => [...a, ...b]
const newFoods = ['육포', ...foods, '닭다리', ...userNames];
console.log(newFoods);

객체구조분해할당 (객체 디스트럭처링)

  • 객체 프로퍼티의 키 값을 통해 추출
const emp = {
    empName: '빡빡이',
    age : 29,
    hireDate: '2014-01-01',
    birthDay: '1995-12-31'
};

const {age, empName, hireDate} = emp;

console.log(`사원의 이름은 ${empName}고 나이는 ${age}이고 입사일자는 ${hireDate}입니다.`);


// 아래 2가지는 동일
  function foo(employee) {
    const {empName, age} = employee;
    console.log(`내 이름은 ${empName}입니다.`);
    console.log(`나이는 ${age}입니다.`);
  }

  function foo(empName, age) {
    const {empName, age} = employee;
    console.log(`내 이름은 ${empName}입니다.`);
    console.log(`나이는 ${age}입니다.`);
  }

프로퍼티 키의 변수 이름을 바꾸고 싶을 경우

  • 객체를 분해하면 프로퍼티의 키 이름이 변수 이름으로 설정되지만 이 때 변수의 이름을 바꿀 수 있음!
  • 변수 이름이 충돌할 때도 있기 때문에 변수 이름을 바꾸는 것을 알아둔다!
  • 변수 이름이 문자열일 때도 변수 이름을 바꿔주어야한다. (''을 쓸 수 없기 때문에)
const emp = {
    empName: '빡빡이',
    age : 29,
    hireDate: '2014-01-01',
    birthDay: '1995-12-31'
};

const {age: a, empName: n, hireDate: h} = emp;
console.log(`사원의 이름은 ${n}고 나이는 ${a}이고 입사일자는 ${h}입니다.`);


const divStyle = {
  'font-size': '18px',
  'background-color': 'red'
};
// ''쓸 수 없으므로 이름을 설정
const { 'font-size': fontSize , 'background-color': bgColor } = divStyle;
console.log(fontSize);
console.log(bgColor);

스프레드로 나머지 요소 가져오기

const emp = {
    empName: '빡빡이',
    age : 29,
    hireDate: '2014-01-01',
    birthDay: '1995-12-31'
};

const {empName, birthDay, ...others} = emp;

console.log(empName);   // '빡빡이'
console.log(birthDay);  // '1995-12-31'
console.log(others);    // { age : 29, hireDate: '2014-01-01' }

스프레드로 객체 안전하게 복사하기 (완전 복사)

const emp = {
    empName: '빡빡이',
    age : 29,
    hireDate: '2014-01-01',
    birthDay: '1995-12-31'
};

const copyEmp = { ...emp };

클로저

  • 클로저에 대해 알기 전에 자바스크립트의 함수는 함수를 리턴할 수 있다 는 점을 알아야함

클로저란?

  • 외부 변수를 기억하고 이 외부 변수에 접근할 수 있는 함수를 의미

클로저가 필요한 이유

// 카운트를 증가시키는 함수
let count = 0; // 전역변수

const increase = () => count++;

console.log(increase()); // 1
console.log(increase()); // 2
count = 999; // 전역변수로 인해 카운트 깨짐
console.log(increase()); //1001
console.log(`count: $${count}`);
  • 전역변수를 지정하게 되면 중간에 count의 값을 수정하게 되면 결과가 변해버림
    -> 전역변수 사용을 자제해야하는 이유이기도 함, 그렇다면 지역변수를 사용한다면 문제는 해결될까?
const increase = () => {
  let count = 0; // 지역변수
  return ++count;
}

// 지역변수이기 때문에 함수 안에서만 호출하고 함수가 끝나면 사라지므로 카운트 안됨
increase(); // 1
increase(); // 1
increase(); // 1
const count = increase();
console.log(`count: $${count}`);
*/
  • 지역변수이기 때문에 함수 안에서만 호출하고 함수가 끝나면 사라지므로 카운트 안됨 !
    -> 위처럼 전역변수, 지역변수 모두 해결할 수 없으므로 클로저를 이용!
const increaseClosure = () => {
  let count = 0; // 지역변수

  return () => ++count;
}

const increase = increaseClosure();

console.log(increase());
console.log(increase());
console.log(increase());
  • 어떤 함수가 내부에 있는 헬퍼 함수를 리턴하게 하는 방법으로 클로저를 구현 !
    -> 이렇게 구현하면 count변수는 함수 외부에서 접근할 수는 없지만 지속적으로 값이 increase에 의해 제어되는 형태로 상태값이 유지되는 효과를 얻을 수 있다 !

즉시 실행 함수

  • 즉시 실행 함수 : 함수를 일회성으로 사용할 목적으로 만드는 함수
  • 즉시 실행 함수를 사용하면 클로저를 좀 더 심플하게 구현할 수 있음
  • 이름없는 함수를 ()로 한 번 덮어주면 됨
const increase_ = (() => {
  let count = 0;
  return () => ++count;
})();

increase_();
increase_();
increase_();

클로저 활용

// count가 따로 적용됨
const increase = (() => {
  let count = 0;
  return () => ++count;
})();

const decrease = (() => {
  let count = 0;
  return () => --count;
})();

console.log(increase()); 1
console.log(increase()); 2
console.log(increase()); 3
console.log(decrease()); -1
console.log(decrease()); -2
console.log(decrease()); -3
  • 아래처럼 count를 return하는 것을 동시에 넣주고 그것을 객체로 return하고 객체분해할당을 통해 함수를 둘 다 적용할 수 있게 해주면 가능!
const countClosure = () => {
  
  let count = 0;
  const increase = () => ++count;
  const decrease = () => --count;

  return { 
    increase,  // increase: increase,
    decrease   // decrease: decrease
  };
};

const { increase, decrease } = countClosure();

console.log(increase());
console.log(increase());
console.log(decrease());
console.log(decrease());
console.log(decrease());

클로저 퀴즈

// createCounter라는 클로저함수를 만드세요
// 파라미터로 전달받은 숫자부터 시작하고 반환받은 헬퍼함수를 작동하면
// 해당 숫자부터 카운트가 증가합니다.

function createCounter(n) {
  // 시작 숫자
  let count = n;
  return function() {
    return ++count;
  }
}

const counterFromFive = createCounter(5);
console.log(counterFromFive()); // 6
console.log(counterFromFive()); // 7
console.log(counterFromFive()); // 8
console.log(counterFromFive()); // 9
console.log(counterFromFive()); // 10


// createCalculator를 호출하면 반환되는 헬퍼함수는 
// 3가지의 기능을 갖고 있는데 add는 더하기 기능을 수행
// substract는 빼기 기능을 수행 getTotal은 현재 값을 가져옴

function createCalculator(){

  let total = 0;
  // createCalculator 함수 안에 add, subtract, getTotal 함수 3개 만듦
  // add와 subtract는 파라미터를 받아야함 숫자가 적용되는 함수라서
  // getTotal은 결과
  const add = (n) => total += n;
  const subtract = (n) => total -= n;
  const getTotal = () => total;

  // 객체를 생성해서 3가지 함수를 객체에 넣고 return 

  return {
    add: add, // add
    subtract: subtract, // subtract
    getTotal, getTotal // getTotal
  };
};


console.log('=============================');

const calculator = createCalculator();
console.log(calculator.add(5)); // 5
console.log(calculator.subtract(2)); // 3
console.log(calculator.add(14)); // 17
console.log(calculator.add(21)); // 38
console.log(calculator.subtract(29)); // 9
console.log(calculator.getTotal()); // 9
profile
백엔드 개발자
post-custom-banner

0개의 댓글