DeepDive this
this
의 값 결정 방식
자바스크립트에서 this
의 값은 대부분 함수가 호출되는 방식에 의해 결정.
- 함수 실행 중에
this
의 값을 할당은 불가능 this
의 컨텍스트는.call()
,.apply()
,.bind()
메서드를 통해 변경 가능- 기본적으로
this
의 값은 함수를 호출하는 객체의 값과 같다.
1.전역 컨텍스트에서의 this
함수가 전역 범위에서 실행될 때, this
의 값은 window
객체
- 엄격 모드(
strict mode
)에서는 전역 컨텍스트에서this
의 값이undefined
가 됩니다.
function myFunction() {
console.log(this);
}
myFunction(); // Window 객체를 출력
---
"use strict";
function myFunction() {
console.log(this);
}
myFunction(); // undefined 출력
2.객체 메서드로서의 this
const myObject = {
myMethod: function() {
console.log(this);
}
};
myObject.myMethod(); // myObject 객체를 출력
var val = 37;
var myObj = {
val: 10,
someFunction: function() {
console.log(this.val);
}
};
myObj.someFunction(); // 10 출력
console.log(window.val); // 37 출력
3..call()
, .apply()
, .bind()
를 통한 this
변경
.call()
과.apply()
메서드는 함수를 호출할 때this
를 명시적으로 설정할 수 있게 해줍니다..bind()
메서드는this
가 무엇인지 명시적으로 설정한 새로운 함수를 반환
function myFunction() {
console.log(this.name);
}
const obj1 = { name: 'Alice' };
const obj2 = { name: 'Bob' };
myFunction.call(obj1); // 'Alice' 출력
myFunction.apply(obj2); // 'Bob' 출력
const boundFunction = myFunction.bind(obj1);
boundFunction(); // 'Alice' 출력
4.생성자 함수에서의 this
생성자 함수는 new
키워드와 함께 사용될 때, this
가 새로 생성된 객체를 가리키게 됩니다.
function ConstructorFunction(val) {
this.val = val;
}
var obj1 = new ConstructorFunction(20);
console.log(obj1.val); // 20 출력
5.즉시 실행 함수 표현식(IIFE)에서의 this
IIFE에서 this
는 항상 window
객체를 가리킵니다.
즉시 실행에 대한 주체는 전역이다.
(function() {
console.log(this); // Window 객체 출력
})();
var obj = {
someFunc: function() {
(function() {
console.log(this); // Window 객체 출력
})();
}
};
obj.someFunc();
6.이벤트 핸들러에서의 this
이벤트 핸들러에서 this
는 이벤트가 발생한 요소를 가리킵니다.
- e.currentTarget = this 이다. ( e.target이 아님.)
<div id="myDiv">Click me</div>
<script>
document.getElementById('myDiv').onclick = function() {
console.log(this); // 클릭된 div 요소 출력
};
</script>
7.화살표 함수(Arrow Function)에서의 this
외부 스코프(lexical scope)의 this
를 상속.
- 화살표 함수 내에서의
this
는 화살표 함수가 정의된 위치의this
와 동일.
// 예제 1: 화살표 함수에서 `this`
const myObj = {
val: 10,
regularFunction: function() {
console.log(this.val); // 10 출력
},
arrowFunction: () => {
console.log(this.val); // undefined 출력
}
};
myObj.regularFunction();
myObj.arrowFunction();
// 예제 2: 외부 함수와 화살표 함수의 `this`
function MyConstructor() {
this.val = 20;
this.regularFunction = function() {
console.log(this.val); // 20 출력
};
this.arrowFunction = () => {
console.log(this.val); // 20 출력
};
}
const obj = new MyConstructor();
obj.regularFunction(); // 20 출력
obj.arrowFunction(); // 20 출력
arrowFunction
도obj
의 메서드로 호출되지만, 화살표 함수는MyConstructor
함수의this
를 상속받습니다. 이 경우,this
는 여전히obj
를 가리키고 있으므로,20
을 출력합니다.
const obj = {
name: "Carol",
greet: function() {
const innerFunc = () => {
console.log(this.name);
};
innerFunc();
}
};
obj.greet(); // "Carol" 출력
8. 중첩된 함수에서의 this
- innerFunc를 부른건 전역(window)이다.
const obj = {
name: "Frank",
greet: function() {
function innerFunc() {
console.log(this.name); // undefined (엄격 모드에서) 또는 전역 객체의 name
}
innerFunc();
}
};
obj.greet(); // undefined 또는 전역 객체의 name 출력
---
`self` 변수를 사용하는 방법:
const obj = {
name: "George",
greet: function() {
const self = this;
function innerFunc() {
console.log(self.name); // "George" 출력
}
innerFunc();
}
};
obj.greet(); // "George" 출력
---
const obj = {
name: "Frank",
greet: function() {
this.innerFunc = function innerFunc() {
console.log(this.name);
}
this.innerFunc();
}
};
obj.greet(); // Frank
9. 클래스 내 메서드에서의 this
class MyClass {
constructor(name) {
this.name = name;
}
greet() {
console.log(this.name);
}
}
const myInstance = new MyClass("Helen");
myInstance.greet(); // "Helen" 출력