[TIL 10][JS] this
개요
this는 뭐라고 정의해야 맞는걸까? 그냥 뜻 그대로 이것! 이라고 해야하나.. 나를 부른게 누구냐라고 하는게 젤 쉬울거 같다.
처음 자바스크립트 공부하면서 막히는 부분이 this와 prototype이 아닐까 싶다.
물론 이걸 작성하고 있는 나도 공부하기 위해서 작성하는거라 쓰면서 점차 이해도를 높히려고 노력하고있다.
this는 this를 포함하고 있는 함수가 어떻게 실행되느냐에 따라 결정된다. 즉, 함수 선언 시점에 의해 결정되는 값이 아닌 함수 실행 시점에 결정되는 값이다.
const age = 32;
const jay = {
age: 31;
logAge: function () {
console.log(this.age);
}
};
const func = jay.logAge();
jay.logAge();
func();
위와 같은 경우 jay.logAge()와 func()는 같은 함수를 실행하지만, 콘솔의 출력결과는 다르다.
함수가 실행될 수 있는 방식에는 4가지가 있는데 this의 값 또한 4가지 경우의 수가 있다.
1. Regular Function Call
2. Dot Notation (Object Method Call)
3. Call, Apply, Bind
4. "new" keyword
1. Regular Function Call
예시
const age = 32;
function call() {
console.log(this.age); // 32
}
call();
- 일반적인 함수 호출에서의
this는 global 객체를 가르킨다. - 일반적인 함수에서의
this값
1. Non strict mode: Global Object
2. Strict Mode: undefined
const age = 32;
const jay = {
age: 31,
logAge: function () {
console.log(this.age);
}
};
const func = jay.logAge;
func();
- 위와 같은 경우에 func() 로 호출을 하면 jay 객체 안의 logAge가 일반 함수로 실행이된다.그래서 출력값은 global object인 32가 출력된다
2. Dot Notation
예시
const age = 32;
const jay = {
age: 31,
logAge: function () {
console.log(this.age);
}
};
const func = jay.logAge;
// Dot Notation
jay.logAge();
// Regular Function Call
func();
- Dot Notation은 함수선언식으로 만든 함수명에
.을 붙여서 실행하는 방법이다. - Dot Notation에서는 Regular Function Call과는 달리
.앞의 함수명이this가 된다. 그래서jay.logAge()의 결과값은 31,func()의 결과값은 32가 된다.
일반함수와 Dot Notation의 비교 예시
일반 함수
const age = 100;
function verifyAge () {
return this.age > 21;
}
const jay = {
age: 20,
verifyAge: verifyAge
};
const beerShop = {
sellBeer: function (customer) {
if (!verifyAge()) {
return "No Beer";
}
return "Beer";
}
};
beerShop.sellBeer(jay);
beerShop.sellBeer(jay)으로 함수 호출beerShop매개변수로 4번째줄jay가 불러짐- 조건문 안의
verifyAge()로 나이 인증 verifyAge()는 일반 함수 호출을 하였으므로 this는 globalage변수가 된다.- global
age는 100이므로"Beer"가 return 됨
Dot Notation
const age = 100;
function verifyAge () {
return this.age > 21;
}
const jay = {
age: 20,
verifyAge: verifyAge
};
const beerShop = {
sellBeer: function (customer) {
if (!customer.verifyAge()) {
return "No Beer";
}
return "Beer";
}
};
beerShop.sellBeer(jay);
beerShop.sellBeer(jay)로 함수 호출beerShop매개변수로jay가 호출!customer.verifyAge()로 나이 인증!customer.verifyAge()는 Dot notation으로 호출되었으므로jay가 this가 됨jay의age는 20이므로"No Beer"가 return 됨
3. call, apply, bind
call
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/call
call메서드는 일반 함수 실행과 똑같이 실행을 하는데, 차이점이 있다면 첫번째 매개변수에 this값을 넣어서 호출할 수 있다는 것이다.call메서드의 첫번째 arg는 this값으로 사용되고 두번째 arg부터는 전부 call한 함수로 전달한다. 그리고 call 메서드의 arg 갯수 제한은 없다
예시
function logAge() {
console.log(this.age);
};
const person = {
age: 20;
};
logAge.call(person)
call메서드를 통해person변수를this로 binding한다.logAge()의this값은person이 된다- console.log를 통해
this.age값을 호출하면person의age인 20이 출력된다.
예시2
function foo (a, b, c) {
console.log(this.age);
console.log(a + b + c);
};
const jay = {
age: 32;
}
foo.call(jay, 1, 2, 3);
- 위와 같은 경우에서는
jay가this값으로 잡히고, 1, 2, 3이 매개변수로 넘어가서 결과값은 32와 6이 된다
apply
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
apply메서드도call과 같이 첫번째 args는this가 된다.apply와call의 차이점은 아래와 같다.
call은 첫번째 arg를 제외한 나머지를 전부 전달하고,apply는 첫번째 arg를 제외한 나머지를 배열로 처리해서 보낸다.call은 arg 갯수 제한이 없는 반면에,apply는 2개의 args만 받을 수 있다.
function foo (a, b, c) {
console.log(this.age);
console.log(a + b + c);
};
const jay = {
age: 32
};
foo.apply(jay, [1, 2, 3]);
- 위의
call과 결과값이 같지만apply는 두번째 매개변수를 배열로 보냈다.
bind
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
bind메서드는 원본 함수를 복제한 새로운 함수를 반환한다.
예시
function foo () {
console.log(this.name);
}
const who = {
name: jay
};
const bar = foo.bind(who);
bar();
bind도call처럼 받을수 있는 arg의 갯수에 대한 제한이 없다. 마찬가지로 첫번째가 this값으로 설정되고, 나머지는 매개변수이다.- 위의 코드에서
foo.bind(who)에서foo함수를 실행시키지는 않고,this값과 나머지 값들을 저장한 후, 새로운 함수를 리턴한다. 위 코드에서 실행되는 곳은bar()이다.
예시 2
function foo (a, b, c) {
console.log(this.age);
console.log(a + b + c);
};
const jay = {
age: 32;
};
const bar = foo.bind(jay, 1);
bar(2, 3);
foo.bind(jay, 1)로jay,1을 바인딩시킨foo함수를 변수bar에 저장bar(2, 3)으로 함수 실행- 기존에 바인딩 시킨
jay는this값이 되고1은 첫번째 매개변수(a),bar(2, 3)을 통해bar함수를 실행시키며,2, 3은 각각 두번째(b), 세번째(c) 매개변수가 된다. - 첫번째 줄의 결과값은
this의 대상이 된jay의 age인32, 두번째 줄은 함수 실행에서foo.bind()에서 매개변수로 넘어온 1 그리고bar()를 실행시키며 매개변수로 넘어온 2, 3을 더하여 6이 된다.
4. new keyword
function Person (name) {
this.name = name;
console.log(this);
}
new Person("jay");
new키워드로 함수를 사용하면 생성자 함수 라고 불린다.- 생성자 함수를 만들 때는 함수명을 대문자로 시작하는 표기법이 있다.
new키워드를 사용한 함수 내부에서this를 사용할 경우,this의 값은 빈 객체가 된다. 저 위에서this.name = name을 해줘서this객체에name프로퍼티가 들어간것이다.- 위
Person함수를 보면 return이 따로 명시되어 있지않다. 그럼 원래 내가 알고있는데로라면 return값은undefined가 되야한다. 하지만 생성자 함수에서는 return이 명시되어있지 않아도this를 return한다
Author And Source
이 문제에 관하여([TIL 10][JS] this), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@devpark_0x1c/TIL-11JS-this저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)