ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바스크립트 함수 심화
    javascript 2023. 5. 13. 11:12

    재귀와 스택

    재귀적 구조

    재귀란 함수 내부에서 자기 자신을 호출하는 것을 나타내는 프로그래밍 용어이다.  재귀적 자료 구조는 자기 자신의 일부를 복제하는 형태의 자료구조이다. 재귀적 구조는 배열이나 연결리스트로 표현할 수 있다. 

     

    연결리스트

    배열의 경우, 삭제와 삽입에 들어가는 비용이 크기 때문에 빠른 삽입과 삭제를 위해서는 배열보다 연결리스트를 사용한다. 

    연결리스트는 아래와 같이 두 가지 방법으로 생성할 수 있다. 

    //1
    let list = {
      value: 1,
      next: {
        value: 2,
        next: {
          value: 3,
          next: {
            value: 4,
            next: null
          }
        }
      }
    };
    
    //2
    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;

    연결리스트는 리스트 쪼개기, 합치기, 요소 추가, 삭제가 굉장히 쉽다. 

    //연결리스트 나누기
    let secondList = list.next.next;
    list.next.next = null;
    
    //연결리스트 합치기
    list.next.next = secondList;
    
    //연결리스트 생성
    let list = { value: 1 };
    list.next = { value: 2 };
    list.next.next = { value: 3 };
    list.next.next.next = { value: 4 };
    
    //연결리스트 요소 추가
    list = { value: "new item", next: list };
    
    //연결리스트 요소 삭제 
    list.next = list.next.next;

    이렇게 연결리스트를 이용하면 쉽게 리스트의 내용을 변경시킬 수 있다. 하지만 인덱스로 접근할 수 없다는 큰 단점을 가지기 때문에, 인덱스로 접근해야하는 것이 중요한 경우에는 배열을 이용해야한다. 

     

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

    나머지 매개변수 ...

    나머지 매개변수 ...는 '남아있는 매개변수들을 한 데 모아 배열을 집어넣으라'는 의미를 가지고 있다. 

    function showName(firstName, lastName, ...titles) {
      alert( firstName + ' ' + lastName ); // Bora Lee
       // 나머지 인수들은 배열 titles의 요소가 됩니다.
      alert(titles); //["Software Engineer", "Researcher"] 
    }
    
    showName("Bora", "Lee", "Software Engineer", "Researcher");

    위와 같은 경우, Bora, Lee를 제외한 나머지 인수들이 모두 titles에 들어가게 된다. 즉, ...는 남은 것들을 한 데 모아서 배열에 집어넣은 값을 만든다. 

    이 때, 나머지 매개변수는 항상 마지막에 있어야한다. 위의 showName함수에 들어간 firstName, lastName, ...titles의 순서가 바뀌어, ...titles가 중간이나 앞에 오면 에러가 난다. 

     

    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");

    나머지 매개변수가 나오기 전에는 arguments를 많이 이용했다. arguments는 유사 배열 객체이면서 반복가능한 이터러블 객체이다. 즉, 배열은 아니기 때문에 배열 메서드를 사용할 수 없고 인수 전체가 arguments에 담기기 때문에 인수의 일부만 사용할 수도 없다. 

     

    스프레드 문법

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

    만약 배열을 통째로 매개변수에 넘겨주고 싶으면 어떻게 할까? 스프레드 문법을 이용한다. 

    let str = "Hello";
    
    alert( [...str] ); // H,e,l,l,o

    이렇게 문자열을 문자 배열로 변환시킬 수도 있다. 

     

    배열과 객체의 복사본 만들기

    //배열
    let arr = [1, 2, 3];
    let arrCopy = [...arr]; // 배열을 펼쳐서 각 요소를 분리후, 매개변수 목록으로 만든 다음에
                            // 매개변수 목록을 새로운 배열에 할당함
    
    // 배열 복사본의 요소가 기존 배열 요소와 진짜 같을까요?
    alert(JSON.stringify(arr) === JSON.stringify(arrCopy)); // true
    
    // 두 배열은 같을까요?
    alert(arr === arrCopy); // false (참조가 다름)
    
    // 참조가 다르므로 기존 배열을 수정해도 복사본은 영향을 받지 않습니다.
    arr.push(4);
    alert(arr); // 1, 2, 3, 4
    alert(arrCopy); // 1, 2, 3
    
    //객체
    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}

    이렇게 스프레드 문법을 이용해서 배열, 객체를 복사할 수 있다!

     

    전역 객체

    var로 선언한 전역 함수나 전역 변수는 전역 객체의 프로퍼티가 됩니다.

    var gVar = 5;
    
    alert(window.gVar); // 5 (var로 선언한 변수는 전역 객체 window의 프로퍼티가 됩니다)

     

    객체로서의 함수와 기명 함수 표현식

    name 프로퍼티

    function sayHi() {
      alert("Hi");
    }
    
    alert(sayHi.name); // sayHi
    
    let sayHi = function() {
      alert("Hi");
    };
    
    alert(sayHi.name); // sayHi (익명 함수이지만 이름이 있네요!)

    이렇게 함수.name을 하면 함수의 이름을 가져올 수 있다. 

     

    커스텀 프로퍼티

    function sayHi() {
      alert("Hi");
    
      // 함수를 몇 번 호출했는지 세봅시다.
      sayHi.counter++;
    }
    sayHi.counter = 0; // 초깃값
    
    sayHi(); // Hi
    sayHi(); // Hi
    
    alert( `호출 횟수: ${sayHi.counter}회` ); // 호출 횟수: 2회

    위와 같이 함수에 자체적으로 만든 프로퍼티를 추가할 수도 있다. 

     

     

    'javascript' 카테고리의 다른 글

    함수 심화와 this  (0) 2023.06.24
    5월 데보션 테크 세미나 클라우드 비용 최적화 후기  (1) 2023.05.28
    자료구조와 자료형  (0) 2023.05.07
    객체  (0) 2023.04.22
    자바스크립트 기본  (0) 2023.04.09

    댓글

Designed by Tistory.