Study/JavaScript

JavaScript [메서드와 this]

maino77 2021. 9. 3. 17:25

객체는 사용자, 주문 등과 같이 실제 존재하는 개체를 표현하고자 할 때 생성됩니다.

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

사용자는 현실에서 장바구니에서 물건 선택하기, 로그인하기, 로그아웃하기 등의 행동을 합니다. 이와 마찬가지로 객체도 특정한 행동을 할 수 있습니다.

자바스크립트에선 객체의 프로퍼티에 함수를 할당해 객체에 행동할 수 있는 능력을 부여해줍니다. 우리는 이를 일반적인 함수와 구분짓기 위해 메서드라고 부릅니다.

즉, 객체 안에 있는 함수를 메서드라고 합니다.

 

 

매서드 만들기

객체에게 인사할 수 있는 능력을 부여해줍시다.

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

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

user.sayHi(); // 안녕하세요!

함수 표현식으로 함수를 만들고, 객체 프로퍼티 user.sayHi에 함수를 할당해주었습니다.

그러면 이제 객체에 할당된 함수를 호출하면 user가 인사를 해줍니다.

이렇게 객체 프로퍼티에 할당된 함수를 매서드라고 부릅니다.

위 예시에선 user에 할당된 sayHi가 메서드입니다.

또한 메서드는 이미 정의된 함수를 이용해서 만들 수 있습니다.

let user = {
 //....
 }
 
 // 함수선언
 function sayHi() {
  	alert("안녕하세요!");
    };
    
  // 선언된 함수를 메서드로 등록
  user.sayHi = sayHi;
  
  user.sayHi(); // 안녕하세요
❗ 객체 지향 프로그램

객체를 사용하여 개체를 표현하는 방식을 객체 지향 프로그래밍(OPP)이라 부릅니다.

OOP는 그 자체만으로도 학문의 분야를 만드는 중요한 주제입니다. 올바른 개체를 선택하는 방법, 개체 사이의 상호작용을 나타내는 방법 등에 관한 의사결정은 객체 지향 설계를 기반으로 이뤄집니다.

 

 

메서드 단축 구문

객체 리터럴(리터럴: 코드상에서 데이터를 표현하는 방식을 리터럴이라 합니다.) 안에 메서드를 선어날 때 사용할 수 있는 단축 문법은 다음과 같습니다.

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

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

// 단축 구문을 사용하니 더 깔끔해 보이네요.
user = {
  sayHi() { // "sayHi: function()"과 동일합니다.
    alert("Hello");
  }
};

위처럼 fuction을 생략해도 메서드를 정의할 수 있습니다.

 

 

메서드와 this

메서드는 객체에 저장된 정보에 접근할 수 있어야 제 역할을 할 수 있습니다. 대부분의 메서드가 객체 프로퍼티의 값을 활용합니다.

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

메서드 내부에서 this 키워드를 사용하면 객체에 접근할 수 있습니다.

이때 '점 앞'의 this는 객체를 나타냅니다. 정확히는 메서드를 호출할 때 사용된 객체를 나타냅니다.

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

user.sayHi(); // John

user.sayHi()가 실행되는 동안에 this는 user를 나타냅니다.

this를 사용하지 않고 외부 변수를 참조해 객체에 접근하는 것도 가능합니다.

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

  sayHi() {
    alert(user.name); // 'this' 대신 'user'를 이용함
  }

};

그런데 이렇게 외부 변수를 사용해 객체를 참조하면 예상치 못한 에러가 발생할 수 있습니다. user를 복사해 다른 변수에 할당(admin = user)하고, user는 전혀 다른 값으로 덮어썼다고 가정하면 sayHi()는 에러가 날 것입니다.

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 (점과 대괄호는 동일하게 동작함)

user와 admin의 객체를 생성하고 sayHi 함수를 각 객체에 넣어준 뒤 호출하면 각 객체에 맞는 name을 가져온다.

❗ 객체 없이 호출하기: this == undefined

객체가 없어도 함수를 호출할 수 있습니다.
function sayHi() {
  alert(this);
}

sayHi(); // undefined​

위 코드를 엄격모드에서 실행하면 undefined가 할당됩니다.

엄격모드가 아닐 때는 window라는 전역 객체를 참조합니다.

 

 

this가 없는 화살표 함수

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

아래 예시에서 함수 arrow() 의 this 는 외부 함수 user.sayHi() 의 this가 됩니다.

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

user.sayHi(); // 보라

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

 

 

* 요약 *

  • 객체 안에 있는 함수는 메서드라고 합니다.
  • object.doSomthing()은 객체를 '행동'할 수 있게 해줍니다.
  • 메서드는 this로 객체를 참조합니다.

this 값은 런타임에 결정됩니다.

  • 함수를 선언할 때 this를 사용할 수 있습니다. 다만, 함수가 호출되지 전까지 this엔 값이 할당되지 않습니다.
  • 함수를 선언한 뒤 개체에 추가할 수 있스빈다.
  • 함수를 객체 프로퍼티에 저장해 메서드 형태로 호출하면 this는 객체를 참조합니다.

 

728x90