스터디원들과 JavaScript this에 대해 이야기하다가 의문점이 풀리지 않아서 ChatCPT와 100분 토론을 했다.
생각보다 멍청한 자식..이었지만 구글링의 수고를 덜어줘서 고마웠다. 잘못된 정보도 있어서 여러 블로그도 함께 참고했다.
JavaScript에서 현재 실행되고 있는 함수의 컨텍스트를 참조 (= 함수 내에서 현재 객체를 참조)하는 특별한 키워드이다.
함수 내부에서 사용되며, 함수가 호출되는 방식에 따라 동적으로 결정된다.
일반적으로 this는 객체 지향 프로그래밍에서 객체를 참조할 때 사용되는 개념입니다. this는 현재 실행되고 있는 메서드가 속한 객체를 가리키는 참조 변수로 사용됩니다. 객체 내부에서 메서드가 호출될 때, 메서드 내부에서 this 키워드를 사용하면 해당 메서드를 호출한 객체를 참조할 수 있습니다.
각 호출 방법에 따라 this가 가리키는 객체가 결정된다.
예를 들어, 함수 호출 방식으로 함수를 호출하면 this는 전역 객체를 가리키지만, 메소드 호출 방식으로 함수를 호출하면 this는 해당 메소드를 소유하는 객체를 가리킨다.
또한, Arrow Function에서는 this가 상위 스코프의 this를 따르기 때문에 함수 호출 방식에 따라 this값이 결정되는 일반 함수와는 달리 this값이 고정된다.
this를 사용할 때는 호출 방법에 따라서 this값이 어떻게 결정되는지 잘 파악해야 한다.
const obj = {
name: "John",
sayName: function() {
console.log(this.name); // this
},
obj2: {
name: "Sarah",
sayName: function() {
console.log(this.name); //this
}
}
};
const sayName = obj.sayName;
const sayName2 = obj.obj2.sayName;
sayName(); // undefined
sayName2(); // undefined
obj.sayName(); // John
obj.sayName(); // Sarah
obj.sayName()
과 같이 메서드가 속한 객체를 명시적으로 지정하여 호출하면 this가 obj를 가르키게 된다.Arrow Function는 일반 함수와는 다르게 자신만의 this 컨텍스트를 가지지 않는다. 그 이유는 화살표 함수가 생성될 때 this를 lexical적으로 상위 스코프의 this 값으로 캡처하기 때문이다.
화살표 함수가 자신만의 this 컨텍스트를 가지지 않고, 대신 부모 함수의 this 값을 가져오는 방식을 말한다. 이렇게 캡처된 this는 화살표 함수가 실행될 때 어디에서 호출되든 항상 같은 값을 가진다.
lexical적이란 해당 변수 또는 함수가 선언된 위치에 따라 유효 범위가 결정되는 것을 의미한다. 즉, lexical this라는 말은 this값이 현재 함수의 lexical scope에 의해 결정된다는 말이다.
다시 정리하자면 Arrow Function의 this는 렉시컬 스코프를 따른다. 즉, 상위 스코프의 this를 자동으로 참조하는 것이다.
그러니까, Lexical scope가 함수가 선언된 위치에 따라 유효범위가 결정되는 것처럼 Lexical this는 함수가 선언된 위치에 따라 this가 결정된다. 따라서 Arrow Function이 선언된 상위 스코프에서의 this 값을 유지한다.
잊지 말아야할 점은 일반함수에서 this는 함수를 호출한 객체에 따라 결정된다.
const person = {
name: "John",
sayHi: function() {
console.log(`Hi, my name is ${this.name}`);
},
sayHiArrow: () => {
console.log(`Hi, my name is ${this.name}`);
}
};
person.sayHi(); // Output: Hi, my name is John
person.sayHiArrow(); // Output: Hi, my name is undefined
this
를 참조하고 있기 때문에, person
객체가 아닌 (화살표함수가 선언되어있는) 객체, 즉 상위스코프의 this를 상속받고 이것이 전역객체인 것이다.맞다. 상위 스코프는 렉시컬 스코프보다 상위 개념이다. 렉시컬 스코프는 함수가 선언된 위치에 따라 정의되는 스코프이고, 상위 스코프는 현재 스코프를 둘러싸는 스코프 중 가장 가까운 스코프를 말한다. 함수의 렉시컬 스코프에는 해당 함수를 감싸는 상위 스코프가 포함되어 있다.
맞다. 정확히는 "결과"이다. 좀 더 정확하게 말하면, 화살표 함수의 내부 동작 메커니즘이 일반 함수와 다르기 때문에, 화살표 함수는 this를 바인딩하지 않는다. 이러한 결과가 발생하는 이유는 내부 메커니즘이 복잡하고 다양하기 때문인데, 이는 앞서 제가 설명해드린 대로, 화살표 함수가 Lexical this를 사용하기 때문이다.
자바스크립트에서 this는 함수가 호출될 때, 호출한 객체에 따라 동적으로 결정된다.
그러나 화살표 함수에서는 this가 선언될 때 결정되며, 선언된 위치의 Lexical Scope에서 값을 참조한다.
따라서, 화살표 함수 내에서 this를 사용할 경우, 전역 객체(Global Object)를 참조할 가능성이 있으므로 주의해야 한다.
또한, 일반 함수에서의 this는 함수를 호출한 객체에 따라 동적으로 결정되는 반면, 메서드 호출 시 메서드가 속한 객체를 명시적으로 지정하여 호출하면 this가 해당 객체를 가리키게 된다.
렉시컬 스코프는 함수를 어디서 호출하느냐가 아닌 함수를 어디에 선언하느냐에 따라 결정되는 스코프이며, 상위 스코프와 관계가 있다.
미안해 ChatGPT