Frontend/JavaScript

[js] this (feat. arrow function)

양원준 2024. 6. 16. 18:08
728x90

 

js에서 this는 자바와 같은 일반 프로그래밍 언어와 다르게 특이하게 작동한다.

js에서 this는 현재 실행 중인 코드에서 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수이다. 다만, 함수 호출 방식에 따라 동적으로 결정된다. 함수를 선언할 때 this가 결정되는 것이 아닌 함수를 호출할 때 this가 결정된다는 의미

 

함수를 어디서 호출하느냐에 따라 그 의미가 달라지기 때문에 좀 세분화 해보았다(굉장히 오묘하게 작동하긴한다..js 개발자가 오류라고 인정했다는,.)

 

this 바인딩

  1. 전역 컨텍스트: 전역 범위에서 this는 전역 객체를 참조(브라우저에서는 window 객체)
  2. 일반 함수 호출: 일반 함수 호출 시, this는 전역 객체를 참조(엄격 모드에서는 undefined)
  3. 생성자 호출: 생성자 함수로 호출될 때, this는 새로 생성된 객체를 참조
  4. 메서드 호출: 객체의 메서드로 호출될 때, this는 해당 객체를 참조
  5. 이밴트 핸들러 내부: 이벤트가 발생한 요소를 참조
  6. 메서드 내부 함수 호출: this는 전역 객체를 참조(일반 함수 취급)
  7. 화살표 함수: 자신의 this 바인딩을 가지지 않고, 정의된 렉시컬 환경의 this를 상속

 

보통 4가지 정도의 경우로 나눠서 설명하든데 이해가 잘안가 좀 더 분류를 해서 나누어보았다

사실 1~5번까지는 그래도 익숙한? 느낌이긴하다

//1. 전역컨택스트
console.log(this); // window 


//2. 일반 함수
function showThis() {
    console.log(this);
}

showThis(); // window (엄격 모드에서는 undefined)

//3. 생성자
function Person(name) {
    this.name = name;
}

const yang = new Person('yang');
console.log(yang.name); // "yang"

//4. 메서드
const person = {
    name: 'yang',
    greet: function() {
        console.log(this.name);
    }
};

person.greet(); // "yang"


//5. 이벤트 핸들러
const button = document.querySelector('button');

button.addEventListener('click', function() {
    console.log(this); // 클릭된 버튼 요소 == e.target
});

 

그럼 다음 경우부터 자세히 살펴보자

 

 

 

6. 메서드 내부 함수 호출: this는 전역 객체를 참조(일반 함수 취급)

먼저, 메서드와 일반 함수는 같은 함수이지만 약간 다른 정의를 가지고 있다

  • 메서드: 객체의 속성으로 정의된 함수
  • 일반 함수: 독립적인 함수
//메서드
const person = {
    name: 'yang',
    greet: function() {
        console.log(this.name);
    }
};
person.greet() // 'yang'

//메서드 내부 함수
const person = {
    name: 'yang',
    greet: function() {
        function innerFunc() {
            console.log(this.name); 
        }
        innerFunc();
    }
};

person.greet(); // window

 

  • 메서드는 객체의 속성으로 호출될 때, this가 그 객체를 가리키기 때문에, 메서드가 속한 객체를 참조하지만,
  • 메서드 내부 함수는 일반 함수 호출로 간주되기 때문에, this는 전역 객체를 참조 --> 이는 내부 함수가 메서드와 독립적으로 호출되기 때문이다

 

7. 화살표 함수

먼저, 화살표 함수는 다음과 같은 특징이 있다

  • 무조건 익명함수로만 사용 가능
  • 생성자 함수 사용 불가
  • 스스로의 this, argument가 없다
  • 함수가 정의된 스코프에 존재하는 this 가르킴

결국, 화살표 함수는 자신만의 this 바인딩을 가지지 않는다.

그래서 일반 함수는 호출 시점에 this가 결정되는 반면, 화살표 함수는 정의 시점에 상위 스코프의 this를 상속받는다

//메서드 내부 함수
const person = {
    name: 'yang',
    greet: function() {
        function innerFunc() {
            console.log(this.name); 
        }
        innerFunc();
    }
};

person.greet(); // window

//메서드에 화살표 함수
const person = {
    name: 'yang',
    greet: function() {
        const innerFunc = () => {
            console.log(this.name);
        }
        innerFunc();
    }
};

person.greet(); // "yang" 출력

 

 

일반 함수는 호출 시점에 this가 결정되며, 전역 객체를 참조할 수 있다.

반면, 화살표 함수는 정의 시점에 상위 스코프의 this를 상속받아 항상 부모 컨텍스트의 this를 사용한다. (화살표 함수의 this는 상위 스코프를 따른다고 외우면 편할듯 싶다!)

 

 

 

728x90