320x100
320x100

재귀

: 함수가 자기 자신을 호출하는 것

: 큰 목표 작업 하나를 동일하면서 간단한 작업 여러 개로 나눌 때 유용한 프로그래밍 패턴

 

function pow(x, n) {
  let result = 1;

  // 반복문을 돌면서 x를 n번 곱함
  for (let i = 0; i < n; i++) {
    result *= x;
  }

  return result;
}

alert( pow(2, 3) ); // 8

 

 

 

 

 

재귀깊이

function pow(x, n) {
  return (n == 1) ? x : (x * pow(x, n - 1));
}

: 가장 처음 시행하는 호출을 포함한 중첩 호출의 최대 개수

: pow (x, n)의 재귀 깊이는 n

 

 

 

 

 

실행컨텍스트

: 함수 실행에 대한 세부 정보를 담고 있는 내부 데이터 구조

: 실행 중인 함수의 실행 절차에 대한 정보가 저장 되는 자료구조

: 제어 흐름의 현재 위치, 변수의 현재 값, this의 값 등 상세 내부 정보가 저장 됨 

: 함수 호출 1회당 정확히 하나의 실행 컨텍스트가 생성 됨

 

- 함수 내부에 중첩 호출이 있을 경우의 절차

: 현재 함수의 실행이 일시중지

: 중지된 함수와 연관된 실행 컨텍스트는 실행 컨텍스트 스택 이라는 자료구조에 저장

: 중첩 호출 실행

: 중첩 호출이 끝난 뒤 실행 컨텍스트 스택에서 일시 중단한 함수의 실행 컨텍스트를 꺼내오고

  중단한 함수의 실행을 다시 진행

 

 

 

 

 

 

 

 

재귀적 순회

let company = { // 동일한 객체(간결성을 위해 약간 압축함)
  sales: [{name: 'John', salary: 1000}, {name: 'Alice', salary: 1600 }],
  development: {
    sites: [{name: 'Peter', salary: 2000}, {name: 'Alex', salary: 1800 }],
    internals: [{name: 'Jack', salary: 1300}]
  }
};

// 급여 합계를 구해주는 함수
function sumSalaries(department) {
  if (Array.isArray(department)) { // 첫 번째 경우
    return department.reduce((prev, current) => prev + current.salary, 0); // 배열의 요소를 합함
  } else { // 두 번째 경우
    let sum = 0;
    for (let subdep of Object.values(department)) {
      sum += sumSalaries(subdep); // 재귀 호출로 각 하위 부서 임직원의 급여 총합을 구함
    }
    return sum;
  }
}

alert(sumSalaries(company)); // 7700

: 재귀적 순회를 구현한 예시

: 모든 임직원의 급여를 더한 값을 출력

 

 

 

 

 

연결리스트 구조

let list = { value: 1 };
list.next = { value: 2 };
list.next.next = { value: 3 };
list.next.next.next = { value: 4 };
list.next.next.next.next = null;

: 재귀적으로 정의된 자료구조는 자기 자신을 이용해 자료 구조를 정의

 

 

 

 

 

 

나머지 매개변수 ...

: 자바스크립트에서는 함수 정의와 상관없이 함수에 넘겨주는 인수의 개수에 제약이 없음

: 함수를 정의할 때 인수를 2개만 받도록 하고 실제 함수를 호출 할 때 더 많은 인수를

  전달해도 오류가 발생하지 않음

: 그러나 가장 앞 2개의 인수만 사용됨 

: ... 을 사용하면 모든 인수를 전달할 수 있음

 

- ...

: 남은 매개변수들을 모아 배열로 반환함을 의미하는 문법

: 나머지 매개변수는 항상 마지막에 존재해야 함

function sum(a, b) {
  return a + b;
}

alert( sum(1, 2, 3, 4, 5) );
function sumAll(...args) { // args는 배열의 이름입니다.
  let sum = 0;

  for (let arg of args) sum += arg;

  return sum;
}

alert( sumAll(1) ); // 1
alert( sumAll(1, 2) ); // 3
alert( sumAll(1, 2, 3) ); // 6

 

 

 

 

 

 

arguments 객체

: 인덱스를 사용해 인수에 접근할 수 있도록 하는 유사 배열 객체

: 오래된 코드에서 사용되던 문법

: 배열 메서드를 사용할 수 없다는 단점

: 인수 전체를 담기 때문에 나머지 매개변수 처럼 인수의 일부만 사용하는 것도 불가

function showName() {
  alert( arguments.length );
  alert( arguments[0] );
  alert( arguments[1] );

  // arguments는 이터러블 객체이기 때문에
  // for(let arg of arguments) alert(arg); 를 사용해 인수를 펼칠 수 있습니다.
}

// 2, Bora, Lee가 출력됨
showName("Bora", "Lee");

// 1, Bora, undefined가 출력됨(두 번째 인수는 없음)
showName("Bora");

 

 

 

 

 

 

스프레드 문법

: 배열을 통째로 매개변수에 넘기는 방법

let arr = [3, 5, 1];

alert( Math.max(arr) ); // NaN

alert( Math.max(...arr) ); // 5
let arr1 = [1, -2, 3, 4];
let arr2 = [8, 3, -8, 1];

alert( Math.max(...arr1, ...arr2) ); // 8
let arr1 = [1, -2, 3, 4];
let arr2 = [8, 3, -8, 1];

alert( Math.max(1, ...arr1, 2, ...arr2, 25) ); // 25
let arr = [3, 5, 1];
let arr2 = [8, 9, 15];

let merged = [0, ...arr, 2, ...arr2];

alert(merged); // 0,3,5,1,2,8,9,15 (0, arr, 2, arr2 순서로 합쳐집니다.)
let str = "Hello";

alert( [...str] ); // H,e,l,l,o

// Array.from은 이터러블을 배열로 바꿔줍니다.
alert( Array.from(str) ); // H,e,l,l,o

: 문자열, 배열의 요소를 나누어서 반환

: 이터러블 객체에만 사용가능

: 문자열을 객체로 바꿀 때는 유사 배열 객체 및 이터러블 객체까지 지원하는 Array.from을 주로 이용

 

 

 

 

 

스프레드를 이용한 객체 복사

let obj = { a: 1, b: 2, c: 3 };
let objCopy = { ...obj }; // 객체를 펼쳐서 각 요소를 분리후, 매개변수 목록으로 만든 다음에
                          // 매개변수 목록을 새로운 객체에 할당함

// 객체 복사본의 프로퍼티들이 기존 객체의 프로퍼티들과 진짜 같을까요?
alert(JSON.stringify(obj) === JSON.stringify(objCopy)); // true

// 두 객체는 같을까요?
alert(obj === objCopy); // false (참조가 다름)

// 참조가 다르므로 기존 객체를 수정해도 복사본은 영향을 받지 않습니다.
obj.d = 4;
alert(JSON.stringify(obj)); // {"a":1,"b":2,"c":3,"d":4}
alert(JSON.stringify(objCopy)); // {"a":1,"b":2,"c":3}

 

 

 

 

 

 

Refference

 

재귀와 스택

 

ko.javascript.info

 

나머지 매개변수와 스프레드 문법

 

ko.javascript.info

 

300x250
728x90