Skip to main content

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 출력
  • arrowFunctionobj의 메서드로 호출되지만, 화살표 함수는 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" 출력