Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sokcuri/87caf022bafefb093b4ab065a330bde2 to your computer and use it in GitHub Desktop.
Save sokcuri/87caf022bafefb093b4ab065a330bde2 to your computer and use it in GitHub Desktop.
디폴트 파라메터를 지정하는 방법과 NodeList를 Array로 바꾸는 방법을 설명합니다

자바스크립트 함수의 디폴트 파라메터

파라메터 핸들링

Javascript에서는 제한 없이 여러개의 파라메터를 받을 수 있다. 다만 디폴트 파라메터를 지원하지 않기 때문에 OR 연산자를 이용해 파라메터의 기본값을 지정하는 트릭이 널리 쓰이고 있다.

function f(param) {
  param = param || "Woowahan";
  ...
}

OR 연산자는 앞의 조건이 참이면 뒤의 조건을 실행하지 않는 특징이 있다. 이를 이용해 param에 undefined 또는 null과 같은 잠재적인 false 값이면 뒤의 조건을 실행하게 만들어 기본값을 지정해주는 방법이 있다.

다만 이 방법은 0이나 null과 같은 값도 초기화하는 문제가 있다. 따라서 다음과 같이 값에 undefined가 들어왔을 때에만 초기화하도록 지정하기도 한다.

function foo(a, b)
{
  a = typeof a !== undefined ? a : 42;
  ...
}

최신 언어 스펙인 ES6 (ECMAScript 2015)부터는 C++ 언어와 같은 형태를 지닌 디폴트 파라메터를 지원한다. 이를 이용하면 앞과 같은 방법을 사용하지 않아도 된다.

function f(x, y=0) {
  return [x, y];
}

두번째 파라메터를 빠뜨리더라도 디폴트로 지정된 값이 들어가게 된다.

> f(1)
[1, 0]
> f()
[undefined, 0]

함수의 파라메터로 undefined를 넣었을때도 마찬가지로 동작한다.

> f(undefined, undefined)
[undefined, 0]

더 자세한 내용을 보려면 아래 링크들을 참고하자

NodeList을 배열처럼 쓰는 방법

NodeList란?

document.querySelectorAll 셀렉터 함수의 결과물로, HTML Node를 가지고 있다.

> document.querySelectorAll('div')
(293) [div#notify-container, div#custom-header, div.-container, div.-main,]

document에서 모든 div 노드를 가져오는 코드이다. 배열의 모습을 갖추고 있지만 Array는 아니다. forEachpush, pop 등의 Array 메소드들을 쓰려면 NodeList를 Array로 변환하여야 한다.

document.getElementById 또는 document.getElementsByClassName 등을 쓰면 나오는 HTMLCollection 또는 파생 객체들도 마찬가지로 배열 형태를 띄고 있지만, Array는 아니므로 Array 메소드를 쓰려면 Array로 변환해야 한다. 이제 Array로 바꾸는 방법에 대해서 알아보도록 한다.

NodeList를 Array로 바꾸기

여러가지 방법이 존재한다. 첫번째는 for문과 같은 반복문으로 직접 한땀한땀 요소를 넣는 방법, 두번째는 ES6의 표준격인 Array.from을 사용해서 바꾸는 방법, *세번째는 배열을 복제하는 slice 메소드를 이용해서 Array 객체로 바꾸는 것이고, 다른 하나는 존재하는 배열에 추가하는 concat 메소드를 이용하는 방법이다. 이 밖에도 무궁무진한 방법이 존재하지만 지면이 모잘라 모두 싣지는 않는다.

for문으로 직접 바꾸기
var div = document.querySelectorAll('div');
var list = [];
for (let item in div) {
  list.push(div[item]);
}
Array.from 메소드를 이용
var div = document.querySelectorAll('div');
Array.from(div);
slice 메소드를 이용
var nodeList = document.querySelectorAll('div');
var list = Array.prototype.slice.call(nodeList);

Array.prototype.slice.call은 [].slice.call로 줄여 쓸 수 있다.

concat 메소드를 이용
var nodeList = document.querySelectorAll('div');
var list = [].concat(nodeList);

ES6 (ECMAScript 2015)을 지원하는 환경에서는 var list = […nodeList]와 같이 써도 된다.

다른 방법

지금까지는 NodeList를 Array로 바꾸는 방법을 알아보았는데, 발상을 바꿔 NodeList를 Array로 바꾸지 않고 Array의 메소드들을 NodeList로 그대로 옮기는 방법이 있다.

NodeList.prototype.forEach = Array.prototype.forEach

이렇게 하면, 앞으로 NodeList에서도 Array와 마찬가지로 forEach를 쓸 수 있다.

document.querySelectorAll('td').forEach(function(o){
   o.innerHTML = 'text';
});

참고

최신 브라우저에서는 NodeList에서도 forEach 메소드가 존재한다. 하지만 구버전 브라우저를 지원하려면 NodeList를 Array로 변환하는 것이 좋다.

현재는 크롬과 오페라, 파이어폭스 환경 모두 NodeList에서 forEach 메소드를 사용할 수 있다.

검증

NodeList가 Array로 잘 변환되었는지 보려면 toString.call을 사용해서 객체의 형태를 확인해본다.

> var td = document.querySelectorAll('td');
> toString.call(td)
"[object NodeList]"
var list = [];
for (let item in td) {
  list.push(div[item]);
}
toString.call(list);
toString.call([].slice.call(td))
"[object Array]"
toString.call([].concat(td))
"[object Array]"
toString.call([...td])
"[object Array]"

이렇게 NodeList가 모두 Array로 바뀌었음을 확인할 수 있다.

더 자세한 내용들은 아래 링크를 참고하자.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment