메서드와 this

kevin kim·2020년 6월 21일
0

객체는 실제 존재하는 개체(entity)를 표현하고자 할 때 생성된다.

let user = {
  name: "John",
  age: 30
};

위와 같은 객체가 있다고 가정하면, 자바스크립트에서는 객체의 프로퍼티에 함수를 할당하여, 객체에게 행동할 수 있는 능력을 부여해준다.

메서드 만들기

let user = {
  name: "John",
  age: 30
};

user.sayHi = function() {
  alert("Hello");
};

user.sayHi(); // Hello

위의 코드를 살펴보면 함수 표현식으로 함수를 만들고, 객체 프로퍼티 user.sayHi에 함수를 할당해 주었다.
이제 객체에 할당된 함수를 호출하면 user가 'Hello'라는 응답을 한다.
이렇게 객체 프로퍼티에 할당된 함수를 메서드(method)라고 부른다.
위의 코드에서는 user에 할당된 sayHi가 메서드이다.

또 메서드는 이미 정의된 함수를 이용해서 만들 수도 있다.
아래의 코드를 보자.

let user = {
  name: "John",
  age: 30
};

// 함수 선언
function sayHi() {
  alert('Hello');
}

// 선언된 함수를 메서드로 등록
user.sayHi = sayHi;

user.sayHi(); // Hello

🧐객체 지향 프로그래밍
객체를 사용하여 개체를 표현하는 방식객체 지향 프로그래밍(object-oriented programming, OOP) 이라 부른다.
OOP는 그 자체만으로도 학문의 분야를 만드는 중요한 주제이다. 올바른 개체를 선택하는 방법, 개체 사이의 상호작용을 나타내는 방법 등에 관한 의사결정은 객체 지향 설계를 기반으로 이뤄진다.

메서드와 'this'

메서드는 객체에 저장된 정보에 접근할 수 있어야 제 역할을 할 수 있다. 모든 메서드가 그런건 아니지만, 대부분의 메서드가 객체 프로퍼티의 값을 활용한다.
메서드 내부에서 this 키워드를 사용하면 객체에 접근할 수 있다.

let user = {
  name: "John",
  age: 30,
  
  sayHi() {
    // this 는 '현재 객체'를 나타낸다.
    alert(this.name);
  }
};

user.sayHi(); // John

user.sayHi()가 실행되는 동안에 thisuser를 나타낸다.
this를 사용하지 않고 외부 변수를 참조해 객체에 접근하는 것도 가능하다.

let user = {
  name: "John",
  age: 30
  
  sayHi() {
    alert(user.name); // 'this' 대신 'user'를 이용함
  }
};

이렇게 외부 변수를 사용해 객체를 참조하면 예상치 못한 에러가 발생할 수 있다. user를 복사해 다른 변수에 할당하고, user는 전혀 다른 값으로 덮어썼다고 가정해 보자. sayHi()는 원치 않는 값(null)을 참조할 것이다.

let user = {
  name: "John",
  age: 30
  
  sayHi() {
    alert(user.name); // Error: Cannot read property 'name' of null
  }
};

let admin = user;
user = null; // user를 null로 덮어쓴다.

admin.sayHi(); // sayHi()가 엉뚱한 객체를 참조하면서 에러가 발생

여기에서 alert 함수가 user.name 대신 this.name을 인수로 받았다면 에러가 발생하지 않았을 것이다.

자유로운 'this'

자바스크립트의 this는 다른 프로그래밍 언어의 this와 동작 방식이 다르다. 자바스크립트에서는 모든 함수에 this를 사용할 수 있다.

function sayHi() {
  alert(this.name);
}

이렇게 코드를 작성해도 문법 에러가 발생하지 않는다.
this 값은 런타임에 결정된다. 컨텍스트에 따라 달라지는 것이다.
동일한 함수라도 다른 객체에서 호출했다면 'this'가 참조하는 값이 달라진다.

let user = { name: "John" };
let admin = { name: "Admin" };

function sayHi() {
  alert(this.name);
}

// 별개의 객체에서 동일한 함수를 사용함
user.f = sayHi;
admin.f = sayHi;

user.f(); // John (this === user)
admin.f(); // Admin (this === admin)

admin['f'](); // Admin (점과 대괄호는 동일하게 동작)

규칙은 간단하다. obj.f()를 호출했다면 thisf를 호출하는 동안의 obj이다. 위 예시에서는 objuseradmin을 참조하는 것이다.

'this'가 없는 화살표 함수

화살표 함수는 일반 함수와는 달리 고유한 this를 가지지 않는다. 화살표 함수에서 this를 참조하면, 화살표 함수가 아닌 평범한 외부 함수에서 this 값을 가져온다.

let user = {
  firstName: "Kevin",
  sayHi() {
    let arrow = () => alert(this.firstName);
    arrow();
  }
};
user.sayHi(); // Kevin

별개의 this가 만들어지는 건 원하지 않고, 외부 컨텍스트에 있는 this를 이용하고 싶은 경우 화살표 함수가 유용하다.

profile
프론트엔드 개발자

0개의 댓글