this ํค์๋
this๋ ์์ ์ด ์ํ ๊ฐ์ฒด ๋๋ ์์ ์ด ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค๋ ์๊ธฐ ์ฐธ์กฐ ๋ณ์๋ค. this๋ฅผ ํตํด ์์ ์ด ์ํ ๊ฐ์ฒด ๋๋ ์์ ์ด ์์ฑํ ์ธ์คํด์ค์ ํ๋กํผํฐ๋ ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ ์ ์๋ค. ํจ์๋ฅผ ํธ์ถํ ๋ arguments ๊ฐ์ฒด์ this๊ฐ ์๋ฌต์ ์ผ๋ก ํจ์ ๋ด๋ถ์ ์ ๋ฌ๋๋ค. ๋จ, this๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ, ์ฆ this ๋ฐ์ธ๋ฉ์ ํจ์ ํธ์ถ ๋ฐฉ์์ ์ํด ๋์ ์ผ๋ก ๊ฒฐ์ ๋๋ค.
// ์ ์ญ์์ this → ์ ์ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log(this); //window
// ์ผ๋ฐ ํจ์ ๋ด๋ถ์ this → ์ ์ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
function test() {
console.log(this); // window
}
// stric mode๊ฐ ์ ์ฉ๋ ์ผ๋ฐ ํจ์ ๋ด๋ถ์ this → undefined๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
// (์ผ๋ฐ ํจ์์์ this๋ฅผ ์ฌ์ฉํ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ)
function stric() {
'use strict';
console.log(this); // undefined
}
// ๋ฉ์๋ ๋ด๋ถ this → ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
const person = {
name: 'Lee',
getName() {
console.log(this); // {name: 'Lee', getName: f}
}
};
// ์์ฑ์ ํจ์ ๋ด๋ถ this → ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
function Person(name) {
this.name = name;
console.log(this); // Person {name: 'Lee'}
}
ํจ์ ํธ์ถ ๋ฐฉ์๊ณผ this ๋ฐ์ธ๋ฉ
์ผ๋ฐ ํจ์ ํธ์ถ
์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ ๋ชจ๋ ํจ์(์ค์ฒฉ ํจ์, ์ฝ๋ฐฑ ํจ์ ํฌํจ) ๋ด๋ถ์ this์๋ ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ ๋๋ค.
function one() {
console.log(this); // window
function two() {
console.log(this); // window
}
two();
}
one();
const obj = {
value: 100,
one() {
console.log(this); // {value: 100, one: f}
function two() {
console.log(this); // window
}
two();
// ์ฝ๋ฐฑ ํจ์๊ฐ ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋๋ค๋ฉด ์ฝ๋ฐฑ ํจ์์ ๋ด๋ถ this์๋ ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ
setTimeout(function () {
console.log(this); // window
}, 0);
},
};
obj.one();
ํ์ง๋ง ๋ฉ์๋ ๋ด์์ ์ ์ํ ์ค์ฒฉ ํจ์ ๋๋ ๋ฉ์๋์๊ฒ ์ ๋ฌํ ์ฝ๋ฐฑ ํจ์๊ฐ ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ ๋ ๋ฉ์๋ ๋ด์ ์ค์ฒฉ ํจ์ ๋๋ ์ฝ๋ฐฑ ํจ์์ this๊ฐ ์ ์ญ ๊ฐ์ฒด๋ฅผ ๋ฐ์ธ๋ฉ ํ๋ ๊ฒ์ ํฌํผ ํจ์๋ก ๋์ํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ ๋ค. ๋ฉ์๋ ๋ด๋ถ์ ์ค์ฒฉ ํจ์๋ ์ฝ๋ฐฑ ํจ์์ this ๋ฐ์ธ๋ฉ์ ๋ฉ์๋์ this ๋ฐ์ธ๋ฉ๊ณผ ์ผ์น์ํค๊ธฐ ์ํ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
const obj = {
value: 100,
one() {
// ๋ฐฉ๋ฒ1. this ๋ฐ์ธ๋ฉ์ ๋ณ์ that์ ํ ๋น
const that = this;
setTimeout(function () {
console.log(that); // {value: 100, one: f}
}, 0);
// ๋ฐฉ๋ฒ2. ์ฝ๋ฐฑ ํจ์์ ๋ช
์์ ์ผ๋ก this๋ฅผ ๋ฐ์ธ๋ฉ
setTimeout(
function () {
console.log(this); // {value: 100, one: f}
}.bind(this),
0
);
// ๋ฐฉ๋ฒ3. ํ์ดํ ํจ์ ๋ด๋ถ์ this๋ ์์ ์ค์ฝํ์ this๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
setTimeout(() => console.log(this), 0); // {value: 100, one: f}
},
};
obj.one();
๋ฉ์๋ ํธ์ถ
๋ฉ์๋ ๋ด๋ถ์ this์๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด, ์ฆ ๋ฉ์๋๋ฅผ ํธ์ถํ ๋ ๋ฉ์๋ ์ด๋ฆ ์์ ๋ง์นจํ(.) ์ฐ์ฐ์ ์์ ๊ธฐ์ ํ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ ๋๋ค. ์ฃผ์ํ ๊ฒ์ ๋ฉ์๋ ๋ด๋ถ์ this๋ ๋ฉ์๋๋ฅผ ์์ ํ ๊ฐ์ฒด๊ฐ ์๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉ๋๋ค๋ ๊ฒ์ด๋ค.
const person = {
name: 'Lee',
getName() {
return this.name;
},
};
console.log(person.getName()); // Lee
๋ฉ์๋๋ ๊ฐ์ฒด์ ํฌํจ๋ ๊ฒ์ด ์๋๋ผ ๋ ๋ฆฝ์ ์ผ๋ก ์กด์ฌํ๋ ๋ณ๋์ ๊ฐ์ฒด๋ค. ๊ฐ์ฒด์ ํ๋กํผํฐ๊ฐ ํจ์ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์์ ๋ฟ์ด๋ค. ๋ฐ๋ผ์ ๋ฉ์๋๋ ๋ค๋ฅธ ๊ฐ์ฒด์ ํ๋กํผํฐ์ ํ ๋นํ๋ ๊ฒ์ผ๋ก ๋ค๋ฅธ ๊ฐ์ฒด์ ๋ฉ์๋๊ฐ ๋ ์๋ ์๊ณ ์ผ๋ฐ ๋ณ์์ ํ ๋นํ์ฌ ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ ์๋ ์๋ค.
const person1 = {
name: 'Lee',
getName() {
return this.name;
},
};
const person2 = {
name: 'Kim',
};
// getName ๋ฉ์๋๋ฅผ person2 ๊ฐ์ฒด์ ๋ฉ์๋๋ก ํ ๋น
person1.getName = person2.getName;
console.log(person2.getName()); // Kim
// getName ๋ฉ์๋๋ฅผ ๋ณ์์ ํ ๋น
const getName = person1.getName;
console.log(getName()); // '' (window.name ์ ๋ธ๋ผ์ฐ์ ์ฐฝ์ ์ด๋ฆ์ ๋ํ๋ด๋ ๋นํธ์ธ ํ๋กํผํฐ)
ํ๋กํ ํ์ ๋ฉ์๋ ๋ด๋ถ์์ ์ฌ์ฉ๋ this๋ ์ผ๋ฐ ๋ฉ์๋์ ๋ง์ฐฌ๊ฐ์ง๋ก ํด๋น ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉ ๋๋ค.
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
};
const me = new Person('Lee');
console.log(me.getName()); // Lee
Person.prototype.name = 'Kim';
console.log(Person.prototype.getName()); // Kim
์์ฑ์ ํจ์ ํธ์ถ
์์ฑ์ ํจ์ ๋ด๋ถ์ this์๋ ์์ฑ์ ํจ์๊ฐ ๋ฏธ๋์ ์์ฑํ ์ธ์คํด์ค๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
function Person(name) {
this.name = name;
this.getName = function () {
return this.name;
};
}
const person1 = new Person('Lee');
const person2 = new Person('Kim');
console.log(person1.getName()); // 'Lee'
console.log(person2.getName()); // 'Kim'
Function.prototype.apply/call/bind ๋ฉ์๋์ ์ํ ๊ฐ์ ํธ์ถ
Function.prototype.apply(thisArg[, argArray])
- thisArg : this๋ก ์ฌ์ฉํ ๊ฐ์ฒด
- argArray : ํจ์์๊ฒ ์ ๋ฌํ ์ธ์ ๋ฆฌ์คํธ์ ๋ฐฐ์ด ๋๋ ์ ์ฌ ๋ฐฐ์ด ๊ฐ์ฒด (ํธ์ถํ ํจ์์ ์ธ์๋ฅผ ๋ฐฐ์ด๋ก ๋ฌถ์ด ์ ๋ฌ)
- ํจ์๋ฅผ ํธ์ถํ๊ณ ํธ์ถ๋ ํจ์์ ๋ฐํ๊ฐ์ return
Function.prototype.call(thisArg[, arg1 [, arg2 [, ...]]])
- thisArg : this๋ก ์ฌ์ฉํ ๊ฐ์ฒด
- arg1, arg2, ... : ํจ์์๊ฒ ์ ๋ฌํ ์ธ์ ๋ฆฌ์คํธ (ํธ์ถํ ํจ์์ ์ธ์๋ฅผ ์ผํ๋ก ๊ตฌ๋ถํ ๋ฆฌ์คํธ ํ์์ผ๋ก ์ ๋ฌ)
- ํจ์๋ฅผ ํธ์ถํ๊ณ ํธ์ถ๋ ํจ์์ ๋ฐํ๊ฐ์ return
Function.prototype.bind(thisArg[, arg1[, arg2[, ...]]])
- thisArg : this๋ก ์ฌ์ฉํ ๊ฐ์ฒด
- arg1, arg2, ... : ํจ์์๊ฒ ์ ๋ฌํ ์ธ์ ๋ฆฌ์คํธ (ํธ์ถํ ํจ์์ ์ธ์๋ฅผ ์ผํ๋ก ๊ตฌ๋ถํ ๋ฆฌ์คํธ ํ์์ผ๋ก ์ ๋ฌ)
- ํจ์๋ฅผ ํธ์ถํ์ง ์๊ณ this ๋ฐ์ธ๋ฉ์ด ๊ต์ฒด๋ ํจ์๋ฅผ ์๋กญ๊ฒ ์์ฑํด์ retrun
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์ ๋ฉ์๋ ๋ด๋ถ์ ์ค์ฒฉ ํจ์ ๋๋ ์ฝ๋ฐฑ ํจ์์ this๊ฐ ๋ถ์ผ์นํ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค.
const person = {
name: 'Lee',
test(callback) {
setTimeout(callback.bind(this), 100);
},
};
person.test(function () {
console.log(this.name); // Lee
});
ํจ์ ํธ์ถ ๋ฐฉ์ | this ๋ฐ์ธ๋ฉ |
์ผ๋ฐ ํจ์ ํธ์ถ | ์ ์ญ ๊ฐ์ฒด |
๋ฉ์๋ ํธ์ถ | ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด |
์์ฑ์ ํจ์ ํธ์ถ | ์์ฑ์ ํจ์๊ฐ ์์ฑํ ์ธ์คํด์ค |
Function.prototype.apply/call/bind ๋ฉ์๋์ ์ํ ๊ฐ์ ํธ์ถ | Function.prototype.apply/caa/bind ๋ฉ์๋์ ์ฒซ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌํ ๊ฐ์ฒด |