본문 바로가기
[코드잇]/JavaScript 백엔드 개발자

모던 자바스크립트 -Arrow Function, this-

by 수민띠 2023. 2. 22.

Arrow Function

1. 익명 함수를 간결하게 표현하는 문법(ES2015)

2. function 키워드를 지우고, 소괄호 오른쪽에 => 표현.

3. 모든 화살표 함수는 익명 함수이다. 따라서

4. 이름을 가진 변수에 할당하거나, 다른 함수의 아규먼트를 선언할 때 사용

5. Arrow Function에는 arguments객체가 없다. 따라서 arguments객체 사용하는 함수는 Arrow Function으로 대체하기 어렵다.

6. this가 가리키는 값이 일반 함수와 다르다.

const getTwice = function(number) {
  return number * 2;
};

console.log(getTwice(5));

const myBtn = document.querySelector('#myBtn');

myBtn.addEventListener('click', function(){
  console.log('button is clicked!')
});

위 코드에 있는 함수들을 Arrow Function으로 변환

const getTwice = (number) => {
  return number * 2;
};

console.log(getTwice(5));

const myBtn = document.querySelector('#myBtn');

myBtn.addEventListener('click', () => {
  console.log('button is clicked!')
});

조건에 따라 더 축약된 형태로 함수를 만들 수 있다.

 

조건 1. 파라미터가 하나뿐일 때

파라미터를 감싸는 소괄호 생략 가능(number가 파라미터라는 것을 명확하게 알려주는 것이 좋기 때문에 생략 비추)

파라미터가 없거나 2개 이상일 경우는 소괄호 반드시 작성.

const getTwice = number => {
  return number * 2;
};

 

조건 2. 함수 내부의 동작 코드가 return문만 있을 때

중괄호와 return 키워드 생략 가능.

const getTwice = number => number * 2;
console.log(getTwice(3)); //6

 

조건 3. 함수 내부의 동작이 return문 하나밖에 없지만 return값이 객체일 때

const getmsg = () => {
  return { msg: 'Hi',};
};

이런 경우 return문과 중괄호를 지우게 되면 객체를 표현하는 중괄호를 함수의 동작 부분을 구분하는 중괄호로 해석해서 발생하는 오류 발생오류 발생

const getmsg = () => { msg: 'Hi',}; //SyntaxError

 

이런 경우 중괄호 바깥을 소괄호로 감싸주게 되면 해결

const getmsg = () => ({ msg: 'Hi',});

 

this키워드

웹 브라우저 안에서 JS가 동작한다면 전역 객체인 Window객체가 기본값.

객체의 메소드를 정의하기 위한 함수 안에서는 메소드를 호출한 객체를 가리킨다.

console.log(this);

this는 함수 내부에서 주로 사용되며, 특히 객체의 메소드를 만들 때 중요한 역할을 한다.

const user = {
  firstName: 'Tess',
  lastName: 'Jang',
  getFullName: function() {
    return `${user.firstName} ${user.lastName}`;
  },
};
console.log(user.getFullName()); //Tess Jang

코드 해석 : user 객체에 firstName과 lsatName  프로퍼티를 만들고, getFullName메소드에서는 user객체의 각 프로퍼티를 합쳐서 새로운 문자열을 리턴한다.

 

getFullName메소드를 다른 객체에도 적용하고 싶어서 함수 외부로 분리하게 된다면 문제가 생긴다.

function getFullName() {
    return `${user.firstName} ${user.lastName}`;
}

const user = {
  firstName: 'Tess',
  lastName: 'Jang',
  getFullName: getFullName,
};

const admin = {
  firstName: 'Alex',
  lastName: 'Kim',
  getFullName: getFullName,
};

console.log(user.getFullName()); //Tess Jang
console.log(admin.getFullName()); //Tess Jang

getFullName의 동작 부분에서는 user 객체만 바라보기 때문에 admin객체에서 메소드를 호출하더라도 user객체의 프로퍼티를 사용하게 되는 것이다. 이런 상황에서 this 키워드가 활용된다.

function getFullName() {
    return `${this.firstName} ${this.lastName}`;
}

const user = {
  firstName: 'Tess',
  lastName: 'Jang',
  getFullName: getFullName,
};

const admin = {
  firstName: 'Alex',
  lastName: 'Kim',
  getFullName: getFullName,
};

console.log(user.getFullName()); //Tess Jang
console.log(admin.getFullName()); //Alex Kim

JS에서 this는 함수를 호출한 객체를 가리키는 키워드이다.

즉, 값이 미리 결정되는게 아니라 함수가 호출될 때 어떤 객체가 그 함수를 호출했는지에 따라 값이 변하게 된다는 것이다.

 

+추가 설명

console.log(this); // 그냥this사용

function printThis() { //함수선언
  console.log(this);
}

printThis(); // 함수호출

그냥 this를 사용하거나 함수를 선언하고서 함수를 그냥 호출하게 되면 this는 기본값인 Window 객체를 가리키게 된다.

 

그런데 어떤 객체의 메소드로 호출이 되는 경우에는 함수를 호출하는 객체this에 담긴다.

console.log(this);

function printThis() {
  console.log(this);
}

const myObj ={
  content: 'myObj',
  printThis: printThis,
};

const otherObj = {
 content: 'otherObj',
 printThis: printThis,
};

myObj.printThis();
otherObj.printThis();

주의해야 할 점

일반 함수와 화살표 함수의 가장 중요한 차이가 this키워드이다.

Arrow function에서 this는 Arrow function이 선언되기 직전, 그 때 유효한 this값을 가지게 됨.

 

printThis함수를 화살표함수로 변경 후 코드 실행 -> 모든 결과가 윈도우 객체.

console.log(this);
 
const printThis = () => {  
  console.log(this);
};

const myObj ={
  content: 'myObj',
  printThis: printThis,
};

const otherObj = {
 content: 'otherObj',
 printThis: printThis,
};

myObj.printThis();
otherObj.printThis();

 

위 코드에서 화살표 함수가 선언되기 직전의 this는 윈도우 객체.

이런 특징 때문에 객체에 메소드를 만들 때는 화살표 함수보다는 일반 함수가 좀 더 권장된다는 점도 참고

 

꼭 외부에서 여러 객체에서 공통적으로 사용되는 메소드를 만들 뿐만 아니라, 객체 내부에서 메소드를 만들 때도 메소드가 속해 있는 객체의 프로퍼티가 필요한 상황에서 활용가능

const user ={
  firstName: 'Tess',
  lastName: 'Jang',
  getFullName: function() {
    return `${user.firstName} ${user.lastName}`;
  },
};
console.log(user.getFullName());

문제

//이 함수를 호출한 객체의 title프로퍼티를 출력하는 함수
function printThisTitle() { 
  console.log(this.title); 
}

const courseA = {
  title: '프로그래밍 기초 in JavaScript',
  printTitle: printThisTitle,
};

const courseB = {
  title: '컴퓨터 개론',
  printTitle: courseA.printTitle,
};

const courseC = {
  title: '웹 퍼블리싱',
  printTitle: courseB.printTitle,
};

courseA.printTitle(); //프로그래밍 기초 in JavaScript
courseB.printTitle(); //컴퓨터 개론
courseC.printTitle(); //웹 퍼블리싱

문제 2

const getFullName = () => `${this.firstName} ${this.lastName}`;

const user = {
  firstName: 'Ted',
  lastName: 'Chang',
  getFullName: getFullName,
};

console.log(user.getFullName()); //undefined undefined