티스토리 뷰
반응형
🚀 들어가며...
- 자바스크립트에는 this라는 키워드가 있습니다. this는 문맥에 따라서 다양한 값을 가지는 데, this가 쓰이는 함수를 어떤 방식으로 실행하느냐에 따라서 그 역할이 구별됩니다. this의 값들은 크게 4가지 정도로 나눌 수 있는데, this를 이용하는 함수를 4가지 방식 중에서 어떤 방식으로 실행하느냐에 따라 this의 값이 결정됩니다. 이러한 특성 때문에 this가 무엇을 지칭하는지 알기 위해서는 this가 사용된 함수가 어디서 어떻게 실행되었는지를 알아야 합니다.
📑 내용
JS에서 this의 할당은?
JS에서 this는 정적으로 할당 되지 않고, 동적으로 할당됩니다.
쉽게 말하자면, this가 선언되었을 때가 아닌, 호출되었을 때 결정된다는 의미입니다.
ex)
const person = function (name) {
this.name = name; // 이 때 this가 결정되는 것이 아니라
}
const person1 = new person('son'); // 이 때 결정 됩니다.
console.log(person1.name);
JS에서 호출에 따른 this의 해석
1. 함수 호출
- 일반적으로 일반 함수에서 this는 전역 객체(window)를 가르킵니다.
- 모든 내부함수(함수속에 함수, 메소드 속 함수)의 this는 전역 객체(window)를 가르킵니다.
- 콜백함수로 일반함수가 올 경우 전역객체(window)를 가르킵니다.
ex1)
var value = 1;
var obj = {
value: 100,
foo: function() {
console.log("foo's this: ", this); // obj
console.log("foo's this.value: ", this.value); // 100
function bar() {
console.log("bar's this: ", this); // window
console.log("bar's this.value: ", this.value); // 1
}
bar();
}
};
obj.foo();
ex2)
var value = 1;
var obj = {
value: 100,
foo: function() {
setTimeout(function() {
console.log("callback's this: ", this); // window
console.log("callback's this.value: ", this.value); // 1
}, 100);
}
};
obj.foo();
위 예제들을 보시면 이해가 가실겁니다.
2. 메소드 호출
- 함수가 객체의 프로퍼티 값이면, 메소드로서 호출됩니다. 이 때, this는 메소드를 소유한 객체가 됩니다.
- 프로토타입 객체도 메소드를 가질 수 있습니다. 그리고 프로토타입 객체의 this도 해당 메소드를 호출한 객체를 바인딩합니다.
ex1)
var obj1 = {
name: 'Lee',
sayName: function() {
console.log(this.name);
}
}
var obj2 = {
name: 'Kim'
}
obj2.sayName = obj1.sayName;
obj1.sayName(); // /Lee
obj2.sayName(); // kim
ex2)
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
return this.name;
}
var me = new Person('Cho');
console.log(me.getName()); // Cho
Person.prototype.name = 'Son';
console.log(Person.prototype.getName()); // Son
3. 생성자 함수 호출
- 생성자 함수란 어떤 공통 성질을 가지는 객체들을 생성하는데 사용하는 함수입니다.
생성자를 클래스(class), 클래스를 통해 만든 객체를 인스턴스(instance)라고 합니다. - JS는 함수에 생성자로서의 역할을 함께 부여 했습니다.
new 명령어를 통해 함수를 호출하면 함수가 생성자로 동작하여 인스턴스 객체를 만듭니다. 이때 내부에서의 this는 새로 만들어진 인스턴스 자신이 됩니다. - 생성자 함수를 호출하면
1. 생성자의 prototype 프로퍼티를 참조하는 __proto__ 라는 프로퍼티가 있는 객체를 생성합니다.
2. 미리 준비된 공통 속성 및 개성을 해당 객체(this)에 부여합니다. - new 명령어를 통해 함수를 호출하면 함수가 생성자로 동작하여 인스턴스 객체를 만듭니다. 이때 내부에서의 this는 새로 만들어진 인스턴스 자신이 됩니다.
// 생성자 함수
function Person(name) {
this.name = name;
}
var me = new Person('Lee');
console.log(me); // {name: "Lee"}
// new 연산자와 함께 생성자 함수를 호출하지 않으면 생성자 함수로 동작하지 않습니다.
var you = Person('Kim');
console.log(you); // undefined
3-1 생성자 함수 동작 방식
- 생성자 함수가 실행되기 전 빈 객체를 생성하고, 생성자 함수 내에서 사용되는 this는 이 객체를 가르킵니다. 빈 객체는 생성자 함수의 prototype 프로퍼티가 가르키는 객체를 자신의 프로토타입 객체로 설정합니다.
- this를 통해 this가 가르키는 객체에 프로퍼티를 생성할 수 있습니다.
- 생성자 함수의 return이 없는 경우 새롭게 바인딩 된 객체(this가 가르키는 객체)가 반환됩니다.
function Person(name) {
// 생성자 함수 코드 실행 전 -------- 1번
this.name = name; // --------- 2번
// 생성된 함수 반환 -------------- 3번
}
var me = new Person('Lee');
console.log(me.name);
3-2 객체 리터럴 방식과 생성자 함수 방식의 차이
const object = {
name: "park",
age: 12,
} // 객체 리터럴방식
const Person = function (name, age) {
this.name = name;
this.age = age;
} // 생성자 함수 선언
const person1 = new Person("Lee", 13); // 생성자 함수 방식
위 객체 리터럴 방식과 생성자 함수 방식의 차이는 생성자 함수의 prototype 객체는 Object이고,
객체리터럴방식의 prototype 객체는 Person입니다.
3-3 생성자 함수에 new 키워드를 쓰지 않는 경우
- 일반함수와 생성자 함수는 차이가 없습니다.
대부분의 new 없이 사용하는 빌트인 생성자(Array, Regex 등)는 scope-safe Constructor Pattern을 사용합니다. 아래는 scope-safe Constructor Pattern 의 예제입니다.
function A(arg) {
// arguments.callee는 호출된 함수의 이름을 나타냅니다.
if(!(this instanceof arguments.callee)) {
return new arguments.callee(arg);
}
this.value = arg ? arg : 0;
}
var a = new A(100);
var b = A(100);
console.log(a.value);
console.log(b.value);
callee는 arguments 객체의 프로퍼티로서 함수 바디 내에서 현재 실행 중인 함수를 참조할 때 사용합니다. 즉, 함수 바디 내에서 현재 실행 중인 함수의 이름을 반환합니다.
🙋🏻♂️ 후기
this는 프론트개발자라면 익숙한 문법일텐데, 이렇게 자세히 살펴보면 많은 호출방법에 따라 다르게 쓰이는 것을 알 수 있습니다. 한번 짚고 넘어간다면, 추후에 this문법때문에 오류가 나와도 금방 알아차리실수 있을 것 같습니다. 제가 게시한 방법 이외에도 다르게 쓰이는 this를 좀더 확인하고 공부해야겠습니다.
🔗 참고한 글
반응형
'JavaScript' 카테고리의 다른 글
[JavaScript] default export와 named export의 차이점을 알아보자! (0) | 2022.07.28 |
---|---|
[JavaScript] 화살표함수(arrow function)에 대해 알아보자! (0) | 2022.06.07 |
[JavaScript] 소수점 계산오류 해결하기 (1) | 2022.05.17 |
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- static files
- 탐욕법
- ORM
- JS
- Linux
- Python
- Named export
- JavaScript
- django
- programmers
- db
- docker
- lv2
- PostgreSQL
- MVT
- Greedy Algorithm
- Algorithm
- container
- uSWGI
- This
- Master & Slave
- list
- django ORM
- lv1
- union-find
- Default export
- SQL
- data formatting
- generator expression
- react
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함