26일차 - javascript (다중 매개변수와 다중 반환값, spread, 스코프와 var키워드의 문제점, let, const)

Yohan·2024년 3월 27일
0

코딩기록

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

3-3. 함수 기초

다중 매개변수와 다중 반환값

  • 만약 n개의 정수 합을 구해주는 함수를 만들어야 한다면
    파라미터에 집합자료형(배열, 객체)을 전달
function addAll(numbers) {
  var total = 0;
  for (var n of numbers) {
    total += n;
  }
  return total;
}

var r1 = addAll([1, 2, 3, 10, 15, 20]);
console.log(`r1 : ${r1}`);

spread 문법

  • ... 활용
// ES6 - spread문법
function addAllES6(...numbers) {
  console.log(numbers);
  var total = 0;
  for (var n of numbers) {
    total += n;
  }
  return total;
}

var r2 = addAllES6(10, 20, 30);
console.log(`r2 : ${r2}`);
  • spread는 여러번 불가, 한 번만 사용 가능 !
// 불가능
function addAllES6(...numbers, ...others) {
	//...
}
// 가능
function addAllES6(first, second, ...numbers) {
	//...
}
// 불가능
function addAllES6(first, second, ...numbers, others) {
	//...
}

다중 반환값

  • 함수의 반환값은 언제나 하나! (불변)
    -> 다중 반환값을 하려면 여러개를 하나로 만들 생각 (집합자료형 활용)
  • 참고
    • 변수를 재사용 할 것이 아니면 굳이 정의 할 필요 없음
    • 미리 만들어놓았던 함수가 있으면 재사용 가능
// 순서에 상관없이 출력해야 편하기 때문에 배열 대신 객체 선택

function arithmeticOperate(n1, n2) {
  // var addResult = n1 + n2;
  // var subResult = n1 - n2;
  // var multiResult = n1 * n2;
  // var divResult = n1 / n2;

  // return addResult, subResult; 불가능
  return {
    add: add2(n1, n2), // add: addResult, 위에 있는 함수 재활용 가능
    sub: n1 - n2, // 변수를 재사용 할 것이 아니면 굳이 정의 할 필요 X
    multi: n1 * n2,
    div: n1 / n2,
};
}

var r3 = arithmeticOperate(20, 10);
// console.log(`r3: ${r3}`);

console.log(`덧셈결과: ${r3.add}`);
console.log(`곱셈결과: ${r3.multi}`);
console.log(`뺄셈결과: ${r3.sub}`);
console.log(`나눗셈결과: ${r3.div}`);


var r4 = arithmeticOperate(5, 3).multi;
// var r4 = arithmeticOperate(5, 3)[1]; // 배열 문법이라 X
  • 퀴즈
/*
  Q. n개의 정수를 전달하면 해당 정수들의 총합과 평균을 
     반환하는 함수 calcNumbersTotalAndAverage를 작성하세요.
*/

function calcNumbersTotalAndAverage(...numbers) {
  var total = 0;
  var avg = 0;

  for (var n of numbers) {
    total += n;
  }
  avg = total / numbers.length;
  return {
    total: total, // ES6문법에 의해 total,
    avg: avg 	  // 			   avg, 라고 써도 무방
  };
}

var result = calcNumbersTotalAndAverage(90, 80, 100, 90); //360과 90이 리턴되어야 함!
console.log(`총합: ${result.total}, 평균: ${result.avg}`);

함수의 재사용성

const NOT_FOUND = -1;

// 배열 안에 특정 요소의 인덱스를 찾아 반환하는 함수
function myIndexOf(array, searchElement) {
  for (var i = 0; i < array.length; i++) {
    if (searchElement === array[i]) {
      return i;
    }
  }
  return NOT_FOUND;
}

function myIncludes(array, searchElement) {

  // var idx = myIndexOf(array, searchElement);
  // return idx !== -1;
  return myIndexOf(array, searchElement) !== NOT_FOUND;
}

var foods = [
  '족발',
  '피자',
  '파스타',
  '김치찌개'
];

var idx = myIndexOf(foods, '파스타');
console.log(`index: ${idx}`);

var flag = myIncludes(foods, '족발');
console.log(`flag: ${flag}`);
  • const NOT_FOUND = -1; 처럼 -1 대신 무슨 말인지 쉽게 알아볼 수 있게 해주는 변수로 저장해두면 코드를 볼 때 쉽다.
  • myIncludes함수를 return으로 myIndexOf함수를 재사용한 것을 볼 수 있다. 이처럼 함수를 잘 활용하여 재사용하는 방법을 연습해보면 좋다.

3-4. 스코프와 var키워드의 문제점

변수사용범위

  • 전역 스코프와 전역 변수 (global scope)
    • 코드의 가장 바깥쪽 영역에서 선언된 변수, 전역 변수는 코드 전체
      의 전역 스코프에서 참조가 가능
    • 전역 변수는 코드 모든부분에서 사용 가능
  • 지역 스코프와 지역 변수 (local scope)
    • 지역 변수는 자신이 선언된 지역과 하위 지역(중첩 함
      수)에서만 참조 가능
      -> 즉, 지역 변수는 자신의 지역 스코프와 하위 지역 스코프에서만 유효
    • 전역 변수와 지역 변수의 이름이 같을 경우 함수 내부에선 지역 스코프를 먼저 참조 (우선 참조)
    • 지역변수는 함수 안에서만 사용가능, return 하면 함수 밖에서도 사용 가능 !!
  • 중첩 함수 : 함수 안에 함수를 정의
  • 헬퍼 함수: 바깥쪽 함수 전용함수
// 중첩 함수 : 함수 안에 함수를 정의
function outer(m) {
  var n = 'outer local n';
  var v = 'outer local v';
  console.log(n);
  console.log(v);
  console.log(m);

  // 헬퍼 함수: 바깥쪽 함수 전용함수
  function inner() {
    console.log(n);
    var m = 'inner local m'; // 바깥쪽 m보다 먼저 사용
    console.log(m);
  }
  inner();
}

outer('outer param m');

// 출력
// outer local n
// outer local v
// outer param m
// outer local n
// inner local m

var키워드의 문제점

  1. 변수의 중복선언을 암묵적으로 허용
  2. 블록 레벨 스코프를 지원하지 않는다!
  • 블록 밖에서는 x가 1로 되었으면 좋겠지만 블록 레벨 스코프를 지원하지 않기 때문에 10이 출력
  1. 호이스팅 문제: 선언위치와 관계없이 참조가능 (var를 사용하면 늦게 선언해도 참조가 돼서 문제발생)

let

  • let 키워드로 선언한 변수는 모든 코드 블록(함수, if문, for문, while문, try/catch문 등)을 각각의 지역 스코프로 인정하는 블록 레벨 스코프를 지원

const

  • 선언과 할당을 한꺼번에 해야함
  • 불변하는 것들을 const로 선언 (상수)
  • 객체는 const로 선언하는 것이 좋음! 단, 프로퍼티는 변경가능
  • 배열도 const로 선언하는 것이 좋음! (배열은 객체의 일부이기 때문에)
    -> 증거, 배열의 type은 object이다.

정리

profile
백엔드 개발자
post-custom-banner

0개의 댓글