Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- 장고
- webpack
- Django
- lazy loading
- 라우터
- 로컬스토리지
- 뷰
- 자바스크립트 #javascript #렌더링 #렌더링순서
- 세션스토리지
- 프론트엔드
- vuetify
- NavigationDuplicated
- 세션
- 성능 최적화
- jest
- Transition
- 안드로이드
- cubic-bezier
- DOM
- vue #vue.js #font #web-font
- vue-router
- Router
- 렌더링 최적화
- VUE
- 주니어 개발자
- vue.js
- 예외처리
- css
- virtual dom
- frontend
Archives
- Today
- Total
한준호
[Modern javascript] this 본문
728x90
◎ this는 자신이 속하나 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수다. this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
// this는 어디서든지 참조 가능하다.
// 전역에서 this는 전역 객체 window를 가리킨다.
console.log(this); // window
function square(number) {
// 일반 함수 내부에서 this는 전역 객체 window를 가리킨다.
console.log(this); // window
return number * number;
}
square(2);
const person = {
name: 'Lee',
getName() {
// 메서드 내부에서 this는 메서드를 호출한 객체를 가리킨다.
console.log(this); // {name: "Lee", getName: ƒ}
return this.name;
}
};
console.log(person.getName()); // Lee
function Person(name) {
this.name = name;
// 생성자 함수 내부에서 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
console.log(this); // Person {name: "Lee"}
}
const me = new Person('Lee');
- this 바인딩은 함수 호출 방식에 의해 동적으로 결정된다.
- 함수의 상위 스코프를 결정하는 방식인 렉시컬 스코프는 함수 정의가 평가되어 함수 객체가 생성되는 시점에 상위 스코프를 결정하지만 this 바인딩은 함수 호출 시점에 결정된다.
1. 일반 함수 호출
- 기본적으로 this에는 전역 객체가 바인딩된다. 즉 어떠한 함수라도 일반 함수로 호출되면 this에는 전역 객체가 바인딩된다.
function foo() {
console.log("foo's this: ", this); // window
function bar() {
console.log("bar's this: ", this); // window
}
bar();
}
foo();
하지만 자주 사용하는 setTimeout 함수와 같이 콜백함수의 this에도 전역 객체가 바인딩 되는 것은 문제가 있다.
var value = 1;
const obj = {
value: 100,
foo() {
console.log("foo's this: ", this); // {value: 100, foo: ƒ}
// 콜백 함수 내부의 this에는 전역 객체가 바인딩된다.
setTimeout(function () {
console.log("callback's this: ", this); // window
console.log("callback's this.value: ", this.value); // 1
}, 100);
}
};
obj.foo();
var value = 1;
const obj = {
value: 100,
foo() {
// this 바인딩(obj)을 변수 that에 할당한다.
const that = this;
// 콜백 함수 내부에서 this 대신 that을 참조한다.
setTimeout(function () {
console.log(that.value); // 100
}, 100);
}
};
obj.foo();
위와 같이 that을 활용하거나 화살표 함수를 사용한다.
2. 메서드 호출
- 메서드 내부의 this는 메서드를 호출하는 객체가 바인딩 된다.
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
};
const me = new Person('Lee');
// getName 메서드를 호출한 객체는 me다.
console.log(me.getName()); // ① Lee
Person.prototype.name = 'Kim';
// getName 메서드를 호출한 객체는 Person.prototype이다.
console.log(Person.prototype.getName()); // ② Kim
3. 생성자 함수 호출
- 생성자 함수 내부의 this는 생성자 함수가 미래에 생성할 인스턴스가 바인딩 된다.
// 생성자 함수
function Circle(radius) {
// 생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}
// 반지름이 5인 Circle 객체를 생성
const circle1 = new Circle(5);
// 반지름이 10인 Circle 객체를 생성
const circle2 = new Circle(10);
console.log(circle1.getDiameter()); // 10
console.log(circle2.getDiameter()); // 20
// new 연산자와 함께 호출하지 않으면 생성자 함수로 동작하지 않는다. 즉, 일반적인 함수의 호출이다.
const circle3 = Circle(15);
// 일반 함수로 호출된 Circle에는 반환문이 없으므로 암묵적으로 undefined를 반환한다.
console.log(circle3); // undefined
// 일반 함수로 호출된 Circle 내부의 this는 전역 객체를 가리킨다.
console.log(radius); // 15
4. Function.prototype.apply / call / bind 메서드에 의한 간접 호출
- apply / call / bind 메서드는 Function.prototype의 메서드다. 모든 함수가 상속받아 사용할 수 있다.
apply 와 call 메서드의 기능은 함수를 호출하는 것이다. 첫 번째 인수 객체에 나머지 인수(배열)를 전달한다.
function getThisBinding() {
console.log(arguments);
return this;
}
// this로 사용할 객체
const thisArg = { a: 1 };
// getThisBinding 함수를 호출하면서 인수로 전달한 객체를 getThisBinding 함수의 this에 바인딩한다.
// apply 메서드는 호출할 함수의 인수를 배열로 묶어 전달한다.
console.log(getThisBinding.apply(thisArg, [1, 2, 3]));
// Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
// {a: 1}
// call 메서드는 호출할 함수의 인수를 쉼표로 구분한 리스트 형식으로 전달한다.
console.log(getThisBinding.call(thisArg, 1, 2, 3));
// Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
// {a: 1}
bind 메서드는 this로 사용할 객체만 전달한다.
const person = {
name: 'Lee',
foo(callback) {
// ①
setTimeout(callback, 100);
}
};
person.foo(function () {
console.log(`Hi! my name is ${this.name}.`); // ② Hi! my name is .
// 일반 함수로 호출된 콜백 함수 내부의 this.name은 브라우저 환경에서 window.name과 같다.
// 브라우저 환경에서 window.name은 브라우저 창의 이름을 나타내는 빌트인 프로퍼티이며 기본값은 ''이다.
// Node.js 환경에서 this.name은 undefined다.
});
const person = {
name: 'Lee',
foo(callback) {
// bind 메서드로 callback 함수 내부의 this 바인딩을 전달
setTimeout(callback.bind(this), 100);
}
};
person.foo(function () {
console.log(`Hi! my name is ${this.name}.`); // Hi! my name is Lee.
});
728x90
'Frontend > modern javascript' 카테고리의 다른 글
[Modern javascript] 실행 컨텍스트(2) (0) | 2021.08.28 |
---|---|
[Modern javascript] 실행 컨텍스트(1) (1) | 2021.08.28 |
[Modern javascript] 빌트인 객체 (0) | 2021.08.26 |
[Modern javascript] strict mode (0) | 2021.08.25 |
[Modern javascript] 프로토타입(2) (0) | 2021.08.25 |
Comments