[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.)