22์ฅ this
22.1 this ํค์๋
-
๊ฐ์ฒด๋ ์ํ๋ฅผ ๋ํ๋ด๋ property์ ๋์์ ๋ํ๋ด๋ method๋ฅผ ํ๋์ ๋ ผ๋ฆฌ์ ์ธ ๋จ์๋ก ๋ฌถ์ ๊ฒ์ด๋ค.
-
method๋ ์์ ์ด ์ํ ๊ฐ์ฒด์ ์ํ, property๋ฅผ ์ฐธ์กฐํ๊ณ ๋ณ๊ฒฝํ ์ ์์ด์ผ ํ๋ค.
-
์ด๋ ๋ฉ์๋๊ฐ ์์ ์ด ์ํ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ฅผ ์ฐธ์กฐํ๋ ค๋ฉด ๋จผ์ ์์ ์ด ์ํ ๊ฐ์ฒด(์ ์๋ณ์)๋ฅผ ์ฐธ์กฐํ ์ ์์ด์ผ ํ๋ค.
-
๊ฐ์ฒด ๋ฆฌํฐ๋ด ๋ฐฉ์์ผ๋ก ์์ฑํ ๊ฐ์ฒด์ ๊ฒฝ์ฐ ์ด๋ฏธ ๊ณ ์ ์๋ณ์ ์ด๋ฆ์ด ๋ง๋ค์ด์ก์ผ๋ฏ๋ก ๋ฉ์๋ ๋ด๋ถ์์ ์์ ์ด ์ํ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ์๋ณ์๋ฅผ ์ฌ๊ท์ ์ผ๋ก ์ฐธ์กฐ ๊ฐ๋ฅํ๋ค.
const circle = {
radius: 5,
getDiameter() {
return 2 * circle.radius;
},
};
console.log(circle.getDiameter());
-
์ฐธ์กฐ ํํ์์ด ํ๊ฐ๋๋ ์์ ์ getDIameter ๋ฉ์๋๊ฐ ํธ์ถ๋์ด ํจ์ ๋ชธ์ฒด๊ฐ ์คํ๋๋ ์์ ์ด๋ค.
- ์ ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ circle ๋ณ์์ ํ ๋น๋๊ธฐ ์ง์ ์ ํ๊ฐ๋๋ค. ๋ฐ๋ผ์ ์๋์์ getDiameter ๋ฉ์๋๊ฐ ํธ์ถ๋๋ ์์ ์ ์ด๋ฏธ ๊ฐ์ฒด๊ฐ ์์ฑ๋์ด ๋ณ์์ ํ ๋น๋์์ผ๋ฏ๋ก ๋ฉ์๋ ๋ด๋ถ์์ circle ์๋ณ์ ์ฐธ์กฐ ๊ฐ๋ฅ
-
๊ทธ๋ฌ๋ ์์ฑ์ ํจ์ ๋ฐฉ์์ผ๋ก ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ, ์ธ์คํด์ค๊ฐ ์์ฑ๋๊ธฐ ์ ์ ํด๋น ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํฌ ์๋ณ์๊ฐ ํ์ํ๋ค. ์ด๊ฒ์ด ๋ฐ๋ก
this
์๋ณ์์ด๋ค. -
this๋ ์์ ์ด ์ํ ๊ฐ์ฒด ๋๋ ์์ ์ด ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค๋ ์๊ธฐ ์ฐธ์กฐ ๋ณ์๋ค.
- this๋ฅผ ํตํด ๊ฐ์ฒด ์์ ์ด ์์ฑํ ์ธ์คํด์ค์ ํ๋กํผํฐ์ ๋ฉ์๋ ์ฐธ์กฐ ๊ฐ๋ฅ
- this๋ JS ์์ง์ ์ํด ์๋ฌต์ ์์ฑ
- ํจ์ ํธ์ถ ์
arguments
๊ฐ์ฒด์this
๊ฐ ์๋ฌต์ ์ผ๋ก ํจ์ ๋ด๋ถ์ ์ ๋ฌ๋๊ณ , ์ง์ญ ๋ณ์์ฒ๋ผ ์ฌ์ฉ ๊ฐ๋ฅ - ๋จ, this ๋ฐ์ธ๋ฉ(this๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ)์ ํจ์ ํธ์ถ ๋ฐฉ์์ ์ํด ๋์ ์ผ๋ก ๊ฒฐ์
[!note] ๋ฐ์ธ๋ฉ ๋ฐ์ธ๋ฉ์ด๋ ์๋ณ์์ ๊ฐ์ ์ฐ๊ฒฐํ๋ ๊ณผ์ ๋ณ์ ์ ์ธ : ๋ณ์ ์ด๋ฆ๊ณผ ํ๋ณด๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ฃผ์(๊ฐ)์ ๋ฐ์ธ๋ฉํ๋ ๊ฒ
-
์๋ฐ๋ C++ ๊ฐ์ ํด๋์ค ๊ธฐ๋ฐ ์ธ์ด์์ this๋ ํญ์ ํด๋์ค๊ฐ ์์ฑํ๋ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
- JS์ this๋ ํจ์๊ฐ ํธ์ถ๋๋ ๋ฐฉ์์ ๋ฐ๋ผ ์ค์ ๊ฐ์ฒด๋ ์์ฑ๋ ์ธ์คํด์ค ๋ฑ ๋์ ์ผ๋ก ๊ฒฐ์ ๋๋ค. strict mode๋ this ๋ฐ์ธ๋ฉ์ ์ํฅ์ ์ค๋ค(20.6.1 ์ )
-
this๋ ์ ์ญ, ํจ์ ๋ด๋ถ ์ฝ๋ ์ด๋์์๋ ์ฐธ์กฐ ๊ฐ๋ฅํ๋ค.
- ํ์ง๋ง this๋ ๊ฐ์ฒด์ ๋ฉ์๋ ๋ด๋ถ, ์์ฑ์ ํจ์ ๋ด๋ถ์์๋ง ์๋ฏธ๊ฐ ์๋ค.
- ๋ฐ๋ผ์ strict mode๊ฐ ์ ์ฉ๋ ์ผ๋ฐ ํจ์์
this
์๋undefined
๊ฐ ๋ฐ์ธ๋ฉ๋๋ค. ์ผ๋ฐ ํจ์์์this
๋ฅผ ์ฌ์ฉํ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค.
22.2 ํจ์ ํธ์ถ ๋ฐฉ์๊ณผ this ๋ฐ์ธ๋ฉ
-
this ๋ฐ์ธ๋ฉ์ ํจ์ ํธ์ถ ๋ฐฉ์์ ๋ฐ๋ผ ๋์ ์ผ๋ก ๊ฒฐ์ ๋๋ค.
-
๊ทธ๋ฐ๋ฐ ๋์ผ ํจ์๋ ๋ค์ํ ๋ฐฉ์์ผ๋ก ํธ์ถ ๊ฐ๋ฅํ๋ค. <ํจ์ ํธ์ถ ๋ฐฉ์>
- ์ผ๋ฐ ํจ์ ํธ์ถ
- ๋ฉ์๋ ํธ์ถ
- ์์ฑ์ ํจ์ ํธ์ถ
- Function.prototype.apply/call/bind ๋ฉ์๋์ ์ํ ๊ฐ์ ํธ์ถ
const foo = function () {
console.dir(this);
};
// 1. ์ผ๋ฐ ํจ์ ํธ์ถ : this๋ ์ ์ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ์ง๋ค.
foo(); // window
// 2. ๋ฉ์๋ ํธ์ถ : this๋ ๋ฉ์๋ ํธ์ถํ ๊ฐ์ฒด obj๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
const obj = { foo };
obj.foo(); // obj
// 3. ์์ฑ์ ํจ์ ํธ์ถ : this๋ ์์ฑ์ ํจ์๊ฐ ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
new foo(); // foo {}
// 4. Function.prototype.apply/call/bind ๋งค์๋์ ์ํ ๊ฐ์ ํธ์ถ : this๋ ์ฃผ์ด์ง ์ธ์์ ์ํด ๊ฒฐ์ ๋๋ค.
const bar = { name: "bar" };
foo.call(bar); // bar
foo.apply(bar); // bar
foo.bind(bar)(); // bar
22.2.1 ์ผ๋ฐ ํจ์ ํธ์ถ
-
๊ธฐ๋ณธ์ ์ผ๋ก this์์๋ ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
-
์ ์ญ ํจ์ ํน์ ์ค์ฒฉ ํจ์๋ฅผ ์ผ๋ฐ ํจ์๋ก ํธ์ถํ๋ฉด this์ ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
-
๋จ, strict mode๊ฐ ์ ์ฉ๋ ์ผ๋ฐ ํจ์ ๋ด๋ถ this์๋ undefined๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
- ๊ฐ์ฒด๋ฅผ ์์ฑํ์ง ์๋ ์ผ๋ฐ ํจ์์์ this๋ ์๋ฏธ๊ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค.
-
์ฝ๋ฐฑ ํจ์ ๋ฑ ์ด๋ค ํจ์๋ผ๋ ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋๋ฉด this์ ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
-
์ธ๋ถ ํจ์์ ๋ด๋ถ ์ค์ฒฉ ํจ์, ์ฝ๋ฐฑ ํจ์์ this๊ฐ ์ผ์นํ์ง ์๋๋ค๋ ๊ฒ์ ์ค์ฒฉ ํจ์ ๋๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ํฌํผ ํจ์๋ก ๋์ํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ ๋ค.
- ๋ฐ๋ผ์ ๋ด๋ถ this ๋ฐ์ธ๋ฉ์ ์ธ๋ถ this ๋ฐ์ธ๋ฉ๊ณผ ์ผ์น์์ผ์ผ ํ ํ์์ฑ์ด ์๋ค.
- ์๋ก์ด ๋ณ์์ this๋ฅผ ๋ฏธ๋ฆฌ ๋ฃ์ด๋๊ณ ๊ฐ์ ธ๋ค ์ฐ๊ฑฐ๋, apply / call / bind ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
- ํ์ดํ ํจ์ ๋ด๋ถ์ this๋ ์์ ์ค์ฝํ์ this๋ฅผ ๊ฐ๋ฆฌํค๋ฏ๋ก, ์ฝ๋ฐฑ ํจ์๋ฅผ ํ์ดํ ํจ์๋ก ์ฐ๋ฉด ์์ฐ์ค๋ฝ๊ฒ this ๋ฐ์ธ๋ฉ์ด ์ผ์นํ๊ฒ ๋๋ค.
22.2.2 ๋ฉ์๋ ํธ์ถ
- ๋ฉ์๋๋ฅผ ํธ์ถํ ๋๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด, ํธ์ถํ ๋ ๋ง์นจํ ์ฐ์ฐ์ ์์ ๊ธฐ์ ๋ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
- ๋จ, ์ฃผ์์ ์ ๋ฉ์๋๋ฅผ ์์ ํ ๊ฐ์ฒด๊ฐ ์๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉ๋๋ค๋ ๊ฒ์ด๋ค.
const person = {
name: "Lee",
getName() {
return this.name;
},
};
์ด ์์ ์์ getName() ๋ฉ์๋๋ person ๊ฐ์ฒด ์์์ ์ ์๋์๋ค. ๊ทธ๋ฐ๋ฐ ๋ฉ์๋๋ ํ๋กํผํฐ์ ๋ฐ์ธ๋ฉ๋ ํจ์์ด๋ค.
- ์ฆ, person ๊ฐ์ฒด์ getName ํ๋กํผํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ํจ์ ๊ฐ์ฒด๋ ๋ค๋ฅธ ํ๋กํผํฐ๋ ๋ณ์์ ๋ฐ์ธ๋ฉํ๊ธฐ๋ง ํ๋ฉด ๋ ๋ฆฝ์ ์ผ๋ก ์กด์ฌ ๊ฐ๋ฅํ๋ค.
const anotherPerson = {
name: "Kim",
};
anotherPerson.getName = person.getName;
const getName = person.getName;
- ๋ฐ๋ผ์ ๋ฉ์๋ ๋ด๋ถ์ this๋ ํธ์ถ ์์ ์ ๊ฒฐ์ ๋์ด ํธ์ถํ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉ๋๋ค.
- ํ๋กํ ํ์ ๋ฉ์๋ ๋ด๋ถ์์ ์ฌ์ฉ๋ this๋ ํธ์ถํ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉ๋๋ค.
22.2.3 ์์ฑ์ ํจ์ ํธ์ถ
- ์์ฑ์ ํจ์ ๋ด๋ถ์ this์๋ ์์ฑ์ ํจ์๊ฐ ๋ฏธ๋์ ์์ฑํ ์ธ์คํด์ค๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
- Class ๊ธฐ๋ฐ ์ธ์ด์ ๋์ผํ๊ฒ ์๋ํ๋ฉฐ, ๋ง์ฝ new ์ฐ์ฐ์์ ํจ๊ป ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ์ง ์์ผ๋ฉด ์ผ๋ฐ ํจ์๋ก ๋์ํ๊ณ , this๋ ์ผ๋ฐ ํจ์์ ๋์ผํ๊ฒ ๋ฐ์ธ๋ฉ๋๋ค.
22.2.4 Function.prototype.apply/call/bind ๋ฉ์๋์ ์ํ ๊ฐ์ ํธ์ถ
- apply, call, bind๋ Function.prototype์ ๋ฉ์๋์ด๋ฏ๋ก ๋ชจ๋ ํจ์๊ฐ ์์๋ฐ์ ์ฌ์ฉํ ์ ์๋ค.
- apply์ call ๋ฉ์๋๋ ํจ์๋ฅผ ํธ์ถํ๋ฉด์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌํ ํน์ ๊ฐ์ฒด๋ฅผ ํธ์ถํ ํจ์์ this์ ๋ฐ์ธ๋ฉํ๋ค.
- apply์ call ๋ฉ์๋๋ ์ธ์ ์ ๋ฌ ๋ฐฉ์๋ง ๋ค๋ฅผ ๋ฟ ๋์ผํ๊ฒ ๋์ํ๋ค.
function getThisBinding() {
console.log(arguments);
return this;
}
const thisArg = { a: 1 };
console.log(getThisBinding.apply(thisArg, [1, 2, 3]));
console.log(getThisBinding.call(thisArg, 1, 2, 3));
-
apply ๋ฉ์๋๋ ์ธ์๋ฅผ ๋ฐฐ์ด๋ก ๋ฌถ์ด ์ ๋ฌํ๊ณ , call ๋ฉ์๋๋ ์ธ์๋ฅผ ์ผํ๋ก ๊ตฌ๋ถํ ๋ฆฌ์คํธ๋ก ์ ๋ฌํ๋ค.
-
apply, call ๋ฉ์๋์ ๋ํ์ ์ฉ๋๋ arguments ๊ฐ์ฒด์ ๊ฐ์ ์ ์ฌ ๋ฐฐ์ด ๊ฐ์ฒด์ ๋ฐฐ์ด ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์ด๋ค.
function convertArgsToArray() {
console.log(arguments);
const arr = Array.prototype.slice.call(arguments);
console.log(arr);
return arr;
}
convertArgsToArray(1, 2, 3); // [1, 2, 3]
- bind ๋ฉ์๋๋ ํจ์๋ฅผ ํธ์ถํ์ง ์๊ณ , ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌํ ๊ฐ์ผ๋ก this ๋ฐ์ธ๋ฉ์ด ๊ต์ฒด๋ ํจ์๋ฅผ ์๋กญ๊ฒ ์์ฑํด ๋ฐํํ๋ค.
function getThisBinding() {
return this;
}
const thisArg = { a: 1 };
// bind ๋ฉ์๋๋ ์ ๋ฌํ ์ธ์๋ก this๊ฐ ๊ต์ฒด๋ getThisBinding์ ์๋กญ๊ฒ ์์ฑํด ๋ฐํํ๋ค.
console.log(getThisBinding.bind(thisArg)); // getThisBinding
//bind ๋ฉ์๋๋ ํจ์๋ฅผ ํธ์ถํด์ฃผ์ง ์์ผ๋ฏ๋ก ๋ฐํ๋ ํจ์๋ฅผ ํธ์ถํ๋ ค๋ฉด ๋ช
์์ ์ผ๋ก ๋ค์ ํธ์ถํด์ผ ํ๋ค.
console.log(getThisBinding.bind(thisArg)()); // {a: 1}
- bind ๋ฉ์๋๋ ๋ด๋ถ ์ค์ฒฉ ํจ์, ์ฝ๋ฐฑ ํจ์์ this ๋ถ์ผ์น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
const person = {
name: 'Lee',
foo(callback) {
setTimeout(callback.bind(this), 100);
}
};
person.foo(function() {
console.log('Hi! my name is ${this.name}.`);
})