해당 포스팅은 링크된 웹사이트를 보고 이해한 내용을 정리합니다.
배열 고차 함수(Higher order function)
: 함수를 인자로 전달받거나 함수를 결과로 반환하는 함수
: 인자로 받은 함수를 필요한 시점에 호출하거나 클로저를 생성해 반환
* JS에서 함수는 일급 객체
= 인자로 전달/반환 가능
// 함수를 인자로 전달받고 함수를 반환하는 고차 함수
function makeC(predicate) {
let num = 0;
return function() {
num = predicate(num);
return num;
};
}
// 보조 함수
function increase(n) {
return ++n;
}
function decrease(n) {
return --n;
}
// makeC는 함수를 인자로 전달받고 클로저 반환
const increaser = makeC(increase);
console.log(increaser()); //1
console.log(increaser()); //2
const decreaser - makeC(decrease);
console.log(decreaser()); //-1
console.log(decreaser()); //-2
외부 상태 변경 || 가변 데이터를 피하고 불변성
을 지향하는 함수형 프로그래밍 기반
💡 다시 정리!
함수형 프로그래밍
순수 함수와 보조 함수의 조합을 통해 로직 내 존재하는 조건문과 반복문 제거해복잡성 해결
+ 변수의 사용 억제해상태 변경을 피하려는
프로그래밍 패러다임
=부수 효과를 억제
해 오류를 피하고 프로그램의 안정성을 높이는 방법
Array.prototype.sort()
: 배열의 요소 적절하게 정렬
this
(원본 배열) 직접 변경, 정렬된 배열 반환
Array.prototype.sort([compareFunction])
compareFunction
: 두 개의 인자를 받아 서로 비교해 순서를 정하는 함수
0보다 작은 수
, 0
, 0보다 큰 수
중 하나 반환
sort(compareFn?:(a:T, b:T) => number):this;
기본 정렬 순서: 문자열 Unicode 코드 포인트 순서
배열의 요소가 숫자 타입이라도 일시적으로 문자열 변환 후, 정렬
const points = [32, 45, 99, 102, 1, 4, 10];
points.sort();
console.log(points); // [1, 4, 10, 32, 45, 99, 102]
- compareFunction(a,b) > 0 : a가 b보다 먼저 위치
- compareFunction(a,b) = 0 : a와 b의 순서가 바뀌지 않음
- compareFunction(a,b) < 0 : b가 a보다 먼저 위치
객체를 요소로 갖는 배열을 정렬하는 경우
const teams = [
{id: 3, name: 'Whyrano'},
{id: 6, name: 'GOD'},
{id: 2, name: 'Tomato'}
];
// 비교 함수
function compare(key) {
return function(a,b) {
return a[key] > b[key] ? 1 : (a[key] < b[key] ?-1 : 0);
};
}
// id 기준 정렬
teams.sort(compare('id'));
// name 기준 정렬
teams.sort(compare('name'));
Array.prototype.forEach()
: 주어진 함수를 배열 요소 각각에 대해 실행
:this
(원본 배열) 변경 X But, 콜백 함수는 this
변경 가능
array.forEach(callback(currentValue[, index[, array]]) => [, thisArg])
- for문 대신 사용 가능
- 배열 순회하며 배열 각 요소에 대해 인자로 주어진 콜백함수 실행
- 반환값:
undefined
- 콜백 함수의 매개변수를 통해
this
를 전달받을 수 있음 - for문과 달리
break문
사용 불가 = 중간에 순회 중단 불가 - for문에 비해 성능이 좋지 않으나, 가독성이 좋아 사용 권장됨
💡 용어 정리
callback: 각 요소에 대해 실행할 함수, 아래 3가지 매개변수를 받음
currentValue: 처리할 현재 요소
index: 처리할 현재 요소의 인덱스
array: forEach() 메서드를 호출한 배열
thisArg: callback을 실행할 때 this로 사용할 값
const numbers = [1, 2, 3];
let pows = [];
// for문
for (let i = 0; i < numbers.length; i++) {
pows.push(numbers[i] ** 2);
}
console.log(pows); // [ 1, 4, 9 ]
pows = [];
// forEach 메소드
numbers.forEach(function (item) {
pows.push(item ** 2);
});
console.log(pows); // [ 1, 4, 9 ]
+ forEach 메소드에 2번째 인자로 this
전달 가능
+ ES6에서는 Arrow function
을 사용하면, this
생략해도 동일한 동작 실행
Array.prototype.map()
: 배열을 순회하며 각 요소에 대해 인자로 주어진 콜백 함수의 반환값으로 새로운 배열 생성해 반환
:this
(원본 배열) 변경 X
map<U>(callback: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
- 배열을 순회하며 요소 값을 다른 값으로 매핑하기 위한 함수
- 콜백 함수의 매개변수를 통해
this
전달 받을 수 있음 - IE9 이상에서 정상 작동
💡 용어 정리
U: 콜백 함수가 반환할 타입
U[ ]: 콜백 함수의 반환값 = 콜백 함수의 로직(조건)에 따라 새로 생성된 배열
const numbers = [1, 4, 9];
const roots = numbers.map(function (item) {
// 반환값이 새로운 배열의 요소가 된다. 반환값이 없으면 새로운 배열은 비어 있다.
return Math.sqrt(item);
});
// 위 코드의 축약표현
// const roots = numbers.map(Math.sqrt);
// 새로운 배열 반환
console.log(roots); // [ 1, 2, 3 ]
// 원본 배열은 변경 X
console.log(numbers); // [ 1, 4, 9 ]
+ 2번째 인자로 this
전달 가능
+ ES6에서는 Arrow function
을 사용하면, this
생략해도 동일한 동작 실행
Array.prototype.filter()
: 배열에서 특정 케이스만 필터링 조건으로 추출해 새로운 배열을 만들 때 사용
:this
(원본 배열) 변경 X
filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
- if문 대체 가능
- 콜백 함수의 실행 결과가
true
인 배열 요소의 값만 추출해 새로운 배열 반환 - 콜백 함수의 매개변수를 통해
this
전달 받을 수 있음 - IE9 이상에서 정상 동작
💡 용어 정리
unknown: 콜백 함수의 반환 타입이 true/false이지만 타입안정성 보장을 위해unknown
으로 설정
* 안정한 타입_모든 타입의 상위 타입
T[ ]: 콜백 함수의 반환값
const result = [1, 2, 3, 4, 5].filter(function (item, index, self) {
console.log(`[${index}] = ${item}`);
return item % 2; // 홀수만을 필터링 (1은 true로 평가)
});
console.log(result); // [ 1, 3, 5 ]
+ 2번째 인자로 this
전달 가능
Array.prototype.reduce()
: 배열 순회하며 각 요소에 대해 이전의 콜백 함수 실행 반환값 전달해 콜백 함수 실행, 그 결과를 반환
:this
(원본 배열) 변경 X
reduce(callbackFn: previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
reduce(callbackFn: previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
- 객체의 프로퍼티 값을 합산하는 경우, 반드시
초기값
전달 - 언제나
초기값
을 전달하는 것이 에러를 회피할 수 있어 보다 안전
💡 용어 정리
previousValue: 초기값 = 이전 콜백 호출의 반환값
initialValue: T: 초기값, 없는 경우 배열의 1번째 요소 사용
const arr = [1, 2, 3, 4, 5];
// 합산
const sum = arr.reduce(function (previousValue, currentValue, currentIndex, self) {
console.log(previousValue + '+' + currentValue + '=' + (previousValue + currentValue));
return previousValue + currentValue; // 결과는 다음 콜백의 첫번째 인자로 전달된다
});
console.log(sum); // 15: 1~5까지의 합
/*
1: 1+2=3
2: 3+3=6
3: 6+4=10
4: 10+5=15
15
*/
// 최대값 취득
const max = arr.reduce(function (pre, cur) {
return pre > cur ? pre : cur;
});
console.log(max); // 5: 최대값
+ 2번째 인수로 초기값
전달 가능, 이 값은 콜백 함수에 최초로 전달됨
* reduce
로 빈 배열 호출하면 에러 발생
Array.prototype.some()
: 배열 내 일부
요소가 콜백 함수 테스트를 통과하는지 확인해 그 결과를 boolean
으로 반환
:this
(원본 배열) 변경 X
array.some((item[, index, array]) => {} [, thisArg])
- 매개변수를 통해
this
전달 받을 수 있음
// 배열 내 요소 중 10보다 큰 값이 1개 이상 존재하는지 확인
let res = [2, 5, 8, 1, 4].some(function (item) {
return item > 10;
});
console.log(res); // false
res = [12, 5, 8, 1, 4].some(function (item) {
return item > 10;
});
console.log(res); // true
// 배열 내 요소 중 특정 값이 1개 이상 존재하는지 확인
res = ['apple', 'banana', 'mango'].some(function (item) {
return item === 'banana';
});
console.log(res); // true
+ 2번째 인자로 this
전달 가능
Array.prototype.every()
: 배열 내 모든
요소가 콜백 함수 테스트를 통과하는지 확인해 그 결과를 boolean
으로 반환
:this
(원본 배열) 변경 X
array.every((item[, index, array]) => {} [, thisArg])
- 매개변수를 통해
this
전달 받을 수 있음
Array.prototype.find()
: 콜백 함수를 실행하여 그 결과가 참
인 1번째 요소 반환, 참인 요소가 존재하지 않으면 undefined
반환
:this
(원본 배열) 변경 X
array.find(callbackFn[, thisArg])
- 매개변수를 통해
this
전달 받을 수 있음 filter
는 콜백 함수의 실행 결과가true
인 배열 요소의 값만 추출한 새로운 배열 반환
=filter
의 반환값은 언제나배열
find
는 콜백함수를 실행해 그 결과가true
인 첫번째 요소를 반환
=find
의 반환값은 해당요소값
Array.prototype.findIndex()
: 콜백 함수를 실행해 그 결과가 참
인 1번째 요소의 인덱스
반환, 참인 요소가 존재하지 않으면 -1
반환
:this
(원본 배열) 변경 X
array.findIndex(callback[, thisArg])
- 매개변수를 통해
this
전달 받을 수 있음
DOM(Document Object Model)
: 브라우저 랜더링 엔진이 웹 문서를 로드한 후, 파싱해 브라우저가 이해할 수 있는 구조로 웹 문서를 구성해 메모리에 적재하는 것
= 모든 요소, 요소의 attrinute, text를 각각의 객체로 만들고 이들 간의 부자 관계를 표현할 수 있는 트리 구조로 구성한 것
- 동적으로 변경 가능
- 변경된 DOM은 랜더링에 반영

DOM API
: DOM은 웹 문서의 동적 변경을 위해 프로그래밍 언어가 자신에 접근하고 수정할 수 있는 방법을 일반적으로 JS의 객체(프로터피 + 메소드)로 제공
=> 정적인 웹페이지에 접근해 동적으로 웹페이지를 변경하는 유일한 방법이 메모리 상에 존재하는 DOM 변경이고, 이때 필요한 것이 DOM API
DOM은 W3C의 공식 표준 + 플랫폼/프로그래밍 언어 중립적
HTML 문서에 대한 모델 구성 | HTML 문서 내의 각 요소에 접근/수정 |
브라우저는 HTML 문서를 로드한 후 해당 문서에 대한 모델을 메모리에 생성 - 모델은 객체의 트리로 구성(DOM tree ) |
모델 내의 각 객체에 접근하고 수정할 수 있는 프로퍼티와 메소드 제공 DOM이 수정되면 브라우저를 통해 사용자가 보게 될 내용도 변경 |
DOM tree
: 브라우저가 HTML 문서를 로드한 후 파싱해 생성하는 모델, 객체의 트리로 구조화

- 요소, 어트리뷰트, 텍스트는 하나의 객체 + Document 객체의 자식
Document Node(문서 노드) | 트리의 최상위에 존재 DOM tree에 접근하기 위한 entry point |
Element Node(요소 노드) | HTML 요소 표현 문서의 구조 서술 모든 요소 노드는 요소별 특성을 표현하기 위해 HTMLElement 객체를 상속한 객체로 구성 |
Attribute Node(어트리뷰트 노드) | HTML 요소의 어트리뷰트 표현 해당 어트리뷰트가 지정된 요소의 자식이 아닌 해당 요소의 일부로 표현 접근 시, 어트리뷰터 참조/수정 가능 |
Text Node(텍스트 노드) | HTML 요소의 텍스트 표현 요소 노드의 자식 자신의 자식 노드를 가질 수 없음 DOM tree의 최종단 |
DOM tree는 개발자도구의 Elements > properties로 확인 가능
DOM Query / Traversing (요소 접근)
하나의 요소 노드 선택
*복수개가 선택된 경우, 첫번째 요소만 반환
document.getElementByID(id)
- id 어트리부트 값으로 요소 노드 1개 선택
- Return: HTMLElement를 상속받은 객체
- 모든 브라우저에서 동작
document.querySelector(cssSelector)
- CSS Selector 사용해 요소 노드 1개 선택
- IE8 이상 브라우저에서 동작
여러 개의 요소 노드 선택
document.getElementsByClassName(class)
- class 어트리부트 값으로 요소 노드 모두 선택
- 공백으로 구분해 여러 개의 class 지정 가능
- IE9 이상 브라우저에서 동작
// HTMLCollection을 반환한다. HTMLCollection은 live하다.
const elems = document.getElementsByClassName('red');
for (let i = 0; i < elems.length; i++) {
// 클래스 어트리뷰트의 값을 변경한다.
elems[i].className = 'blue';
}
❗ 반환값이 복수인 경우getElementsByClassName
메소드의 반환값:HTMLCollection
HTMLElemet의 리스트를 담아 반환하기 위한 객체
배열과 비슷한 사용법을 가지고 있지만 배열 아닌유사 배열
+ 실시간으로 Node의 상태 변경을 반영함
=>loop
가 필요한 경우 다른 방법으로 회피해야 함
// 반복문 역방향
const elems = document.getElementsByClassName('red');
for (let i = elems.length - 1; i >= 0; i--) {
elems[i].className = 'blue';
}
// while 반복문 사용
const elems = document.getElementsByClassName('red');
let i = 0;
while (elems.length > i) { // elems에 요소가 남아 있지 않을 때까지 무한반복
elems[i].className = 'blue';
// i++;
}
elems에 요소가 남아있지 않을 때까지 무한반복하기 위해 index는 0으로 고정
const elems = document.getElementsByClassName('red');
// 유사 배열 객체인 HTMLCollection을 배열로 변환한다.
// 배열로 변환된 HTMLCollection은 더 이상 live하지 않다.
console.log([...elems]); // [li#one.red, li#two.red, li#three.red]
[...elems].forEach(elem => elem.className = 'blue');
=> 이 방법을 권장
// querySelectorAll는 Nodelist(non-live)를 반환한다. IE8+
const elems = document.querySelectorAll('.red');
[...elems].forEach(elem => elem.className = 'blue');
document.getElementsByTagName(tagName)
- 태그명으로 요소 노드 모두 선택
- Return: HTMLCollection (live)
- 모든 브라우저
document.querySelectorAll(selector)
- 지정된 CSS Selector 사용해 요소 노드 모두 선택
- Return: NodeList (non-live)
- IE8+
DOM Traversing(탐색)
.parentNode
- 부모 노드 탐색
- Return: HTMLElement를 상속받은 객체
- 모든 브라우저
.firstChild
.lastChild
- 자식 노드 탐색
- Return: HTMLElement를 상속받은 객체
- IE9+
* IE를 제외한 대부분의 브라우저: 요소 사이 공백
|| 줄바꿈 문자
를 텍스트 노트로 취급
=> 공백 제거
|| jQuery: .prev()
|| jQuery: .next()
사용해 회피 가능
* IE9+
firstElementChild
|| lastElementChild
사용 가능
hasChildNodes() | childNodes | children |
자식 노드 유무 확인 + Boolean 값 반환 | 자식 노드 컬렉션 반환 텍스트 요소를 포함한 모든 자식 요소 반환 |
자식 노드 컬렉션 반환 자식 요소 중 Element type 요소만 반환 |
Return: Boolean 값 | Return: NodeList (non-live) | Return: HTMLCollection (live) |
모든 브라우저 | 모든 브라우저 | IE9+ |
previousSibling, nextSibling | previousElementSibling, nextElementSibling |
형제 노드 탐색 text node 포함한 모든 형제 노드 탐색 |
형제 노드 탐색 형제 노드 중 Element type 요소만 탐색 |
Return: HTMLElement를 상속받은 객체 | Return: HTMLElement를 상속받은 객체 |
모든 브라우저 | IE9+ |
DOM Manipulation(조작)
텍스트 노드 접근/수정
텍스트 노드는 요소 노드의 자식 - firstChile
프로퍼티 사용해 텍스트 노드 탐색 - nodeValue
를 이용해 텍스트 취득 - nodeValue
를 이용해 텍스트 수정
nodeValue
nodeName, nodeType // 노드의 정보
- 노드의 값 반환
- Return: 텍스트 노드는 문자열, 요소 노드는 null
- IE6+
어트리부트 노드 접근/수정
className
- class 어트리부터의 값 취득/변경
- className 프로퍼티에 값 할당하는 경우, class 어트리부트가 존재하지 않으면 class 어트리부트를 생성 + 지정된 값 설정
- class 어트리부트 값이 여러 개일 경우,
공백
으로 구분된 문자열 반환 =split(' ')
을 사용해 배열로 변경 - 모든 브라우저
classList
add
,remove
,item
,toggle
,contains
,replace
메소드 제공- IE10+
id
- id 어트리부트의 값 취득/변경
- id 프로퍼티에 값 할당할 때, 어트리부트가 존재하지 않으면 id 어트리부트 생성 + 지정된 값 설정
- 모든 브라우저
hasAttribute(attribute) | getAttribute(attribute) | setAttribute(attribute, value) | removeAttribute(attribute) |
지정한 어트리부트 소유 유무 검사 | 어트리부트 값 취득 | 어트리부트와 어트리부트 값 설정 | 지정 어트리부트 제거 |
Return: Boolean | Return: 문자열 | Return: undefined | Return: undefined |
IE8+ | 모든 브라우저 | 모든 브라우저 | 모든 브라우저 |
HTML 콘텐츠 Manipulation
마크업이 포함된 콘텐츠 추가: Cross-Site Scripting Attacks에 취약하므로 주의
textContent
- 요소의 텍스트 콘텐츠 취득/변경: 마크업 무시
- 요소에 새로운 텍스트 할당 시, 텍스트 변경 가능: 순수한 텍스트만 지정해야 함
- 마크업 포함하면 문자열로 인식되어 그대로 출력
- IE9+
innerText
- 요소의 텍스트 콘텐츠에만 접근 가능: 이마저도 사용하면 좋지 않음
- 비표준
- CSS에 순종적
- CSS를 고려해야 하므로 textContent 프로퍼티보다 느림
innerHTML
- 해당 요소의 모든 자식 요소를 포함하는 모든 콘텐츠를 하나의 문자열로 취득 가능: 마크업 포함
- 마크업 포함된 새로운 콘텐츠 지정: 새로운 요소 DOM에 추가
- 마크업 포함된 콘텐츠 추가는 Cross-Site Scripting Attacks에 취약
DOM 조작 방식
: innerHTML
프로퍼티를 사용하지 않고 새로운 콘텐츠 추가
: 1개의 요소 추가하는 경우 사용
createElement(tagName)
- 태그이름을 인자로 전달해 요소 생성
- Return: HTMLElement를 상속받은 객체
- 모든 브라우저
createTextNode(text)
- 텍스트를 인자로 전달해 텍스트 노드 생성
- Return: Text 객체
- 모든 브라우저
appendChild(Node)
- 인자로 전달한 노드를 마지막 자식 요소로 DOM tree에 추가
- Return: 추가한 노드
- 모든 브라우저
removeChild(Node)
- 인자로 전달한 노드 DOM tree에 제거
- Return: 추가한 노드
- 모든 브라우저
[진행 순서]createElemet()
사용해 새로운 요소 노드 생성 -createElement()
메소드의 인자로 태그 이름 전달 -createTextNode()
사용해 새로운 텍스트 노드 생성 - 생성된 요소DOM
에 추가appendChild()
사용해 생성된 노드 DOM tree에 추가||removeChild()
사용해 DOM tree에서 노드 삭제
insertAdjacentHTML(position, string)
- 인자로 전달한 텍스트를 HTML로 파싱, 그 결과로 생성된 노드를 DOM tree의 지정된 위치에 삽입
- 1번째 인자는 삽입 위치, 2번째 인자는 삽입할 요소를 표현한 문자열
- 1번째 인자로 올 수 있는 값:
beforebegin
,afterbegin
,beforeend
,afterend
- 모든 브라우저
innerHTML vs DOM 조작 방식 vs insertAdjacentHTML()
innerHTML | 장점 | - DOM 조작 방식에 비해 빠르고 간편 - 간편하게 문자열로 정의한 여러 요소를 DOM에 추가 가능 - 콘텐츠 취득 가능 |
단점 | - XSS 공격에 취약: 사용자로부터 입력받은 콘텐츠 추가 시 주의 - 해당 요소의 내용 덮어씀 = HTML 재파싱 = 비효율적 |
|
DOM 조작 방식 | 장점 | 특정 노드 1개를 DOM에 추가할 때 적합 |
단점 | innerHTML보다 느리고 더 많은 코드 필요 | |
insertAdjacentHTML() | 장점 | - 간편하게 문자열로 정의된 여러 요소 DOM에 추가 가능 - 삽입 위치 선정 가능 |
단점 | - XSS 공격에 취약: 사용자로부터 입력받은 콘텐츠 추가 시 주의 |
style
style
: inline
스타일 선언 생성
특정 요소에 inline
스타일 지정하는 경우에 사용
+ style
프로퍼티의 값 취득: window.getComputedStyle
사용 = 인자로 주어진 요소의 모든 CSS 프로퍼티 값 반환
'JS' 카테고리의 다른 글
JAVASCRIPT의 배열은 배열이 아니다? (0) | 2024.08.15 |
---|---|
정규표현식(Regular Expression) (0) | 2024.08.13 |
JAVASCRIPT04 (0) | 2024.08.13 |
JAVASCRIPT03 (0) | 2024.08.09 |
JAVASCRIPT02 (0) | 2024.08.02 |
- 배열 고차 함수(Higher order function)
- Array.prototype.sort()
- Array.prototype.forEach()
- Array.prototype.map()
- Array.prototype.filter()
- Array.prototype.reduce()
- Array.prototype.some()
- Array.prototype.every()
- Array.prototype.find()
- Array.prototype.findIndex()
- DOM(Document Object Model)
- DOM Query / Traversing (요소 접근)
- DOM Manipulation(조작)
- innerHTML vs DOM 조작 방식 vs insertAdjacentHTML()
- style