-
자바스크립트 함수 심화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