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
const age = 32;
function call() {
console.log(this.age); // 32
}
call();
this
는 global 객체를 가르킨다.this
값const age = 32;
const jay = {
age: 31,
logAge: function () {
console.log(this.age);
}
};
const func = jay.logAge;
func();
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();
.
을 붙여서 실행하는 방법이다..
앞의 함수명이 this
가 된다. 그래서 jay.logAge()
의 결과값은 31, func()
의 결과값은 32가 된다.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는 global age
변수가 된다.age
는 100이므로 "Beer"
가 return 됨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 됨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
이 된다this.age
값을 호출하면 person
의 age
인 20이 출력된다.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이 된다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
는 두번째 매개변수를 배열로 보냈다.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()
이다.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이 된다.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한다