๊ฐ์ฒด
๋ ์ํ๋ฅผ ๋ํ๋ด๋ํ๋กํผํฐ
์ ๋์์ ๋ํ๋ด๋๋ฉ์๋
๋ฅผ ํ๋์ ๋ ผ๋ฆฌ์ ์ธ ๋จ์๋ก ๋ฌถ์ ๋ณตํฉ์ ์ธ ์๋ฃ๊ตฌ์กฐ๋ค.
๋ฉ์๋
๋ ํ๋กํผํฐ๋ฅผ ์ฐธ์กฐํ๊ณ ๋ณ๊ฒฝํ ์ ์์ด์ผ ํ๋ค. ์ด ๋๋ฉ์๋
๊ฐ ์์ ์ด ์ํ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ฅผ ์ฐธ์กฐํ๋ ค๋ฉด ์์ ์ด ์ํ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ์๋ฐ์๋ฅผ ์ฐธ์กฐํ ์ ์์ด์ผ ํ๋ค.
โ ๊ฐ์ฒด ๋ฆฌํฐ๋ด ๋ฐฉ์์ผ๋ก ์์ฑํ ๊ฐ์ฒด์ ๊ฒฝ์ฐ
const circle = {
// ํ๋กํผํฐ: ๊ฐ์ฒด ๊ณ ์ ์ ์ํ ๋ฐ์ดํฐ
radius: 5,
// ๋ฉ์๋: ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฐธ์กฐํ๊ณ ์กฐ์ํ๋ ๋์
getDiameter() {
// ์ด ๋ฉ์๋๊ฐ ์์ ์ด ์ํ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ ๋ค๋ฅธ ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ๋ ค๋ฉด
// ์์ ์ด ์ํ ๊ฐ์ฒด์ธ circle์ ์ฐธ์กฐํ ์ ์์ด์ผ ํ๋ค.
return 2 * circle.radius;
}
};
console.log(circle.getDiameter()); // 10
๊ฐ์ฒด ๋ฆฌํฐ๋ด ๋ฐฉ์์ผ๋ก ์์ฑํ ๊ฐ์ฒด์ ๊ฒฝ์ฐ ๋ฉ์๋ ๋ด๋ถ์์ ์์ ์ด ์ํ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ์๋ณ์ ์ฌ๊ท์ ์ผ๋ก ์ฐธ์กฐํ ์ ์๋ค.
ํ์ง๋ง ์๊ธฐ ์์ ์ด ์ํ ๊ฐ์ฒด๋ฅผ ์ฌ๊ท์ ์ผ๋ก ์ฐธ์กฐํ๋ ๋ฐฉ์์ ์ผ๋ฐ์ ์ด์ง๋ ๋ฐ๋์งํ์ง๋ ์๋ค.
โ ์์ฑ์ ํจ์ ๋ฐฉ์์ผ๋ก ์ธ์คํด์ค ์์ฑํ๋ ๊ฒฝ์ฐ
function Circle(radius); {
// ์ด ์์ ์๋ ์์ฑ์ ํจ์ ์์ ์ด ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค๋ ์๋ณ์๋ฅผ ์ ์ ์๋ค.
????.radius = radius
}
Circle.prototype.getDiameter. = function () {
// ์ด ์์ ์๋ ์์ฑ์ ํจ์ ์์ ์ด ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค๋ ์๋ณ์๋ฅผ ์ ์ ์๋ค.
return 2 * ????.radius;
};
// ์์ฑ์ ํจ์๋ก ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ค๋ฉด ๋จผ์ ์์ฑ์ ํจ์๋ฅผ ์ ์ํด์ผ ํ๋ค.
const circle = new Circle(5);
์์ฑ์ ํจ์๋ฅผ ์ ์ํ๋ ์์ ์๋ ์์ง ์ธ์คํฐ์ค๊ฐ ์์ฑํ๊ธฐ ์ด์ ์ด๋ฏ๋ก ์์ ์ด ์ํ ๊ฐ์ฒด ๋๋ ์์ ์ด ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค๋ ํน์ํ ์๋ณ์๊ฐ ํ์ํ๋ค. ์ด๋ฅผ ์ํด ์๋ฐ์คํฌ๋ฆฝํธ๋
this
๋ผ๋ ํน์ํ ์๋ณ์ ์ ๊ณต.
this
๋ ์์ ์ด ์ํ ๊ฐ์ฒด ๋๋ ์์ ์ด ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค๋์๊ธฐ ์ฐธ์กฐ ๋ณ์
๋ค.this
๋ฅผ ํตํด ์์ ์ด ์ํ ๊ฐ์ฒด ๋๋ ์์ ์ด ์์ฑํ ์ธ์คํด์ค์ ํ๋กํผํฐ๋ ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ ์ ์๋ค.
this
๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ์ํด ์๋ฌต์ ์ผ๋ก ์์ฑ๋๋ฉฐ, ์ฝ๋ ์ด๋์๋ ์ฐธ์กฐ ๊ฐ๋ฅํ๊ณ ํจ์๋ฅผ ํธ์ถํ๋ฉดarguments
๊ฐ์ฒด์this
๊ฐ ์๋ฌต์ ์ผ๋ก ํจ์ ๋ด๋ถ์ ์ ๋ฌ๋๋ฉฐ, ํจ์ ๋ด๋ถ์์arguments
๊ฐ์ฒด๋ฅผ ์ง์ญ ๋ณ์์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ฒ๋ผthis
๋ ์ง์ญ ๋ณ์์ฒ๋ผ ์ฌ์ฉ๊ฐ๋ฅ.
๋จ,this
๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ, ์ฆthis
๋ฐ์ธ๋ฉ์ ํจ์ ํธ์ถ ๋ฐฉ์์ ์ํด ๋์ ์ผ๋ก ๊ฒฐ์ ๋๋ค.
๐ก this
๋ฐ์ธ๋ฉ ์ด๋?
๋ฐ์ธ๋ฉ
์ด๋ ์๋ณ์์ ๊ฐ์ ์ฐ๊ฒฐํ๋ ๊ณผ์ ์ ์๋ฏธ. ์๋ฅผ ๋ค์ด ๋ณ์ ์ ์ธ์ ๋ฒผ์ ์ด๋ฆ(์๋ณ์)๊ณผ ํ๋ณด๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ฃผ์๋ฅผ ๋ฐ์ธ๋ฉํ๋ ๊ฒ์ด๋ค.this ๋ฐ์ธ๋ฉ
์this
(ํค์๋๋ก ๋ถ๋ฅ๋์ง๋ง ์๋ณ์ ์ญํ ์ ํ๋ค.)์this
๊ฐ ๊ฐ๋ฆฌํฌ ๊ฐ์ฒด๋ฅผ ๋ฐ์ธ๋ฉํ๋ ๊ฒ์ด๋ค.
โ ์๋ฐ์คํฌ๋ฆฝํธ์ this
๋ ํจ์๊ฐ ํธ์ถ๋๋ ๋ฐฉ์์ ๋ฐ๋ผ this์ ๋ฐ์ธ๋ฉ๋ ๊ฐ, ์ฆ this
๋ฐ์ธ๋ฉ์ด ๋์ ์ผ๋ก ๊ฒฐ์ ๋๋ค
// this๋ ์ด๋์๋ ์ง ์ฐธ์กฐ ๊ฐ๋ฅํ๋ค.
// ์ ์ญ์์ this๋ ์ ์ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log(this); // window
function square(numer) {
// ์ผ๋ฐ ํจ์ ๋ด๋ถ์์ this๋ ์ ์ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log(this); // window
return number * number;
}
square(2);
const person = {
name: 'Lee',
getName() {
// ๋ฉ์๋ ๋ด๋ถ์์ this๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log(this); // {name: "Lee", getName: f}
return this.name;
}
};
console.log(person.getName()); // Lee
function Person(name) {
this.name = name;
// ์์ฑ์ ํจ์ ๋ด๋ถ์์ this๋ ์์ฑ์ ํจ์๊ฐ ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log(this); // Person {name: "Lee"}
}
const me = new Person('Lee');
this
๋ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ๊ธฐ ์ํ์๊ธฐ ์ฐธ์กฐ ๋ณ์
์ผ๋ฐ์ ์ผ๋ก ๊ฐ์ฒด์๋ฉ์๋ ๋ด๋ถ
๋๋์์ฑ์ ํจ์ ๋ด๋ถ
์์๋ง ์๋ฏธ๊ฐ ์๋ค. ์ผ๋ฐ ํจ์ ๋ด๋ถ์์this
๋ฅผ ์ฌ์ฉํ ํ์๋ ์๋ค.
this
๋ฐ์ธ๋ฉ(this์ ๋ฐ์ธ๋ฉ๋ ๊ฐ)์ ํจ์ ํธ์ถ ๋ฐฉ์, ์ฆ ํจ์๊ฐ ์ด๋ป๊ฒ ํธ์ถ๋์๋์ง์ ๋ฐ๋ผ ๋์ ์ผ๋ก ๊ฒฐ์ ๋๋ค.
๐ก ๋ ์์ปฌ ์ค์ฝํ์ this ๋ฐ์ธ๋ฉ์ ๊ฒฐ์ฑ ์๊ธฐ๊ฐ ๋ค๋ฅด๋ค.
ํจ์์ ์์ ์ค์ฝํ๋ฅผ ๊ฒฐ์ ํ๋ ๋ฐฉ์์ธ
๋ ์์ปฌ ์ค์ฝํ
๋ ํจ์ ์ ์๊ฐ ํ๊ฐ๋์ด ํจ์ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ ์์ ์ ์์ ์ค์ฝํ๋ฅผ ๊ฒฐ์ ํ๋ค. ํ์ง๋งthis
๋ฐ์ธ๋ฉ์ ํจ์ ํธ์ถ ์์ ์ ๊ฒฐ์ ๋๋ค.
// this ๋ฐ์ธ๋ฉ์ ํจ์ ํธ์ถ ๋ฐฉ์์ ๋ฐ๋ผ ๋์ ์ผ๋ก ๊ฒฐ์ ๋๋ค.
const foo = function () {
console.dir(this);
};
// ๋์ผํ ํจ์๋ ๋ค์ํ ๋ฐฉ์์ผ๋ก ํธ์ถํ ์ ์๋ค.
// 1. ์ผ๋ฐ ํจ์ ํธ์ถ
// foo ํจ์๋ฅผ ์ผ๋ฐ์ ์ธ ๋ฐฉ์์ผ๋ก ํธ์ถ
// foo ํจ์ ๋ด๋ถ์ this๋ ์ ์ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
foo();
// 2. ๋ฉ์๋ ํธ์ถ
// foo ํจ์๋ฅผ ํ๋กํผํฐ ๊ฐ์ผ๋ก ํ ๋นํ์ฌ ํธ์ถ
// foo ํจ์ ๋ด๋ถ์ this๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด obj๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
const obj = { foo };
obj.foo(); // obj
// 3. ์์ฑ์ ํจ์ ํธ์ถ
// foo ํจ์๋ฅผ new ์ฐ์ฐ์์ ํจ๊ป ์์ฑ์ ํจ์๋ก ํธ์ถ
// foo ํจ์ ๋ด๋ถ์ this๋ ์์ฑ์ ํจ์๊ฐ ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
new foo(); // foo {}
// 4. Function.prototype.apply/call/bind ๋ฉ์๋์ ์ํ ๊ฐ์ ํธ์ถ
const bar = { name: 'bar' };
foo.call(bar); // bar
foo.apply(bar); // bar
foo.bind(bar)(); // bar
๊ธฐ๋ณธ์ ์ผ๋ก
this
์๋์ ์ญ ๊ฐ์ฒด
๊ฐ ๋ฐ์ธ๋ฉ ๋๋ค.
function foo() {
console.log("foo's this: ", this);
function bar() {
console.log("bar's this: ", this);
}
bar();
}
foo();
์ ์ญ ํจ์๋ ๋ฌผ๋ก ์ด๊ณ ์ค์ฒฉ ํจ์๋ฅผ ์ผ๋ฐ ํจ์๋ก ํธ์ถํ๋ฉด ํจ์ ๋ด๋ถ์
this
์๋ ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ๋๋ค. ๋ค๋งthis
๋ ๊ฐ์ฒด์ด ํ๋กํผํฐ๋ ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ๊ธฐ์ํ์๊ธฐ ์ฐธ์กฐ ๋ณ์
์ด๋ฏ๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ์ง ์๋ ์ผ๋ฐ ํจ์์์this
๋ ์๋ฏธ์๋ค.
๋ฐ๋ผ์ ์๋ ์์ ์ฒ๋ผstrict mode
๊ฐ ์ ์ฉ๋ ์ผ๋ฐ ํจ์ ๋ด๋ถ์this
๋undefined
๊ฐ ๋ฐ์ธ๋ฉ.
function foo() {
'use strict';
console.log("foo's this: ", this);
function bar() {
console.log("bar's this: ", this);
}
bar();
}
foo();
โ ๋ฉ์๋๋ด์ ์ ์ํ ์ค์ฒฉ ํจ์๋ ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋๋ฉด this์ ์ ์ญ ๊ฐ์ฒด ๋ฐ์ธ๋ฉ๋๋ค.
// var ํค์๋๋ก ์ ์ธํ ์ ์ญ ๋ณ์ value๋ ์ ์ญ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ค.
var value = 1;
// const ํค์๋ค ์ ์ธํ ์ ์ญ ๋ณ์ value๋ ์ ์ญ ๊ฐ์ฒด์ ํ๋กํผํฐ๊ฐ ์๋๋ค.
// const value = 1;
const obj = {
value : 100,
foo() {
console.log("foo's this: ", this); // {value: 100, foo:f}
console.log("foo's this.value: ", this.value); // 100
// ๋ฉ์๋ ๋ด์์ ์ ์ํ ์ค์ฒฉ ํจ์
function bar() {
console.log("bar's this: ", this); // window
console.log("bar's this.value: ", this.value); // 1
}
// ๋ฉ์๋ ๋ด์์ ์ ์ํ ์ค์ฒฉ ํจ์๋ ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋๋ฉด ์ค์ฒฉ ํจ์ ๋ด๋ถ์
// ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
bar();
}
};
obj.foo();
โ ์ฝ๋ฐฑ ํจ์๊ฐ ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋๋ค๋ฉด ์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์ this
์ ์ ์ญ ๊ฐ์ฒด ๋ฐ์ธ๋ฉ๋๋ค.
var value = 1;
const obj = {
value: 100;
foo() {
console.log("foo's this: ", this); // {value: 100, foo: f}
// ์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์ this์๋ ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ ๋๋ค.
setTimeoit(function () {
console.log("callback's this: ", this); // window
console.log("callback's this: ", this.value) // 1
}, 100);
}
};
obj.foo();
์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ ๋ชจ๋ ํจ์(์ค์ฒฉ ํจ์, ์ฝ๋ฐฑ ํจ์ ํฌํจ) ๋ด๋ถ์
this
์๋ ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ
๐ก ๋ฉ์๋ ๋ด๋ถ์ ์ค์ฒฉํจ์๋ ์ฝ๋ฐฑ ํจ์์ this
๋ฐ์ธ๋ฉ ๋ฉ์๋์ this
๋ฐ์ธ๋ฉ ์ผ์น ์ํค๋ ๋ฐฉ๋ฒ
var value = 1;
const obj = {
value: 100,
foo() {
// this ๋ฐ์ธ๋ฉ(obj)์ ๋ณ์ that์ ํ ๋นํ๋ค.
const that = this;
// ์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์์ this ๋์ that์ ์ฐธ์กฐํ๋ค.
setTimeout(function () {
console.log(that.value); // 100
}, 100);
}
};
obj.foo();
โ this
๋ฅผ ๋ช
์์ ์ผ๋ก ๋ฐ์ธ๋ฉํ ์ ์๋ Function.prototype.apply
Function.prototype.call
Function.prototype.bind
๋ฉ์๋๋ก ๋ช
์์ ๋ฐ์ธ๋ฉ
var value = 1;
const obj = {
value: 100,
foo() {
// ์ฝ๋ฐฑ ํจ์์ ๋ช
์์ ์ผ๋ก this๋ฅผ ๋ฐ์ธ๋ฉํ๋ค.
setTimeout(function () {
console.log(this.value); // 100
}.bind(this), 100);
}
};
obj.foo();
โ ํ์ดํ ํจ์๋ฅผ ์ฌ์ฉํด this ๋ฐ์ธ๋ฉ ์ผ์น
var value = 1;
const obj = {
value : 100,
foo() {
// ํ์ดํ ํจ์ ๋ด๋ถ์ this๋ ์์ ์ค์ฝํ์ this๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
setTimeout(() => console.log(this.value), 100); // 100
}
};
obj.foo();
๋ฉ์๋ ๋ด๋ถ์
this
์๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด, ์ฆ ๋ฉ์๋๋ฅผ ํธ์ถํ ๋ ๋ฉ์๋ ์ด๋ฆ ์์ ๋ง์นจํ.
์ฐ์ฐ์ ์์ ๊ธฐ์ ํ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
์ฃผ์! ๋ฉ์๋ ๋ด๋ถ์this
๋ ๋ฉ์๋๋ฅผ ์์ ํ ๊ฐ์ฒด๊ฐ ์๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉ
const person = {
name : 'Noh',
getName() {
// ๋ฉ์๋ ๋ด๋ถ์ this๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉ๋๋ค.
retrun this.name // ์ฌ๊ธฐ์ this๋ ํธ์ถํ ๊ฐ์ฒด๋ฅผ ๋ปํ๋ค.
}
};
// ๋ฉ์๋ getName์ ํธ์ถํ ๊ฐ์ฒด๋ person์ด๋ค.
console.log(person.getName()); // Noh
// getName ๋ฉ์๋ ๋ค๋ฅธ ๊ฐ์ฒด์ ๋ฉ์๋๊ฐ ๋ ์๋ ์๊ณ
// ์ผ๋ฐ ๋ณ์์ ํ ๋นํ์ฌ ์ผ๋ฐ ํจ์๋ก ํธ์ถ ๊ฐ๋ฅ.
cosnt anotherPerson = {
name: 'YoungWan'
};
// getName ๋ฉ์๋๋ฅผ anotherPerson ๊ฐ์ฒด์ ๋ฉ์๋๋ก ํ ๋น
anotherPerson.getName = person.getName;
// getName ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด๋ anotherPerson์ด๋ค.
// ์ฌ๊ธฐ์ ํธ์ถํ ๊ฐ์ฒด์ this๋ anotherPerson์ ๊ฐ๋ฆฌํจ๋ค.
console.log(anotherPerson.getName()); // YounWan
// getName ๋ฉ์๋๋ฅผ ๋ณ์์ ํ ๋น
const getName = person.getName;
// getName ๋ฉ์๋๋ฅผ ์ผ๋ฐ ํจ์๋ก ํธ์ถ
console.log(getName()); // ''
// ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ getName ํจ์ ๋ด๋ถ์ this๋ ์ ์ญ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํด ์ฆ, window.name๊ฐ ๊ฐ์.
๋ฉ์๋ ๋ด๋ถ์
this
๋ ํ๋กํผํฐ๋ก ๋ฉ์๋๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋ ๊ฐ์ฒด์๋ ๊ด๊ณ๊ฐ ์๊ณ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉ.
โ ํ๋กํ ํ์
๋ฉ์๋ ๋ด๋ถ์์ ์ฌ์ฉ๋ this
๋ ์ผ๋ฐ ๋ฉ์๋์ ๋ง์ฐฌ๊ฐ์ง ํธ์ถํ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉ
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
};
const me = new Person('Lee');
// getName ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด๋ me๋ค.
console.log(me.getName()); // โ Lee
Person.prototype.name = 'Kim';
// getName ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด๋ Person.prototype์ด๋ค.
console.log(Person.prototype.getName()); // โก Kim
โ ์ ๊ฒฝ์ฐ getName๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด๋ me์ด๋ค. ๋ฐ๋ผ์ getName๋ฉ์๋ ๋ด๋ถ์ this๋ me๋ฅผ ๊ฐ๋ฆฌํค๋ฉฐ this.name๊ฐ์ Lee๋ค.
โก์ ๊ฒฝ์ฐ getName๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด๋ Person.prototype์ด๊ณ , ๊ฐ์ฒด์ด๋ฏ๋ก ์ง์ ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์๋ค. ๋ฐ๋ผ์ getName๋ฉ์๋ ๋ด๋ถ์ this๋ Person.prototype์ ๊ฐ๋ฆฌํค๋ฉฐ this.name๊ฐ์ Kim์ด๋ค.
์์ฑ์ ํจ์ ๋ด๋ถ์
this
์๋ ์์ฑ์ ํจ์๊ฐ (๋ฏธ๋์) ์์ฑํ ์ธ์คํด์ค๊ฐ ๋ฐ์ธ๋ฉ
// ์์ฑ์ ํจ์
function Circle(radius) {
// ์์ฑ์ ํจ์ ๋ด๋ถ์ this๋ ์์ฑ์ ํจ์๊ฐ ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}
// ๋ฐ์ง๋ฆ์ด 5์ธ Circle ๊ฐ์ฒด๋ฅผ ์์ฑ
const circle1 = new Circle(5);
// ๋ฐ์ง๋ฆ์ด 10์ธ Circle ๊ฐ์ฒด๋ฅผ ์์ฑ
const circle2 = new Circle(10);
console.log(circle1.getDiameter()); // 10
console.log(circle2.getDiameter()); // 20
// new ์ฐ์ฐ์์ ํจ๊ป ํธ์ถํ์ง ์์ผ๋ฉด ์์ฑ์ ํจ์๋ก ๋์ํ์ง ์๋๋ค. ์ฆ, ์ผ๋ฐ์ ์ธ ํจ์์ ํธ์ถ์ด๋ค.
const circle3 = Circle(15);
// ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ Circle์๋ ๋ฐํ๋ฌธ์ด ์์ผ๋ฏ๋ก ์๋ฌต์ ์ผ๋ก undefined๋ฅผ ๋ฐํํ๋ค.
console.log(circle3); // undefined
// ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ Circle ๋ด๋ถ์ this๋ ์ ์ญ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log(radius); // 15
apply
call
bind
๋ฉ์๋๋Function.prototype
์ ๋ฉ์๋. ์ฆ, ์ด๋ค ๋ฉ์๋๋ ๋ชจ๋ ํจ์๊ฐ ์์๋ฐ์ ์ฌ์ฉ ํ ์ ์๋ค.
โ Function.prototype.apply
Function.prototype.call
๋ฉ์๋๋ this
๋ก ์ฌ์ฉํ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๊ณ ํจ์๋ฅผ ํธ์ถ
/**
* ์ฃผ์ด์ง this ๋ฐ์ธ๋ฉ๊ณผ ์ธ์ ๋ฆฌ์คํธ ๋ฐฐ์ด์ ์ฌ์ฉํ์ฌ ํจ์๋ฅผ ํธ์ถํ๋ค.
* @param thisArg - this๋ก ์ฌ์ฉํ ๊ฐ์ฒด
* @param argArray - ํจ์์๊ฒ ์ ๋ฌํ ์ธ์ ๋ฆฌ์คํธ์ ๋ฐฐ์ด ๋๋ ์ ์ฌ ๋ฐฐ์ด ๊ฐ์ฒด
* @returns ํธ์ถ๋ ํจ์์ ๋ฐํ๊ฐ
*/
Function.prototype.apply(thisArg[, argsArray])
/**
* ์ฃผ์ด์ง this ๋ฐ์ธ๋ฉ๊ณผ ,๋ก ๊ตฌ๋ถ๋ ์ธ์ ๋ฆฌ์คํธ๋ฅผ ์ฌ์ฉํ์ฌ ํจ์๋ฅผ ํธ์ถํ๋ค.
* @param thisArg - this๋ก ์ฌ์ฉํ ๊ฐ์ฒด
* @param arg1, agr2, ... - ํจ์์๊ฒ ์ ๋ฌํ ์ธ์ ๋ฆฌ์คํธ
* @returns ํธ์ถ๋ ํจ์์ ๋ฐํ๊ฐ
*/
Function.prototype.call(thisArg[, arg1[, arg2[, ...]]])
function getThisBinding() {
return this;
}
// this๋ก ์ฌ์ฉํ ๊ฐ์ฒด
const thisArg = { a: 1 };
console.log(getThisBinding()); // window
// getThisBinding ํจ์๋ฅผ ํธ์ถํ๋ฉด์ ์ธ์๋ก ์ ๋ฌ๋ ๊ฐ์ฒด๋ฅผ getThisBinding ํจ์์ this์ ๋ฐ์ธ๋ฉํ๋ค.
console.log(getThisBinding.apply(thisArg)); // {a: 1}
console.log(getThisBinding.call(thisArg)); // {a: 1}
apply
์call
๋ฉ์๋์ ๋ณธ์ง์ ์ธ ๊ธฐ๋ฅ์ ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒapply
call
๋ฉ์๋๋ ํจ์๋ฅผ ํธ์ถํ๋ฉด์ ์ฒซ ๋ฒ์ฌ ์ธ์๋ก ์ ๋ฌํ ํน์ ๊ฐ์ฒด๋ฅผ ํธ์ถํ ํจ์์ this์ ๋ฐ์ธ๋ฉํ๋ค.
apply
์call
๋ฉ์๋๋ ํธ์ถํ ํจ์์ ์ธ์๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ์๋ง ๋ค๋ฅผ ๋ฟ ๋์ผํ๊ฒ ๋์. ์ ์์ ๋ ํธ์ถํ ํจ์, ์ฆgetThisBinding ํจ์
์ ์ธ์๋ฅผ ์ ๋ฌํ์ง ์๋๋ค.apply
์call
๋ฉ์๋๋ฅผ ํตํดgetThisBinding
ํจ์๋ฅผ ํธ์ถํ๋ฉด์ ์ธ์๋ฅผ ์ ๋ฌํด๋ณด์.
function getThisBinding() {
console.log(arguments);
return this;
}
// this๋ก ์ฌ์ฉํ ๊ฐ์ฒด
const thisArg = { a:1 };
// getThisBinding ํจ์๋ฅผ ํธ์ถํ๋ฉด์ ์ธ์๋ก ์ ๋ฌํ ๊ฐ์ฒด๋ฅผ getThisBinding ํจ์์ this๋ฅผ ๋ฐ์ธ๋ฉํ๋ค.
// apply ๋ฉ์๋๋ ํธ์ถํ ํจ์์ ์ธ์๋ฅผ ๋ฐฐ์ด๋ก ๋ฌถ์ด ์ ๋ฌํ๋ค.
console.log(getThisBinding.apply(thisArg, [1, 2, 3]));
// call ๋ฉ์๋๋ ํธ์ถํ ํจ์์ ์ธ์๋ฅผ ์๋ฏธํ๋ก ๊ตฌ๋ถํ ๋ฆฌ์คํธ ํ์์ผ๋ก ์ ๋ฌํ๋ค.
console.log(getThisBinding.call(thisArg, 1, 2, 3));
apply
๋ฉ์๋๋ ํธ์ถํ ํจ์์ ์ธ์๋ฅผ ๋ฐฐ์ด๋ก ๋ฌถ์ด ์ ๋ฌ.call
๋ฉ์๋๋ ํธ์ถํ ํจ์์ ์ธ์๋ฅผ ์ผํ๋ก ๊ตฌ๋ถํ ๋ฆฌ์คํธ ํ์์ผ๋ก ์ ๋ฌ.apply
call
๋ฉ์๋ ํธ์ถํ ํจ์์ ์ธ์๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ์๋ง ๋ค๋ฅผ ๋ฟthis
๋ก ์ฌ์ฉํ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ฉด์ ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒ์ ๋์ผ.
๐ก apply
call
๋ฉ์๋์ ๋ํ์ ์ธ ์ฉ๋
apply
call
๋ฉ์๋์ ๋ํ์ ์ธ ์ฉ๋๋arguments
๊ฐ์ฒด์ ๊ฐ์์ ์ฌ ๋ฐฐ์ด ๊ฐ์ฒด
์ ๋ฐฐ์ด ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ค.
function convertArgsToArray() {
console.log(arguments);
// arguments ๊ฐ์ฒด๋ฅผ ๋ฐฐ์ด๋ก ๋ณํ
// Array.prototype.slice๋ฅผ ์ธ์ ์์ด ํธ์ถํ๋ฉด ๋ฐฐ์ด์ ๋ณต์ฌ๋ณธ์ ์์ฑํ๋ค.
const arr = Array.prototype.slice.call(arguments);
// const arr = Array.prototype.slice.apply(arguments);
console.log(arr);
return arr;
}
convertArgsToArray(1,2,3); // [1, 2, 3]
โ Function.prototype.bind
๋ฉ์๋๋apply
์ call
๋ฉ์๋์ ๋ฌ๋ฆฌ ํจ์๋ฅผ ํธ์ถํ์ง ์๋๋ค.
์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌํ ๊ฐ์ผ๋ก
this
๋ฐ์ธ๋ฉ ๊ต์ฒด๋ ํจ์๋ฅผ ์๋กญ๊ฒ ์์ฑํด ๋ฐํํ๋ค.
function getThisBinding() {
return this;
}
// this๋ก ์ฌ์ฉํ ๊ฐ์ฒด
const thisArg = { a: 1 };
// bind ๋ฉ์๋๋ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌํ thisArg๋ก this ๋ฐ์ธ๋ฉ์ด ๊ต์ฒด๋
// getThisBinding ํจ์๋ฅผ ์๋กญ๊ฒ ์์ฑํด ๋ฐํํ๋ค.
console.log(getThisBinding.bind(thisArg)); // getThisBinding
// bind ๋ฉ์๋๋ ํจ์๋ฅผ ํธ์ถํ์ง๋ ์์ผ๋ฏ๋ก ๋ช
์์ ์ผ๋ก ํธ์ถํด์ผ ํ๋ค.
console.log(getThisBinding.bind(thisArg)()); // {a: 1}
bind
๋ฉ์๋๋ ๋ฉ์๋์this
์ ๋ฉ์๋ ๋ด๋ถ์ ์ค์ฒฉ ํจ์ ๋๋ ์ฝ๋ฐฑ ํจ์์this
๊ฐ ๋ถ์ผ์นํ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ ์ฉํ๊ฒ ์ฌ์ฉ๋๋ค.
const person = {
name : 'Noh',
foo(callback) {
// โ
setTimeout(callback, 100);
}
};
person.foo(function () {
console.log(`Hi my name is ${this.name}`); // โก Hi! my name is .
// ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ ์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์ this.name์ ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ window.name๊ณผ ๊ฐ๋ค.
// ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ window.name์ ๋ธ๋ผ์ฐ์ ์ฐฝ์ ์ด๋ฆ์ ๋ํ๋ด๋ ๋นํธ์ธ ํ๋กํผํฐ์ด๋ฉฐ ๊ธฐ๋ณธ๊ฐ์ ''์ด๋ค.
// Node.js ํ๊ฒฝ์์ this.name์ undefined๋ค.
person.foo ๋ฉ์๋๊ฐ ํธ์ถ๋๋ ์์ ์ธ โ ์์
this
๋foo
๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด ์ฆ, person ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๊ณ person.foo ์ฝ๋ฐฑํจ์๊ฐ ์ผ๋ฐ ํจ์๋ก์ ํธ์ถ๋ โก์ ์์ ์์this
๋ ์ ์ญ๊ฐ์ฒดwindow
๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
person.foo์ ์ฝ๋ฐฑ ํจ์๋ ์ธ๋ถ ํจ์ person.foo๋ฅผ ๋๋ ํฌํผ ํจ์(๋ณด์กฐ ํจ์) ์ญํ ์ ํ๊ธฐ ๋๋ฌธ์ ์ธ๋ถ ํจ์ person.foo ๋ด๋ถ์ this์ ์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์ this๊ฐ ๋ค๋ฅด๋ฉด ๋ฌธ์ ๊ฐ ์๊น. ์ด๋bind
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌthis
๋ฅผ ์ผ์น์ํฌ ์ ์๋ค.
const person = {
name : 'Noh',
foo(callback) {
// bind ๋ฉ์๋๋ก callback ํจ์ ๋ด๋ถ์ this ๋ฐ์ธ๋ฉ์ ์ ๋ฌ
setTimeout(callback.bind(this), 100);
}
};
person.foo(function () {
console.log(`Hi my name is ${this.nae}.`); // Hi! my name is Noh
});
ํจ์ ํธ์ถ ๋ฐฉ์ | this ๋ฐ์ธ๋ฉ |
---|---|
์ผ๋ฐ ํจ์ ํธ์ถ | ์ ์ญ ๊ฐ์ฒด |
๋ฉ์๋ ํธ์ถ | ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด |
์์ฑ์ ํจ์ ํธ์ถ | ์์ฑ์ ํจ์๊ฐ (๋ฏธ๋์) ์์ฑํ ์ธ์คํด์ค |
Function.prototype.apply/call/bind ๋ฉ์๋์ ์ํ ๊ฐ์ ํธ์ถ | Function.prototype.applu/call/bind ๋ฉ์๋์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌํ ๊ฐ์ฒด |