3장 this
3-1. 상황에 따라 달라지는 this
- js에서 this는 실행 컨텍스트가 생성될 때 함께 결정됨
- 함수를 호출할 때 결정
3-1-1. 전역 공간에서의 this
- 전역 공간에서의 this : 전역 객체
- 전역 컨텍스트를 생성하는 주체가 전역 객체
- 브라우저 환경 this: window
- Node.js: global
var a = 1;
console.log(a); // 1
console.log(window.a); // 1
console.log(this.a); // 1
- 전역변수 선언 시 js 엔진은 전역객체의 프로퍼티로 할당
- js의 모든 변수는 특정 객체의 프로퍼티로서 동작하기 때문
- 특정 객체란 실행 컨텍스트의 LE
- 실행 컨텍스트는 변수를 수집해서 LE의 프로퍼티로 저장
- 전역 컨텍스트 LE는 전역 객체를 그대로 참조
- console에 전부 1이 찍히는 이유 ?
- 변수 a에 접근하고자 하면 스코프 체인에서 a 검색
- 가장 가까운 전역 스코프의 LE 에서 a를 발견
- 전역 공간에서 var로 변수를 선언하는 것과 window 프로퍼티에 직접 할당하는 것의 차이
- 전역변수는 삭제 X
- 전역객체의 프로퍼티 삭제 O
- 개발자가 의도치 않게 삭제하는 것을 방지
- configurable 속성(변경 및 삭제 가능성)을 false로 정의함
- var a = 1; delete windw.a; // false window.c = 3; delete window.c; // true
3-1-2. 메서드로서 호출할 때 그 메서드 내부에서의 this
🔍 함수 vs 메서드
- 함수 실행 방법
- 함수로서 호출
- 메서드로서 호출
- 차이 : 독립성
- 함수는 그 자체로 독립적인 기능 수행
- 메서드는 자신을 호출한 대상 객체에 관한 동작 수행
- js는 상황별로 this에 다른 값을 부여함으로써 구현함
함수로서 호출, 메서드로서 호출
var func = function(x) {
console.log(this,x);
}
func(1); // window 1 , 함수로서 호출
// 객체의 프로퍼티에 할당
var obj = {
method: func
};
obj.method(2); // { method: f } 2 , 메서드로서 호출
🔍 메서드 내부에서의 this
- this : 호출한 주체에 대한 정보
- 어떤 함수를 메서드로서 호출하는 경우 호출 주체는 바로 함수명 앞의 객체임
var obj = {
methodA: function () { console.log(this);},
inner: {
methodB: function () { console.log(this);}
}
};
obj.methodA; // obj
obj.inner.methodB; // obj.inner
3-1-3. 함수로서 호출할 때 그 함수 내부에서의 this
🔍 함수 내부에서의 this
- this가 지정되지 않음
- this에는 호출한 주체에 대한 정보가 담기는 것
- 이 경우 개발자가 코드에 직접 관여해서 실행한 것이기 떄문
- 함수에서의 this는 전역 객체.
🔍 메서드 내부함수에서의 this
- 함수를 실행하는 당시의 주변 환경 (메서드 내부인지, 함수 내부인지)은 중요하지 않고, 해당 함수를 호출하는 구문 앞에 점 혹은 대괄호 표기 여부가 중요
- 메서드로서 호출할 때만 this가 해당 객체를 가르킴
🔍 메서드 내부 함수에서의 this를 우회하는 방법
- 변수는 this와 달리 해당 변수가 있는 환경을 기억함
var obj = {
outer: funtion () {
console.log(this);
var innerFunc1 = function() {
console.log(this); // 전역객체인 window
}
innerFunc1();
var self = this;
var innerFunc2 = function() {
console.log(this); // obj
}
{
}
obj.outer();
- 변수를 활용하여 this를 저장하고 이를 함수에서 사용
🔍 this를 바인딩하지 않는 함수
function regularFunction() {
console.log(this);
}
const obj = {
method: regularFunction
};
obj.method(); // `obj`
// ------------ 화살표 함수
const arrowFunction = () => {
console.log(this);
};
const obj = {
method: arrowFunction
};
obj.method(); // 전역 객체
- ES에서 함수 내부 this가 전역객체를 바라보는 문제 보완하고자 화살표 함수(arrow function) 도입
- 실행 컨텍스트를 생성할 떄 this 바인딩 과정 자체가 빠지게 되어, 상위 스코프의 this를 그대로 활용
- 화살표 함수의 this는 상위 스코프의 this와 동일
3-1-4. 콜백 함수 호출 시 그 함수 내부에서의 this
- 콜백함수
- 함수 A의 제어권을 다른 함수 B에게 넘겨주는 경우, A가 콜백 함수
- A는 함수 B의 내부 로직에 따라 실행 ,this도 동일
- 함수에서의 this는 기본적으로 전역객체
- but 제어권을 받은 함수에서 콜백 함수에 별도로 this가 될 대상을 지정한 경우에는 그 대상을 참조 (addEventLsitener)
3-1-5. 생성자 함수 내부에서의 this
- 생성자 함수
- : 어떤 공통된 성질을 지니는 객체들을 생성하는 데 사용하는 함수
- 객체지향 언어에서 생성자를 클래스
- 클래스를 통해 만든 객체를 인스턴스라고 함
- 생성자(클래스): 구체적인 인스턴스를 만들기 위한 일종의 틀, 공통 속성
- 인스턴스: 클래스에 구체적인 개성이 더해진 것
- js는 함수에 생성자 역할 부여
- new 키워드와 함께 함수 호출
- new로 만들어진 함수(=인스턴스) 내부에서의 this는 곧 새로 만들어질 인스턴스 자신
- new !
- 생성자 함수를 호출하면 생성자의 프로토타입 프로퍼티를 참조하는 객체(인스턴스) 만듦
- 공통 속성을 해당 객체(this)에 부여
var Cat = function (name, age) {
this.bark = '야옹';
this.name = name;
this.age = age;
}
var choco = new Cat('초코', 7);
console.log(choco); // 인스턴스 Cat { bark: '야옹', name: '초코', age: 7 }
3-2. 명시적으로 this를 바인딩하는 방법
3-2-1. call 메서드
Function.prototype.call(thisArg[, arg1[, arg2[, ...]]])
- 메서드의 호출 주체인 함수를 즉시 실행하도록 하는 명령
- 첫 번째 인자를 this로 바인딩, 나머지 인자들을 호출할 매개변수로 사용
3-2-2. apply 메서드
Function.prototype.apply(thisArg[, argsArray])
- call 메서드와 기능 동일
- 차이점 : 두 번째 인자를 배열로 받아 그 배열의 요소들을 호출할 함수의 매개변수로 지정
3-2-3. call/apply 메서드의 활용
🔍 유사배열객체에 배열 메서드를 적용
- 유사배열객체: 키가 0 또는 양의 정수인 프로퍼티가 존재하고 length 프로퍼티의 값이 0 또는 양의 정수인 객체
- call, apply 메서드를 이용해 배열 메서드 차용 가능
3-2-4. bind 메서드
Function.prototype.bind[thisArg[, arg1[, arg2[, ...]]])
- call과 유사하나, 즉시 호출하진 않고 넘겨 받은 this 및 인수들을 바탕으로 새로운 함수 반환
- 반환된 함수를 호출할 때 인수를 넘기면 그 인수들은 기존 bind 메서드를 호출할 때 전달했던 인수들의 뒤에 이어서 등록됨
- 즉, 함수에 미리 this를 미리 적용하고 부분 적용 함수를 구현
var func = function (a, b, c, d) {
console.log(this, a, b, c, d);
};
func(1, 2, 3, 4); // window 1 2 3 4
var bindFunc1 = func.bind({ x: 1});
bindFunc1(5, 6, 7, 8); // { x: 1 } 5 6 7 8
name 프로퍼티
- name 프로퍼티에 bound 접두어 붙음
- 코드 추적 용이
🔍 상위 컨텍스트의 this를 내부함수나 콜백 함수에 전달하기
var obj = {
outer: function () {
console.log(this);
var innerFunc = function () {
console.log(this);
};
innerFunc.call(this);
}
};
obj.outer();
3-2-5. 화살표 함수의 예외사항
- 화살표 함수는 실행 컨텍스트 생성 시 this 바인딩 과정 X
- 함수 내부에 this 없음
- 접근 시 스코프체인상 가장 가까운 this에 접근
- call, apply, bind 사용하지 않고 간결
3-3. 정리
- 전역공간에서의 this는 전역객체
- 브라우저 : windos
- Node.js: global
- 함수를 메서드로서 호출한 경우 this는 메서드 호출 주체 (메서드명 앞의 객체) 참조
- 함수를 함수로서 호출한 경우 this는 전역객체 참조. 메서드이 내부함수에서도 같음
- 콜백 함수 내부에서의 this는 해당 콜백 함수의 제어권을 넘겨받은 함수가 정의한 바에 따름. 정의하지 않은 경우는 전역객체
- 생성자 함수에서의 this는 생성될 인스턴스 참조
명시적 this 바인딩
- call, apply : this 지정 및 함수 호출
- bind : this 지정 후 새로운 함수 반환
- 요소를 순회하며 콜백 함수를 반복 호출하는 내용 일부 메서드는 별도 인자로 this를 받기도 함 (특히 Array)
'Javascript > 코어 자바스크립트' 카테고리의 다른 글
[6장] 코어 자바스크립트 프로토타입 (0) | 2024.09.25 |
---|---|
[5장] 코어 자바스크립트 클로저 (0) | 2024.09.25 |
[4장] 코어 자바스크립트 콜백 함수 (0) | 2024.09.24 |
[2장] 코어 자바스크립트 실행 컨텍스트 (4) | 2024.09.22 |
[1장] 코어 자바스크립트 데이터 타입 (0) | 2024.09.20 |