[JS] 자바스크립트에서의 this

Seju·2023년 7월 12일
1

JavaScript

목록 보기
20/28
post-thumbnail

자바스크립트에서의 this

서론


😤 자바스크립트에서의 this
호출하는 방법에 의해 결정된다 이글에서 제대로 알아보고자 작성한다.


🚠 일반 함수에서의 This


  • 자바스크립트에서 함수객체 그 중에서도 일급 객체이다
//함수 선언문에서의 this
function phone() {
  return this;
}

phone1(); //Window 전역객체를 참조

//함수 표현식에서의 this
const phone2 = function () {
  return this;
};

phone2(); //Window 전역객체를 참조

//함수 표현식에서 내부 함수에서의 this
const phone3 = function () {
  function insideFunction() {
    console.log(this);// Window 전역객체를 참조
  }
  insideFunction();
};

phone3();

phone() 함수선언 후 함수 호출시 this는 전역객체 즉, window를 참조한다

🚨 주의!
함수 호출에서 엄격모드에서 this값은 전역객체(=window)를 바인딩하지 않는다

function phone() {
  'use strict';
  return this; //undefined
}

🧑‍🚀 객체 메서드에서의 this


  • 객체메서드에서의 this는 메서드를 호출한 객체, 즉 자신의 상위객체를 가리킨다.
  • MDN에선 객체의 메서드의 this를 함수를 어떤 객체의 메소드로 호출하면 this의 값은 그 객체를 사용한다라고 명시되어 있다.
  • 메서드안에서 this 사용은 보통 객체의 프로퍼티에 접근하기 위해 사용된다.
const object = {
  name: 'seju',
  // concise 함수
  sayMyName() {
    return this.name;
  },
};

console.log(object.sayMyName()); //"seju" ➡️ 자신의 상위객체인 object의 name을 반환
  • 다른 예시를 하나 더 확인해보자
function main() {
  console.log(this);
}

const object = {
  name: 'seju',
  main: main
};

const object2 = {
  name: '다른 객체',
  main: main
};
  • 이경우엔 objectobject2this는 어떤걸 가르키는걸까?

여기서도 객체 메서드인 main이 각기 다른 자기 상위 객체를 this로 참조하고 있다

🌴 화살표 함수에서의 this

  • 자신만의 this를 가지지않는다. (=this를 바인딩하지않는다)
  • 화살표함수 내부에서 this에 접근하면 상위 컨텍스트에서 this를 가져온다
const object = {
  name: 'seju',
  arrowFunc: () => {
    console.log(this);
  },
};

object.arrowFunc() // Window 전역 객체

객체의 메서드를 화살표함수로 표현한경우, 화살표함수의 this가 전역객체의 this를 참조하고 있다

  • 위 코드에서 볼 수 있듯이 화살표함수는 자신만의 this와 다르게, 자신을 감싸고 있는 스코프로 올라가서 this를 찾게되고, 그 this를 사용한다.
  • 저경우 this는 자신의 상위컨텍스트인 window를 참조하게된다.

만약
일반함수로 선언된 메서드 내부에서의 화살표함수는 어떤것을 가르킬까?

일반 함수내부에서 화살표함수로의 this

const obj = {
  name: "seju",
  sayMyName() {
    console.log(this); // this => obj 객체

    const arrowFunc = () => {
      console.log(this); // ???
    };
    arrowFunc();
  },
};

obj.sayMyName()
  • 화살표함수는 상위컨텍스트를 참조하기때문에, 해당 화살표함수에서의 상위컨텍스트, 즉 sayMyName() 메서드를 상위컨텍스트로 인식하게되는데, 여기서 sayMyName()obj를 참조하고 있기때문에 화살표함수의 thisobj를 가르키게된다

화살표함수가 자신의 상위컨텍스트인 sayMyName()을 가르키고 있는 모습


🦁 생성자 함수에서의 this


  • 생성자 함수 내부에서의 this해당 생성자 함수를 이용해 생성되는 신규 객체를 참조한다.
function Person(name, age) {
  this.name = name;
  this.age = age;

  this.introduce = function() {
    console.log("안녕하세요, 제 이름은 " + this.name + "이고, 나이는 " + this.age + "살 입니다.");
  }
}

const person1 = new Person("철수", 27);
const person2 = new Person("영희", 24);

person1.introduce(); 
person2.introduce(); 

생성자 함수로 생성된 각자의 다른 객체가 각각의 다른 this를 참조하고 있다.


🎁 이벤트핸들러에서의 this


addEventListener() 안에서의 일반함수

  • 먼저 addEventListener()에서콜백함수로 일반함수를 전달했을때는 무엇이 나올까?

//first라는 class를 가진 span 노드가 존재하는 상태
const first = document.querySelector('.first');

first.addEventListener('click',function() {
  console.log(this); //???
});

콜백함수로 일반함수로 this를 확인해봤을때, 클릭이벤트의 결과로 클릭한 요소가 출력된 모습

addEventListener() 안에서의 화살표함수

  • addEventListener()에서 콜백함수로 익명의 화살표함수로 전달했을경우의 this를 확인해보자

//first라는 class를 가진 span 노드가 존재하는 상태
const first = document.querySelector('.first');

first.addEventListener('click', () => {
  console.log(this); //???
});

콜백함수로 익명 화살표함수에서의 this를 확인했을때, 전역객체가 나오는 모습

그러면 화살표함수는 window를 참조하니깐 요소를 가져올수 없나요?

  • 정답은 화살표함수를 사용해도 가져올 수 있다
  • addEventListener()메서드는 메서드내에 이벤트 객체가 존재하는데 이벤트 객체는 해당 이벤트 핸들러의 첫번째 파라미터로 전달된다.
  • 이벤트 객체에는 이벤트의 type(click인지 mousedown인지 등등...)
    대상(target), 발생 지점등의 정보를 가지고 있는데,
    여기서의 대상(target)을 참조하면 클릭시 화살표함수에서도 해당 요소를 찾을 수 있게된다

const first = document.querySelector('.first');

//화살표함수에서의 e.target으로 요소를 출력할 수 있을까?
const printThis = (e) => {
  console.log(e.target);
};

first.addEventListener('click', printThis);

해당 first 라는 node를 클릭하면? 💁‍♂️

화살표함수 내부에서의 e.target으로 클릭한 요소를 찾을 수 있다


🐘 마치며..

javascript에서의 this는 객체의 메서드일때 달라지고, 일반함수일때 달라지고, 이벤트의 호출대상일때도 달라지고 경우의 수가많아 헷갈릴 수도 있습니다 하지만 흐름을 이해한다면 this가 무섭지 않을겁니다
또, 해당 내용중에서 수정이 필요한 부분이 있으면 언제든지 댓글 달아주시면 감사하겠습니다 🙇‍♂️

profile
Talk is cheap. Show me the code.

0개의 댓글