this
this는 JavaScript 예약어로, 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수(self-reference variable)이다.
대부분 this의 값은 함수를 호출한 방법에 의해 결정된다. 실행중에는 할당으로 설정할 수 없고 함수를 호출할 때 마다 다를 수 있다. ES5는 함수를 어떻게 호출했는지 상관하지 않고 this 값을 설정할 수 있는 bind 메서드를 도입했고, 스스로의 this 바인딩을 제공하지 않는 화살표 함수를 추가했다.
Binding
프로그램의 어떤 기본 단위가 가질 수 있는 구성요소의 구체적인 값, 성격을 확정하는 것이다. 쉽게 식별자와 값을 연결하는 과정을 의미하며, this바인딩은 this와 this가 가리킬 객체를 바인딩하는 것이다.
전역 문맥
브라우저라는 자바스크립트 런타임의 경우에는 this는 항상 window라는 전역 객체를 참조한다. (Node.js에서 전역 객체는 global이다.)
console.log(this === window); // true
a = 37;
console.log(window.a); // 37
this.b = "test";
console.log(window.b) // "test"
console.log(b) // "test"
함수 문맥
함수 내부에서 this의 값은 함수를 호출한 방법에 의해 좌우된다.
// 엄격 모드가 아닌 경우
function f1() {
return this;
}
f1(); // 브라우저 : window 객체, Node.js : global 객체
// 엄격 모드
function f2() {
"use strict";
return this;
}
f2() === undefined; // true
실행 컨텍스트(EC)가 생성될 때 마다 this의 바인딩이 일어나며 우선순위 순으로 나열해 보면 다음과 같다.
- 실행 컨텍스트(Execution Context) : scope, hoisting, this, function, closure 등 동작원리를 담고 있는 자바스크립트의 핵심원리.
1. new 를 사용했을 때 해당 객체로 바인딩된다.
var name = "global";
function Func() {
this.name = "test";
this.print = function f() {
console.log(this.name);
};
}
var a = new Func();
a.print(); // test
2. call, apply, bind 와 같은 명시적 바인딩을 사용했을 때 인자로 전달된 객체에 바인딩된다.
2-1. call / apply
function add(c,d) {
return this.a + this.b + c + d;
}
var obj = {a: 1, b: 3};
// 첫 번째 인자는 'this'로 사용할 객체이고,
// 이어지는 인자들은 함수 호출에서 인수로 전달된다.
add.call(obj, 5, 7); // 16
// 첫 번째 인자는 'this'로 사용할 객체이고,
// 두 번째 인자는 함수 호출에서 인수로 사용될 멤버들이 위치한 배열이다.
add.apply(obj, [5, 7]); // 16
2-2. bind
ES5는 Function.prototype.bind 를 도입했다. f.bind(someObject)를 호출하면 f 와 같은 코드와 범위를 가졌지만, this는 원본 함수를 가진 새로운 함수를 생성한다. 새 함수 this는 호출 방식과 상관없이 영구적으로 bind()의 첫 번째 매개변수로 고정된다.
function f() {
return this.a;
}
var g = f.bind({a: "apple"});
console.log(g()); // apple
var h = g.bind({a: "banana"}); // bind는 한 번만 동작한다.
console.log(h()); // apple
var o = {a : 37, f: f, g: g, h: h};
console.log(o.a, o.f(); o.g(), o.h()); // 37, 37, apple, apple
화살표함수
화살표함수에서 this는 자신을 감싼 정적 범위이다. 전역 코드에서 전역 객체를 가리킨다.
var globalObject = this; var foo = (() => this); console.log(foo() === globalObject); // true
화살표 함수를 call(), apply(), bind() 를 사용해 호출할 때 this의 값을 정해주더라도 무시한다. 사용할 매개변수를 정해주는 것은 문제없지만, 첫 번째 매개변수(thisArg)는 null을 지정해야한다.
// 객체로서 메서드 호출
var obj = { func: foo };
console.log(obj.func() === globalObject); // true
// call을 사용한 this 설정 시도
console.log(foo.call(obj) === globalObject); // true
// bind를 사용한 this 설정 시도
foo = foo.bind(obj);
console.log(foo() === globalObject); // true
3. 객체의 메서드로 호출할 경우 해당 객체에 바인딩된다.
var obj = {
name : "object name",
print : function p() {
console.log(this.name);
},
};
obj.print(); // object name
4. 그 외의 경우
- 엄격 모드 (strict mode) : undefined로 초기화된다.
- 일반 : 브라우저라면 window 객체에 바인딩된다.
출처:
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this
'코딩 > 정말 나는 잘 알고 있을까?' 카테고리의 다른 글
null, undefined, undeclaered, NaN 이 뭐야? (0) | 2022.08.06 |
---|---|
브라우저 저장소가 뭐야? (feat. 쿠키, 세션, jwt) (0) | 2022.08.06 |
절차 지향 프로그래밍 & 객체 지향 프로그래밍이 뭐야? (0) | 2022.08.06 |
JavaScript가 뭐야? (feat. 프로토타입, 싱글 스레드, 비동기적 코딩) (0) | 2022.08.05 |
프로그래밍 언어가 뭐야? (0) | 2022.08.04 |