JavaScript ES6 정리 - Function

JavaScript ES6 정리 - Function

이번 포스팅에서는 많은 사람이 이미 사용중인 함수의 추가적인 내용에 대해 간략히 알아보자!

name property

function a () {}
console.log(a.name)

const b = function () {}
console.log(b.name)

const c = function c2 () {}
console.log(c.name)
/*
Result
a
b
c2
*/

첫 번째 예제의 경우에는 함수 a 그 자체로, a.name이 a로 출력되는 것은 맞는 것 같다.

하지만 두 번째 예제는 익명 함수를 변수 b에 할당하였는데 왜 b가 나올까 ?

원래대로라면 이름이 안 나오는 것이 맞다.

이는 브라우저들이 편의상 변수의 이름을 자동으로 함수의 name이라는 프로퍼티에 할당하기 시작하면서 생긴 결과이다.

세 번째 예제와 같이 함수의 name 프로퍼티가 존재한다면 기존의 값을 출력한다.

Arrow Function의 경우에도 동일하다.

name 프로퍼티는 주로 디버깅할 때 쓰인다고 한다.

(나도 써본 적이 없는 것 같다. 그냥 이런 게 있다는 정도로만 알고 넘어가자.)

new.target

function Person (name) {
  if(this instanceof Person) {
    this.name = name;
  } else {
    throw new Error('new 연산자를 사용하세요!');
  }
}
Person('진수'); //1
new Person('진수'); //2
/*
Result
1: Error
2: No Error
*/

new 연산자로 생성한다면 생성되는 대상은 this를 인스턴스로 갖는다.

따라서 1번은 오류가 발생, 2번은 오류가 발생하지 않는다.

function Person (name) {
    if(new.target !== undefined) {
    this.name = name;
  } else {
    throw new Error('new 연산자를 사용하세요!');
  }
}
Person('진수'); //1
new Person('진수'); //2
/*
Result
1: Error
2: No Error
*/

new.target이라는 녀석은 난생처음 봤다.

new라는 객체에 target이라는 프로퍼티가 있는 걸까??

console.log(new)를 내부에서 찍어보면 new라는 객체는 존재하지 않는다.

그렇다면 new.target는 그 자체가 하나의 변수라는 것이다.

쓸 일이 많지는 않아 보이니 함수 생성 시에 생기는 변수라고 이해하고 넘어가자!

함수 선언문과 스코프

a() //1
if(true) {
  a()
  function a () { console.log(true) }
}
a() //2

과연 위 코드의 1,2에 해당하는 부분은 true가 출력될까 ?

함수 선언문과 블록 스코프(if 문)에 대한 질문이다.

함수 선언문이 const과 let이 아니기 때문에 2는 출력이 될 것 같다.

마찬가지로, 1도 출력될 것 같은데 이상하게도 크롬에서는 출력되지 않는다.

엥.. 뭐지..? 파이어폭스에서도 안 되는데 사파리에서는 된다..

브라우저마다 다른데 이건 어떻게 이해해야할까 ?

ES5 문법으로 이해하면 true가 3번 출력되는 것이 맞다.

이는, 함수 선언문의 범위를 블록 스코프로 보냐 함수 스코프로 보냐에 따라 다르다.

코드 최상단에 'use strict';를 넣어보고 다시 실행해보자.

그 결과, 세 브라우저 모두 if 문 내부에서만 호출이 가능하다.

함수 선언문의 범위가 블록 스코프로 제한된 것이다.

  • strict mode 사용 시 : 함수 선언문은 블록 스코프로 제한
  • strict mode 미사용 시 : 브라우저마다 다른 동작을 함

이런 특수한 경우에는 클라이언트의 브라우저를 확인하고 예외처리를 해주는 것이 맞을까?

아니다. 자바스크립트를 포함한 모든 언어는 그 등장부터 완전할 수 없다.

함수 선언문을 쓰지 말자!

강의에서는 아래와 같은 방법을 추천한다.

ES6에서는 함수 선언문을 사용하지 말고 함수는 Arrow Function을, 객체는 메소드 축약형, 생성자를 쓸 때는 class를 사용하자.

이렇게 사용하면 function은 generator(function*)를 제외하고 등장할 일이 없다.

나도 ES6를 쓰면서 function 키워드를 사용한 적이 전혀 없는 것 같다!

항상 예상과 같은 동작을 할 수 있는 코드를 작성하자!

본 포스팅은 인프런 강의 Javascript ES6+ 제대로 알아보기를 공부하며 정리한 포스팅입니다!