자바나 파이썬과 같은 언어의 this와 자바스크립트의 this는 조금 다른데, 정확히 이해하기 위해 정리해보았다.
나같이 삽질하는 사람도 이해할 수 있도록 작성한다!! 그래도 어려울지도
꼭 이해해야 하는 개념이므로 미루지 말자.😭
this
js에서 this는 함수가 호출되는 시점의 실행 컨텍스트 (Execution context) 이다.
실행 컨텍스트 (Execution context)는 간단히 말하면 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.
더 자세한 내용은 검색해보자
실행 컨텍스트는 함수를 호출할 때 생성되므로, this도 함수를 호출할 때 결정된다고 볼 수 있다.
this 바인딩 네가지
1. 기본 바인딩 (전역 객체)
2. 암시적 바인딩 (메서드 호출)
3. 명시적 바인딩 (call, apply, bind)
4. new 바인딩 (생성자 함수 호출)
1. 기본 바인딩 default binding(전역 객체)
기본적으로 this는 전역 객체를 가리킨다.
즉, 어떠한 함수라도 일반 함수로 호출되면 this에 전역 객체가 바인딩된다.
크롬 브라우저 console에서 console.log(this) 를 입력할 경우 window 라고 뜨게 되는데,
window가 브라우저 실행 환경에서의 전역 객체이다.
function func() {
console.log(this); //1번째 this
}
func();
console.log(this); //2번째 this
브라우저 | Node.js(REPL) | Node.js(IDE) | |
1번째 this | window | global | global |
2번째 this | window | global | module.exports |
1번째 this는 함수가 func(); 와 같이 단순호출되는 경우로,
2번째 this는 함수 안이 아닌 전역 스코프에서 호출되는 경우로, 각 환경에 따라 전역객체가 다르다.
만약 엄격모드(strict mode)일 경우, 1번째 this는 모두 undefined이다.
2. 암시적 바인딩(메서드 호출)
객체의 메서드를 호출하는 경우, 해당 메서드를 호출한 객체에 바인딩 된다.
함수가 호출될 때 점 표기법(.) 혹은 대괄호 표기법[ ]이 사용되었다면 메서드 호출이라고 볼 수 있다.
const obj = {
test: function() {
console.log(this)
}
};
obj.test();
obj['test']()
암시적 바인딩에서는 누가 메서드를 호출했는가를 중요하게 본다.
obj에 의해 test() 라는 메서드가 호출되었기 때문에, this는 obj가 되는 것이다.
3. 명시적 바인딩(call, apply, bind)
function.prototype에 정의되어 있는 call, apply, bind 메서드를 활용하여 this를 바인딩한다.
특정 함수에 정확히 원하는 객체를 바인딩할 수 있다.
function sayHello() {
console.log(`Hello, ${this.name}!`);
}
const person = { name: 'John' };
sayHello.call(person); // "Hello, John!"
call() : 함수를 호출하면서 객체에 바인딩한다. 함수의 인자는 콤마로 구분지어 넣어준다.
function sayHello(greeting) {
console.log(`${greeting}, ${this.name}!`);
}
const person = { name: 'John' };
sayHello.apply(person, ['Hola']); // "Hola, John!"
apply() : call()과 유사하게 함수를 호출하며 객체에 바인딩하며, 함수에 인자를 배열로 전달한다.
function sayHello() {
console.log(`Hello, ${this.name}!`);
}
const person = { name: 'John' };
const sayHelloToJohn = sayHello.bind(person);
sayHelloToJohn(); // "Hello, John!"
bind() : this가 바인딩된 새로운 함수를 반환한다. bind로 한번 바인딩되면 그 이후로 바뀌지 않는다.
즉 this 값이 고정된 컨텍스트로 유지된다.
4. new 바인딩(생성자 함수 호출)
new 키워드로 생성자 함수를 호출할 때, this는 새로 생성되는 객체를 가리킨다.
기존 함수에 new 연산자를 붙여서 호출하면, 그 함수는 생성자 함수로 동작한다.
function Person(name){
this.name = name;
}
var me = new Person('John');
console.log(me.name); //John
생성자 함수 동작 방식
1. 빈 객체 생성 및 this 바인딩
객체의 Prototype을 생성자 함수의 Prototype이 가리키는 객체로 설정한다.
function Person(name, age) {
this.name = name;
this.age = age;
}
const john = new Person('John', 25);
2. 1에서 만든 객체에 this로 프로퍼티나 메소드를 생성한다.
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};
const john = new Person('John', 25);
john.sayHello(); // "Hello, my name is John and I am 25 years old."
3. 생성된 객체 반환
반환문이 없는 경우, this에 바인딩된 새로 생성한 객체가 반환된다. 명시적으로 this를 반환하여도 결과는 같다.
function Person(name, age) {
this.name = name;
this.age = age;
// return someObject; // 만약에 여기서 객체를 반환하면 그 객체가 인스턴스가 됨.
}
const john = new Person('John', 25);
반환문이 this가 아닌 다른 객체를 명시적으로 반환하는 경우, this가 아닌 해당 객체가 반환된다.
this를 반환하지 않은 함수는 생성자 함수의 역할을 수행하지 못하므로,
생성자함수는 반환문을 명시적으로 사용하지 않는다.
this는.. 항상 어려운 것 같다. 아직도 너무너무 헷갈리고 ㅠ.ㅠ
화살표함수에서 this는 또.. 뭔가 다르니까
화살표 함수 정리도 해보겟다...😖
'Study > JavaScript' 카테고리의 다른 글
[JavaScript] 자바스크립트 강의 (0) | 2024.01.02 |
---|