모던자바스크립트 6장

SH·2022년 6월 10일
0

한이음 ICT

목록 보기
6/8

5.2 나머지 매개변수와 스프레드 연산자(전개 연산자)

나머지 매개변수 ... : 남아있는 매개변수를 모두 모아서 하나의 배열에 넣어라

function foo (arg1, arg2, ...args) {
	alert(arg1); // first
    alert(arg2); // second
    alert(args[0]); // third
    alert(args[1]); // fourth
}


foo("first", "second", "third", "fourth")

유사 배열 객체인 arguments를 통해서는 인덱스를 통해서 매개변수에 접근 가능하다

function foo(){
	alert(arguments[0 // 1
    alert(arguments[1]); // 2
}

foo(1, 2)

arguments는 유사 배열이면서 이터러블 객체이다. 다만 배열은 아니기 때문에 배열 메소드를 사용할 수는 없다. 또한 화살표 함수에서도 사용할 수 없다. 배열 메서드를 사용하거나 인수 일부만 사용할 때는 나머지 매개변수를 사용하는게 좋다.


스프레드문법!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

배열을 통째로 매개변수에 넘겨주어야 할 때, 말 그대로 배열을 '전개'하는 연산자 ...를 사용하면 간편하게 넘겨줄 수 있다.

let arr = [1, 2, 3]

alert(Math.max(arr)) // 에러 발생
alert(Math.max(...arr)) // 3
alert(Math.max(...arr, ...arr2)) // 여러개 전달 가능
alert(Math.max(1, ...arr1, 2)) // 일반적인 값과 혼합하여 사용 가능

또한 스프레드 문법을 통해 문자열과 같은 이터러블한 객체를 배열로 바꿀 때 사용할 수도 있음

let str = "hello";
alert([...str, 's']) // 'h','e','l','l','o','s'

스프레드 문법으로 배열과 객체를 복사할 수 있음

let arr = [1, 2, 3]
let arr_copy = [...arr] // 참조가 아닌 복사됨

let obj = { 1: "one", 2: "two" }
let obj_copy = {...obj} // 참조가 아닌 복사됨

let obj_Copy = Object.assign({}, obj); 보다 짧은 코드로 복사 가능


정리: ...은 나머지 매개변수나 스프레드 문법으로 사용 가능

...이 함수 매개변수의 끝에 있는 경우: 인수 목록의 나머지를 배열로 모아주는 '나머지 매개변수’로 사용됨
...이 함수 호출 시 사용되거나 기타 경우: 배열을 목록으로 확장해주는 '스프레드 문법’으로 사용됨

사용 패턴:
인수 개수에 제한이 없는 함수를 만들 때 - 나머지 매개변수를 사용
다수의 인수를 받는 함수에 배열을 전달할 때 - 스프레드 문법을 사용


렉시컬 스코프 읽어봐라: https://ko.javascript.info/closure var 특징: 1. var로 선언한 변수는 블록 스코프가 아닌 함수 수준 스코프를 갖음 2. var 선언은 함수가 시작되는 시점(전역 공간에선 스크립트가 시작되는 시점)에서 처리됨 -> 호이스팅

결론: let, const 써라


6.5 전역 객체

브라우저 환경 - window
node.js 환경 - global 로 전역 객체를 부름

전역 객체의 이름을 globalThis로 표준화하자는 얘기도 나오는 추세

결론: 엄청 필요한 경우가 아니라면 쓰지 마라


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

함수 프로퍼티

foo.name - 함수의 이름 반환
foo.length - 함수 매개변수의 개수 반환. 나머지 매개변수는 포함하지 않음
foo.customPropertyName = "함수프로퍼티" - 함수 프로퍼티를 임의로 만들어 줄 수도 있음


기명 함수 표현식 - 함수 표현식에서 함수 이름을 붙여준 것

일반 함수 표현식

let foo = function(){
	// body
}

기명 함수 표현식

let foo = function funcName() {
	// body
    funcName(); // 가능
}
funcName(); // 불가능 

기명 함수 표현식을 사용할 때 다음과 같은 변화가 발생함
1. 함수 표현식 내부에서 해당 이름을 통해 자기 자신을 호출 가능
2. 기명 함수 표현식 외부에서는 그 이름을 사용할 수 없음


setTimeout과 setInterval

setInterval도 setTimeout과 똑같이 사용하면 됨
단 setInterval은 인수로 넘겨준 시간 간격마다 콜백 함수가 실행되는 차이가 있음

일정 시간 간격 마다 콜백 함수를 실행하기 위해 setInterval을 써도 되지면 중첨 setTimeout을 활용해도 됨

// 2초마다 alert창에 "째깍"이 뜸
let timerId = setTimeout(function tick() {
	alert("째깍");
    timerId = setTimeout(tick, 2000);
}, 2000);

중첩 setTimeout은 setInterval과 달리 유연하게 코드 작성이 가능함

let delay = 5000;

let timerId = setTimeout(function request() {
	// 다른 로직 어쩌구 저쩌구,,
    if (서버 과부화로 인한 요청 실패){
    	// 요청 간격을 늘려줌
        delay *= 2;
    }
    
    timerId = setTimeout(request, delay);

}, delay);

또한 중첩 setTimeout은 setInterval과 달리 지연 간격을 보장함

더 많은 내용은 https://ko.javascript.info/settimeout-setinterval 참고


6.9 패스


6.10 함수 바인딩

객체 메서드롤 콜백 함수로 전달할 때 this를 잃어버리는 경우가 많다. this에 undefined가 들어가는 경우이다. 객체 메서드를 콜백함수로 전달할 때, 컨텍스트도 제대로 유지하려면 어떻게 해야 될까??


해결책 1: 콜백 함수로 래퍼 함수를 전달함

해결책 2: bind 활용

모든 함수에는 this를 수정하게 해주는 내장 메서드 bind가 있음

let boundFunc = func.bind(context);

func.bind(context)는 함수처럼 호출 가능한 '특수 객체(exotic object)'를 반환함. 이 객체를 호출하면 this가 context로 고정된 함수 func가 반환됨.

따라서 boundFunc를 호출하면 this가 고정된 func를 호출하는 것과 동일하게 됨.

또한 bind로 함수 인수까지 고정해줄 수 있음


6.11 화살표 함수

화살표 함수에는 this가 없다. 따라서 화살표 함수에서 this를 호출할 경우 외부 렉시컬 환경에서 this를 찾는다.

이러한 특성은 자바스크립트에서 함수를 생성하고 전달할 시 함수의 컨텍스트를 잃지 않게 해 줄 수 있다. 화살표 함수 안에서 this를 호출하면, 외부에서 값을 가져오기 때문이다.

let group = {
  title: "1모둠",
  students: ["보라", "호진", "지민"],

  showList() {
    this.students.forEach(
      student => alert(this.title + ': ' + student)
    );
  }
};

group.showList();

this.title은 화살표 함수 바깥에 있는 group의 title을 가져온다.


또한 화살표 함수는 유사 배열 객체인 arguments를 지원하지 않는다.


마지막으로 화살표 함수는 this가 없기 때문에 new와 함께 호출할 수 없다 끝!

profile
블로그 정리안하는 J개발자

0개의 댓글