this는 기본적으로 window를 말한다 일반 함수 내에서 혼자 this를 선언하면 그 this는 window 객체를 가르킨다.
일반 함수가 아니라면??
객체 메서드 a 안의 this는 obj를 가리킨다. 왜?? 객체의 메서드를 호출할 때 this를 내부적으로 바꿔주기 때문이다
let obj = {
a: function () {
console.log(this);
},
};
obj.a(); // obj
여기서 바꿔준다는 표현은 호출 방식에 따라서 달라진다는 것을 의미한다.
a 를 실행하는 동안 해당 함수의 실행 컨텍스트에서는 this 는 obj 를 가리킴var a2 = obj.a;
a2(); // window
반면에 이렇게 코드를 작성하면 a2는 obj.a 를 꺼내온 것이기 때문에 더 이상 obj의 메서드가 아니라고 인식을 한다.
즉 호출할 때, 호출하는 함수가 객체의 메서드인지, 그냥 함수인지가 중요하다. 자바와는 다르게 JS에서 this 가 가리키는 값은 함수가 호출되는 방식 에 따라 동적으로 결정되는 것
obj.a() 를 호출할 때, this는 a 메서드를 호출한 객체은 obj를 가리킨다.
즉, 점(.) 연산자나 대괄호 [] 를 통해 호출하면 해당 객체가 this 로 설정됩니다. 여기서 자바스크립트는 내부적으로 호출 객체를 this 로 바인딩한다
let a2 = obj.a; // 메서드를 변수로 복사
a2(); // window (브라우저 환경), undefined (strict 모드)
a2는 obj.a 의 참조 주소만 복사한 것이다. a2는 독립적인 함수로 취급 되기 때문에 이때 a2() 를 호출하면 메서드 호출이 아니라 일반 함수 호출로 간주된다.
자바스크립트는 this 를 메서드 정의 시점이 아니라 호출 시점 에 결정한다. a2()는 독립적인 함수로 호출되었으므로, this와 obj 와는 무관해짐
가장 결정적인 것은 호출 방식 obj.a() 처럼 객체를 통해 호출하면 this는 해당 객체를 가리킨다. a2() 처럼 독립적인 함수 호출이면, this 는 기본적으로 전역 객체를 가리킴
여기서 한 가지 예외가 있는데 화살표 함수 이다. 화살표 함수는 this 를 정의된 위치의 상위 스코프에서 상속한다. 호출 방식에 영향을 받지 않으므로 다르게 동작할 수 있음
Java에서는 this는 인스턴스 자신(self) 을 가리키는 참조변수인데, 자바스크립트 같은 경우 this에 바인딩되는 객체는 한가지로 고정되는 것이 아니라 달라질 수 있다는 점
기본적으로 this는 전역객체(Global object)에 바인딩된다.
일반 전역 함수는 물론이고 내부함수의 경우도 this는 외부함수가 아닌 전역 객체에 바인딩된다. 자바스크립트에서는 함수 내부의 또 다른 내부함수는 this를 자동으로 부모함수의 this로 상속받지 않는다.
function foo() {
console.log("foo's this: ", this); // window
function bar() {
console.log("bar's this: ", this); // window
}
bar();
}
foo();
마찬가지로 콜백 함수의 경우에도 this는 전역객체에 바인딩된다. 콜백 함수는 별도의 컨텍스트에서 실행되기 때문이다
내부함수의 this가 전역객체를 참조하는 것을 회피하는 방법은 아래와 같은데,
화살표 함수를 사용하면 된다. 화살표 함수는 this 를 상위 스코프에서 상속받기 때문
let obj = {
value: 10,
method: function () {
console.log(this.value); // 10
const inner = () => {
console.log(this.value); // 10
};
inner();
},
};
obj.method();
화살표 함수에서는 this 가 동적으로 설정되지 않고 정의된 위치의 this 를 유지한다.
이외에도 bind,call,apply 등등 으로 회피할 수 있지만 현재는 화살표 함수로 대체하고 있다. 가장 현대적인 방법
this 는 자바스크립트에서 함수가 호출되는 방식에 따라 동적으로 바인딩되는 특성을 가진다. 이를 이해하는 것은 객체 지향적인 코드 작성뿐만 아니라 콜백 함수, 내부 함수, 화살표 함수 등 다양한 상황에서 의도한 대로 코드를 동작하게 만드는 데 중요하다.
전역 함수에서의 this는 브라우저 환경에서는 window, Node.js 환경에서는 global을 참조한다.
obj.a()처럼 객체를 통해 호출하면 this는 해당 객체를 참조한다.
하지만, 메서드를 변수에 할당하거나, 함수로 독립적으로 호출하면 this는 다시 전역 객체를 가리킨다.
일반 함수 내의 내부 함수에서 this는 상위 함수가 아닌 전역 객체를 가리킨다.
이를 해결하기 위해 bind, call, apply와 같은 명시적인 바인딩 방법을 사용하거나, 화살표 함수를 활용하여 상위 스코프의 this를 상속받을 수 있다.
화살표 함수는 호출 방식에 관계없이 상위 스코프의 this를 유지한다. 따라서 객체 메서드나 콜백 함수에서 의도치 않은 this 바인딩 문제를 해결하는 가장 현대적인 방법이다.
자바의 this는 객체 인스턴스를 고정적으로 가리키는 반면, 자바스크립트의 this는 함수 호출 방식에 따라 달라지므로 더 유연하지만, 예측하기 어렵다는 단점이 있다.