js에서의 this

피자냠냠(피자냠냠)·2023년 1월 11일
0

JavaScript

목록 보기
15/16

메서드와 this


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

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

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

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

  sayHi() {
    *// this는 현재 객체를 나타냅니다.
    console.log(this.name);*}
};

user.sayHi(); // John

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

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

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

user.sayHi() // john

user는 전혀 다른 값으로 덮어썼다고 가정해 봅시다. 

sayHi()는 원치 않는 값(null)을 참조할 겁니다.
예시:


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

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

자유로운 this가 만드는 결과

다른 언어를 사용하다 자바스크립트로 넘어온 개발자는 this를 혼동하기 쉽습니다. this는 항상 메서드가 정의된 객체를 참조할 것이라고 착각하죠. 이런 개념을 'bound this'라고 합니다.
자바스크립트에서 this는 런타임에 결정됩니다. 메서드가 어디서 정의되었는지에 상관없이 this는 ‘점 앞의’ 객체가 무엇인가에 따라 ‘자유롭게’ 결정됩니다.
이렇게 this가 런타임에 결정되면 좋은 점도 있고 나쁜 점도 있습니다. 함수(메서드)를 하나만 만들어 여러 객체에서 재사용할 수 있다는 것은 장점이지만, 이런 유연함이 실수로 이어질 수 있다는 것은 단점입니다.
자바스크립트가 this를 다루는 방식이 좋은지, 나쁜지는 우리가 판단할 문제가 아닙니다. 개발자는 this의 동작 방식을 충분히 이해하고 장점을 취하면서 실수를 피하는 데만 집중하면 됩니다.

this가 없는 화살표 함수


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

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

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

user.sayHi(); // undefined // this === sayHi

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

user.sayHi(); // 보라 // this === user 

별개의 this가 만들어지는 건 원하지 않고, 외부 컨텍스트에 있는 this를 이용하고 싶은 경우 화살표 함수가 유용합니다. 이에 대한 자세한 내용은 별도의 챕터, 화살표 함수 다시 살펴보기에서 다루겠습니다.

요약


  • 메서드는 this로 객체를 참조합니다.
  • this 값은 런타임에 결정됩니다.
  • 함수를 선언할 때 this를 사용할 수 있습니다. 다만, 함수가 호출되기 전까지 this엔 값이 할당되지 않습니다.
    • 함수를 복사해 객체 간 전달할 수 있습니다.
  • 함수를 객체 프로퍼티에 저장해 object.method()같이 ‘메서드’ 형태로 호출하면 this는 object를 참조합니다.
    • 화살표 함수는 자신만의 this를 가지지 않는다는 점에서 독특합니다. 화살표 함수 안에서 this를 사용하면, 외부에서 this 값을 가져옵니다.
profile
교사에서 개발자로

0개의 댓글