자바스크립트.js #6 call, apply 그리고 this 바인딩

김창회·2021년 1월 1일
3

자바스크립트.js

목록 보기
6/8
post-thumbnail

💻자바스크립트.js 시리즈는 자바스크립트에 대해 심플하게 훑어봅니다📖

this!

자바스크립트에서는 함수를 호출할 때, 매개변수로 전달되는 인자값을 포함해 arguments 객체와 this 인자가 함수 내부로 암묵적으로 전달됩니다. 특히 오늘 알아볼 this는 고급 자바스크립트 개발자로 거듭나기 위해선 꼭 이해해야하는 핵심 개념 중 하나입니다.

this는 함수가 호출되는 방식에 따라 다른 객체를 참조합니다. 이걸 this 바인딩이라 부릅니다.
바인딩이란? 어떤 코드에서 함수를 호출할 때 그 해당 함수가 위치한 메모리 주소로 연결해주는 것을 의미합니다.

객체 메서드 호출 시 this 바인딩

만약 객체의 메서드에서 this를 사용한다면 해당 메서드가 호출된 객체로 바인딩 됩니다.

EX

const obj = {
  name: "cskim132",
  callName: function () {
    console.log(this.name);
  }
};

console.log(obj.callName());

위 예제에서 보았듯 callName 함수는 자신이 선언된 객체를 바인딩합니다.

여기서 주의할 점으론 화살표 함수, 즉 () => 와 같은 방식의 함수는 this를 바인딩하지않고 언제나 상위 스코프의 this만을 바인딩합니다.

함수 호출 시 this 바인딩

함수를 호출할 때, 함수 내부에서 사용된 this는 window 객체를 바인딩합니다. 즉, 전역 객체에 바인딩이 됩니다. 함수 내부에서 호출했을 경우에도 this가 전역 객체(window)를 바인딩하기 때문에 이 점을 주의해야 합니다.

기법을 활용한 this 바인딩

자바스크립트에서는 함수 호출 시 this가 전역 객체를 사용하게 되는 한계를 이겨내기 위해, this 바인딩을 개발자가 명시적으로 할 수 있도록 call과 apply같은 메서드를 제공합니다.

생성자 함수를 호출한 this 바인딩

생성자 함수는 new 연산자를 붙여 호출하는 방식을 말합니다.
만약 생성자 함수를 호출할 때면 this는 알아서 생성자가 만든 객체로 바인딩 됩니다.

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const person = new Person("cskim132", 20);

console.log(person); // { name : "cskim132", age : 20 }

class 문법을 사용한다면 constructor를 활용하면 되겠습니다.

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

const person = new Person("cskim132", 20);

console.log(person); // { name : "cskim132", age : 20 }
}

call과 apply 메서드를 이용한 this 바인딩

자바스크립트를 의도에 따라 바인딩시킬 수 있는 방법도 존재합니다.
바로 apply()와 call()메서드입니다. 이 둘은 모든 함수의 부모 프로토타입인 Function.prototype 객체의 메서드이므로, 모든 함수는 이 두개의 메서드를 사용할 수 있습니다. 또, 많은 라이브러리와 프레임워크에서 bind()라는 메서드를 지원하는데요. 이 bind()라는 메서드는 함수를 호출하는 것이 아닌, this가 바인딩된 함수를 리턴하는 형식이라고 보시면 되겠습니다..

지금은 apply와 call에 대해 살펴보겠습니다. apply와 call은 넘기는 인자의 형식만 다른 아주 비슷한 메서드인데요, 우선 apply는 첫번째 인자로 바인딩할 객체를 넣고, 두번째 인자로 함수에 사용될 인자를 배열 형식으로 넘기면 됩니다.

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const obj = {};
Person.apply(obj, ["cskim132", 20]);

console.log(obj); // { name : "cskim132", age : 20 }

call 메서드의 경우도 매우 흡사합니다.

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const obj = {};
Person.call(obj, "cskim132", 20);

console.log(obj); // { name : "cskim132", age : 20 }

위 두 개의 예제는 다음과 같습니다.

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const obj = new Person("cskim132", 20)

apply()와 call() 메서드는 this를 원하는 값으로 함수나 메서드를 호출할 수 있다는 장점이 있습니다. 그리고 이들이 대표적으로 쓰이는 곳은 유사 배열 객체에서 배열 메서드를 사용하는 경우입니다. 유사배열은 배열이 아니기때문에 배열 메서드를 사용할 수 없습니다. 하지만 apply() 메서드를 사용하면 가능해집니다.

const noArr = { 0: "1", 1: "2", 2: "3", length: 3 };

const arr = Array.prototype.slice.apply(noArr);

console.log(arr); // [1, 2, 3]

하지만 ES6 문법으로 Array.form으로 대체가 가능하기도 합니다.

const noArr = { 0: "1", 1: "2", 2: "3", length: 3 };

const arr = Array.from(noArr);

console.log(arr); // [1, 2, 3]

마무리

this에 대해 살펴봤습니다!
다음 게시글에선 실행 컨텍스트와 클로저에 대해 살펴보겠습니다🙂

출처

  • 인사이드 자바스크립트
profile
프론트엔드 개발자

1개의 댓글

comment-user-thumbnail
2021년 1월 2일

매번 글 보면서 자바스크립트 배우고싶다는 생각을 갖게됐어요!

답글 달기