메서드와 'this'- JavaScript 객체

Christy·2020년 9월 13일
0

Today I Learn

목록 보기
1/3
post-thumbnail

객체지향프로그래밍 함수에 대해 학습을 하면서, 먼저 언제나 쓰인다는 'this'에 대해 정리해본다.

메서드

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

객체는 사용자(user), 주문(order)등과 같이 실제 존재하는 개체(entity)를 표현하고자 할때 생성된다.
객체, 사용자(user)의 현실적 쓰임은 '장바구니에서 물건 선택하기, 로그인하기, 로그아웃하기' 등의 action을 취한다.

메서드 만들기

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

user.sayHi = function() {
  alert("안녕하세요!");
  
 user.sayHi(); //안녕하세요!

위의 함수표현식에서 객체 property user.sayHi에 함수를 할당해 주었다.
이렇게 객체 property에 할당된 함수를 메서드(method)라고 부른다.
즉, user에 할당된 sayHi가 메서드이다.

let user = {
// ...
};

//함수 선언
function sayHi() {
  alert("안녕하세요!");
  };
  
  //선언된 함수를 메서드로 등록
  user.sayHi = sayHi;
  
  usr.sayHi(); //안녕하세요!

메서드는 이미 정의된 함수를 위와 같이 이용해서 만들 수 있다.

메서드 단축 구문

//아래 두 객체는 동일하게 동작한다.

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

//단축 구문을 사용하니 코드가 더 간단해진다.
user = {
  sayHi() {
    alert("Hello");
  }
};

function를 생략해도 메서드를 정의할 수 있다.
하지만 좀더 깊이 알아봐야 할것은 일반적인 방법과 단축 구문을 사용한 방법이 완전히 동일하진 않다.

메서드와 'this'

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

user.sayHi()의 내부 코드에서 객체 user에 저장된 이름(name)을 이용해 인사말을 만드는 경우가 이런경우에 속한다.

메서드 내부에서 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를 복사해 다른 변수에 할당 (admin = 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;

//'this'는 '점(.)앞의' 객체를 참조하기 때문에
// this값이 달라짐
user.f(); // John (this === user)
admin.f(); // Admin (this === admin)

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

obj.f()를 호출했다면 thisf를 호출하는 동안의 obj이다. 위 예시에선 objuseradmin를 참조했다.

객체가 없어도 함수를 호출할 수 있다.

function sayHi() {
  alert(this);
}

sayHi(); // undefined

자바스크립트에서 this는 런타임에 결정된다. 메서드가 어디서 정의되었는지에 상관없이 this는 '점 앞의'객체가 무엇인가에 따라 '자유롭게' 결정된다.

이렇게 this가 런타임에 결정되면 좋은 점도 있고 나쁜 점도 있다. 함수(메서드)를 하나만 만들어 여러객체에서 재사용할 수 있다는 것은 장점이지만, 이런 유연함이 실수로 이어질 수 있다는 것은 단점이다.

자바스크립트가 this를 다루는 방식이 좋은지, 나쁜지는 우리가 판단할 문제가 아니다. 개발자는 this의 동작 방식을 충분히 이해하고 장점을 취하면서 실수를 피하는 데에만 집중하면 된다.

요약하면

  • 객체 프로퍼티에 저장된 함수를 '메서드'라고 부른다.
  • object.doSomthig()은 객체를 '행동'할 수 있게 해준다.
  • 메서드는 this로 객체를 참조한다.

this값은 런타임에 결정된다.

  • 함수를 선언할 때 this를 사용할 수 있다. 다만, 함수가 호출 되기 전까지 this엔 값이 할당되지 않는다.
  • 함수를 복사해 객체 간 전달할 수 있다.
  • 함수를 객체 프로퍼티에 저장해 object.method()같이 '메서드'형태로 호출하면 thisobject를 참조한다.

0개의 댓글