- ๊ฐ์ฒด๋ ์ํ๋ฅผ ๋ํ๋ด๋ ํ๋กํผํฐ์ ๋์์ ๋ํ๋ด๋ ๋ฉ์๋๋ฅผ ํ๋์ ๋ ผ๋ฆฌ์ ์ธ ๋จ์๋ก ๋ฌถ์ ๋ณตํฉ์ ์ธ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
- ๋์์ ๋ํ๋ด๋ ๋ฉ์๋๋ ํ๋กํผํฐ๋ฅผ ์ฐธ์กฐํ๊ณ ๋ณ๊ฒฝ ๊ฐ๋ฅํจ. ๋ฉ์๋๊ฐ ์์ ์ด ์ํ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ฅผ ์ฐธ์กฐํ ๋ ์์ ์ด ์ํ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ์๋ณ์๋ฅผ ์ฐธ์กฐ ๊ฐ๋ฅํด์ผํ๋ค.
const circle = {
// โ
ํ๋กํผํฐ: ๊ฐ์ฒด ๊ณ ์ ์ ์ํ ๋ฐ์ดํฐ
radius: 5,
// โ
๋ฉ์๋: ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฐธ์กฐํ๊ณ ์กฐ์ํ๋ ๋์
getDiameter() {
// this๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
return 2 * this.radius;
},
};
console.log(circle.getDiameter()); // 10๐จ ์๊ธฐ ์์ ์ด ์ํ ๊ฐ์ฒด๋ฅผ ์ฌ๊ท์ ์ผ๋ก ์ฐธ์กฐํ๋ ๋ฐฉ์์ ์ผ๋ฐ์ ์ด์ง ์๋ค.
๐ ๋์ , ์์ฑ์ ํจ์ ๋ฐฉ์์ผ๋ก ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ ์ฐจ์ฉ
- this๋ ์์ ์ด ์ํ ๊ฐ์ฒด ๋๋ ์์ ์ด ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค๋ ์๊ธฐ ์ฐธ์กฐ ๋ณ์๋ก ํ๋กํผํฐ๋ ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ ์ ์๋ค.
- this๋ ์์ง์ ์ํด ์๋ฌต์ ์ผ๋ก ์์ฑ๋๊ณ ์ด๋์๋ ์ฐธ์กฐ ๊ฐ๋ฅํ๋ค. ํจ์ ํธ์ถ ์ arguments ๊ฐ์ฒด์ this๊ฐ ์๋ฌต์ ์ผ๋ก ํจ์ ๋ด๋ถ์ ์ ๋ฌ๋์ด, ํจ์ ๋ด๋ถ์์๋ arguments ๊ฐ์ฒด๋ฅผ ์ง์ญ๋ณ์์ฒ๋ผ ์ฐ๋ ๊ฒ๊ณผ ๊ฐ์ด this๋ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค. ๐ this ๋ฐ์ธ๋ฉ(this๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ)์ ํจ์ ํธ์ถ ๋ฐฉ์์ ์ํด ๋์ ์ผ๋ก ๊ฒฐ์ ๋จ.
- strict mode ์ ์ฉ์, ์ผ๋ฐ ํจ์ ๋ด๋ถ์ this์๋ undefined๊ฐ ๋ฐ์ธ๋ฉ๋๋ค. => this๋ ๊ฐ์ฒด์ ๋ฉ์๋ ๋ด๋ถ ๋๋ ์์ฑ์ ํจ์ ๋ด๋ถ์์๋ง ์๋ฏธ๊ฐ ์์ผ๋ฏ๋ก..
// ์์ฑ์ ํจ์
function Circle(radius) {
// this๋ ์์ฑ์ ํจ์๊ฐ ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
this.radius = radius;
}
Circle.prototype.getDiameter = function () {
// this๋ ์์ฑ์ ํจ์๊ฐ ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
return 2 * this.radius;
};
// ์ธ์คํด์ค ์์ฑ
const circle = new Circle(5);
console.log(circle.getDiameter()); // 10// this๋ ์ด๋์๋ ์ง ์ฐธ์กฐ ๊ฐ๋ฅํ๋ค.
// ์ ์ญ์์ this๋ ์ ์ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log(this); // window
function square(number) {
// ์ผ๋ฐ ํจ์ ๋ด๋ถ์์ this๋ ์ ์ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log(this); // window
return number * number;
}
square(2);
const person = {
name: "Lee",
getName() {
// ๋ฉ์๋ ๋ด๋ถ์์ this๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log(this); // {name: "Lee", getName: ฦ}
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์๋ ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
-
this๋ ์๊ธฐ ์ฐธ์กฐ ๋ณ์์ด๋ฏ๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ์ง ์๋ ์ผ๋ฐ ํจ์์์๋ ์๋ฏธ๊ฐ ์๋ค. ์๋ฅผ ๋ค์ด,
strict mode์์๋undefined๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
function foo() {
"use strict";
console.log("foo's this: ", this); // undefined
function bar() {
console.log("bar's this: ", this); // undefined
}
bar();
}
foo();- ์ฝ๋ฐฑ ํจ์๊ฐ ์ผ๋ฐ ํจ์๋ก ํธ์ถ ์, ์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์ this์๋ ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ๋๋ค. ์ด๋ ํ ํจ์๋ผ๋ ์ผ๋ฐ ํจ์๋ก ํธ์ถ ์, this์ ์ ์ญ ๊ฐ์ฒด(window)๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
// var ํค์๋๋ก ์ ์ธํ ์ ์ญ ๋ณ์ value๋ ์ ์ญ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ค.
var value = 1;
// const ํค์๋๋ก ์ ์ธํ ์ ์ญ ๋ณ์ value๋ ์ ์ญ ๊ฐ์ฒด์ ํ๋กํผํฐ๊ฐ ์๋๋ค.
// const value = 1;
const obj = {
value: 100,
foo() {
console.log("foo's this: ", this); // {value: 100, foo: ฦ}
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
}
// ๋ฉ์๋ ๋ด์์ ์ ์ํ ์ค์ฒฉ ํจ์๋ ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋๋ฉด ์ค์ฒฉ ํจ์ ๋ด๋ถ์ this์๋ ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
bar();
},
};
obj.foo();- ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ ๋ชจ๋ ํจ์(์ค์ฒฉ ํจ์, ์ฝ๋ฐฑ ํจ์ ํฌํจ) ๋ด๋ถ์ this์๋ ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
โ ๏ธ ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ ๋, ๋ฉ์๋ ๋ด ์ค์ฒฉ ํจ์ ๋๋ ์ฝ๋ฐฑ ํจ์์ this๊ฐ ์ ์ญ ๊ฐ์ฒด๋ฅผ ๋ฐ์ธ๋ฉํ ๋ ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์์. ์ธ๋ถ ํจ์์ธ ๋ฉ์๋์ ์ค์ฒฉ ํจ์ ๋๋ ์ฝ๋ฐฑ ํจ์์ this๊ฐ ์ผ์นํ์ง ์์ ๋, ์ค์ฒฉ ํจ์ ๋๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ํฌํผ ํจ์๋ก ๋์ํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ค ์๊ฐ ์์.
var value = 1;
const obj = {
value: 100,
foo() {
console.log("foo's this: ", this); // {value: 100, foo: ฦ}
// ์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์ this์๋ ์ ์ญ ๊ฐ์ฒด๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
setTimeout(function () {
console.log("callback's this: ", this); // window
console.log("callback's this.value: ", this.value); // 1
}, 100);
},
};
obj.foo();
setTime()
- ๋๋ฒ์จฐ ์ธ์๋ก ์ ๋ฌํ ์๊ฐ(ms)๋งํผ ๋๊ธฐํ ๋ค์, ์ฒซ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌํ ์ฝ๋ฐฑ ํจ์๋ฅผ ํธ์ถํ๋ ํ์ด๋จธ ํจ์
- this๊ฐ ์ผ์นํ์ง ์๋ ๋ฌธ์ ์์
const obj = {
name: "Alice",
showName: function () {
console.log("๋ฉ์๋ ๋ด๋ถ this.name:", this.name); // "Alice"
function innerFunction() {
console.log("์ค์ฒฉ ํจ์ ๋ด๋ถ this.name:", this.name); // undefined (strict mode) ๋๋ window.name
}
innerFunction(); // ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋๋ฏ๋ก `this`๊ฐ ์ ์ญ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํด
},
};
obj.showName();- ์ฝ๋ฐฑ ํจ์์์ this ๋ฌธ์
const obj = {
name: "Alice",
showName: function () {
setTimeout(function () {
console.log("setTimeout ๋ด๋ถ this.name:", this.name); // undefined
}, 1000);
},
};
obj.showName();๐ ํด๊ฒฐ์ฑ
1. self(or that) ๋ณ์ ์ฌ์ฉ
- self์ this(ํ์ฌ ๊ฐ์ฒด)๋ฅผ ์ ์ฅํ๊ณ ์ค์ฒฉ ํจ์์์ self๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด ์์ฑ์ ์ ๊ทผ
const obj = {
name: "Alice",
showName: function () {
const self = this; // `this`๋ฅผ ์ ์ฅ
function innerFunction() {
console.log("์ค์ฒฉ ํจ์ ๋ด๋ถ this.name:", self.name); // "Alice"
}
innerFunction();
},
};
obj.showName();ํด๊ฒฐ์ฑ
2. bind() ๋ฉ์๋ ์ฌ์ฉ
const obj = {
name: "Alice",
showName: function () {
function innerFunction() {
console.log("์ค์ฒฉ ํจ์ ๋ด๋ถ this.name:", this.name); // "Alice"
}
const boundInnerFunction = innerFunction.bind(this); // `this`๋ฅผ obj๋ก ๊ณ ์
boundInnerFunction();
},
};
obj.showName();ํด๊ฒฐ์ฑ 3. ํ์ดํ ํจ์ ์ฌ์ฉ
- ํ์ดํ ํจ์๋ this๋ฅผ ์์ ์ค์ฝํ์ this๋ฅผ ๊ทธ๋๋ก ๊ณ์นํ๋ฏ๋ก, ์ค์ฒฉ ํจ์์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
const obj = {
name: "Alice",
showName: function () {
const innerFunction = () => {
console.log("์ค์ฒฉ ํจ์ ๋ด๋ถ this.name:", this.name); // "Alice"
};
innerFunction();
},
};
obj.showName();ํด๊ฒฐ์ฑ
4. call() ๋๋ apply() ์ฌ์ฉ
- this๋ฅผ ๋ช ์์ ์ผ๋ก ์ง์ ํ์ฌ ํธ์ถ
const obj = {
name: "Alice",
showName: function () {
function innerFunction() {
console.log("์ค์ฒฉ ํจ์ ๋ด๋ถ this.name:", this.name); // "Alice"
}
innerFunction.call(this); // `this`๋ฅผ obj๋ก ์ค์
},
};
obj.showName();- ๋ฉ์๋ ๋ด๋ถ์ this๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด(๋ฉ์๋ ์ด๋ฆ ์์ ๋ง์นจํ(.) ์ฐ์ฐ์ ์์ ๊ธฐ์ ํ ๊ฐ์ฒด)๊ฐ ๋ฐ์ธ๋ฉ๋๋ค. ๋ฉ์๋ ๋ด๋ถ์ this๋ ๋ฉ์๋๋ฅผ ์์ ํ ๊ฐ์ฒด๊ฐ ์๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉ๋๋ค๋ ๊ฒ์ด๋ค.
const person = {
name: "Lee",
getName() {
// ๋ฉ์๋ ๋ด๋ถ์ this๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉ๋๋ค.
return this.name;
},
};
// ๋ฉ์๋ getName์ ํธ์ถํ ๊ฐ์ฒด๋ person์ด๋ค.
console.log(person.getName()); // Lee- getName ํ๋กํผํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ํจ์์ธ getName ๋ฉ์๋๋ ๋ค๋ฅธ ๊ฐ์ฒด์ ํ๋กํผํฐ์ ํ ๋นํ๋ ๊ฒ์ผ๋ก ๋ค๋ฅธ ๊ฐ์ฒด์ ๋ฉ์๋๊ฐ ๋ ์ ์์. ๋ํ, ์ผ๋ฐ ํจ์์ ํ ๋นํ์ฌ ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ ์๋ ์์.
- ๋ฉ์๋ ๋ด๋ถ์ this๋ ํ๋กํผํฐ๋ก ๋ฉ์๋๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋ ๊ฐ์ฒด์ ๊ด๊ณ๊ฐ ์๊ณ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉ๋จ.
const anotherPerson = {
name: "Kim",
};
// getName ๋ฉ์๋๋ฅผ anotherPerson ๊ฐ์ฒด์ ๋ฉ์๋๋ก ํ ๋น
anotherPerson.getName = person.getName;
// getName ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฐ์ฒด๋ anotherPerson์ด๋ค.
console.log(anotherPerson.getName()); // Kim
// getName ๋ฉ์๋๋ฅผ ๋ณ์์ ํ ๋น
const getName = person.getName;
// getName ๋ฉ์๋๋ฅผ ์ผ๋ฐ ํจ์๋ก ํธ์ถ
console.log(getName()); // ''
// ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ getName ํจ์ ๋ด๋ถ์ this.name์ ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ window.name๊ณผ ๊ฐ๋ค.
// ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ window.name์ ๋ธ๋ผ์ฐ์ ์ฐฝ์ ์ด๋ฆ์ ๋ํ๋ด๋ ๋นํธ์ธ ํ๋กํผํฐ์ด๋ฉฐ ๊ธฐ๋ณธ๊ฐ์ ''์ด๋ค.
// Node.js ํ๊ฒฝ์์ this.name์ undefined๋ค.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- ์์ฑ์ ํจ์ ๋ด๋ถ์ 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๋ฉ์๋ ํจ์๋?
- ๋ฉ์๋ ํจ์๋ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ก ์ ์๋ ํจ์๋ก, ํด๋น ๊ฐ์ฒด์ ์์ฑ์ ์ฝ๊ฑฐ๋ ์์ ํ๋ ๊ธฐ๋ฅ์ ์ํํฉ๋๋ค.
๐ ํน์ง
- ๊ฐ์ฒด์ ์์ฑ๊ณผ ์ฐ๊ด๋ ๋์์ ์ํํ๋ ํจ์
- ๊ฐ์ฒด์ ๋ฉ์๋๋ก ํธ์ถ๋ ๋, this๋ ํด๋น ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํด.
- new ํค์๋ ์์ด ํธ์ถ
์์ฑ์ ํจ์๋?
- ์์ฑ์ ํจ์๋ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ํ ํจ์๋ก, new ํค์๋์ ํจ๊ป ํธ์ถ๋ฉ๋๋ค.
๐ ํน์ง
- ์๋ก์ด ๊ฐ์ฒด(์ธ์คํด์ค)๋ฅผ ์์ฑํ๋ ์ฉ๋
- new ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ํธ์ถํ ๋, this๊ฐ ์๋กญ๊ฒ ์์ฑ๋ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํด.
- ์์ฑ์ ํจ์์ ์ด๋ฆ์ ๋๋ฌธ์๋ก ์์ํ๋ ๊ฒ์ด ๊ด๋ก (PascalCase)
apply, call, bind๋ฉ์๋๋Function.prototype.apply์ ๋ฉ์๋๋ก ๋ชจ๋ ํจ์๊ฐ ์์๋ฐ์ ์ฌ์ฉ ๊ฐ๋ฅ- apply, call ๋ฉ์๋๋ this๋ก ์ฌ์ฉํ ๊ฐ์ฒด์ ์ธ์ ๋ฆฌ์คํธ๋ฅผ ์ธ์๋ก ์ ๋ฌ ๋ฐ์ ํจ์๋ฅผ ํธ์ถํ๋ค.
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 ๋ฉ์๋๋ ํธ์ถํ ํจ์์ ์ธ์๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ์๋ง ๋ค๋ฅผ ๋ฟ ๋์ผํ๊ฒ ๋์ํ๋ค.
์ฐจ์ด์ :
- apply๋ ์ธ์๋ฅผ ๋ฐฐ์ด๋ก ๋ฌถ์ด ์ ๋ฌํ๋ค. call์ ์ผํ๋ก ๊ตฌ๋ถํ ๋ฆฌ์คํธ ํ์์ผ๋ก ์ ๋ฌํ๋ค.
function getThisBinding() {
console.log(arguments);
return this;
}
// this๋ก ์ฌ์ฉํ ๊ฐ์ฒด
const thisArg = { a: 1 };
// getThisBinding ํจ์๋ฅผ ํธ์ถํ๋ฉด์ ์ธ์๋ก ์ ๋ฌํ ๊ฐ์ฒด๋ฅผ getThisBinding ํจ์์ this์ ๋ฐ์ธ๋ฉํ๋ค.
// apply ๋ฉ์๋๋ ํธ์ถํ ํจ์์ ์ธ์๋ฅผ ๋ฐฐ์ด๋ก ๋ฌถ์ด ์ ๋ฌํ๋ค.
console.log(getThisBinding.apply(thisArg, [1, 2, 3]));
// Arguments(3) [1, 2, 3, callee: ฦ, Symbol(Symbol.iterator): ฦ]
// {a: 1}
// call ๋ฉ์๋๋ ํธ์ถํ ํจ์์ ์ธ์๋ฅผ ์ผํ๋ก ๊ตฌ๋ถํ ๋ฆฌ์คํธ ํ์์ผ๋ก ์ ๋ฌํ๋ค.
console.log(getThisBinding.call(thisArg, 1, 2, 3));
// Arguments(3) [1, 2, 3, callee: ฦ, Symbol(Symbol.iterator): ฦ]
// {a: 1}- apply์ call ๋ฉ์๋์ ๋ํ์ ์ธ ์ฉ๋๋ arguments์ ๊ฐ์ ์ ์ฌ ๋ฐฐ์ด ๊ฐ์ฒด์ ๋ฐฐ์ด ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ: arguments ๊ฐ์ฒด๋ ๋ฐฐ์ด์ด ์๋๋ฏ๋ก Array.prototype.slice์ ๊ฐ์ ๋ฐฐ์ด์ ๋ฉ์๋๋ฅผ ์ฌ์ฉ ๋ชปํ๋ apply, call ๋ฉ์๋์์๋ ๊ฐ๋ฅํ๋ค.
๐ bind ๋ฉ์๋๋ ๋ฉ์๋์ this์ ๋ฉ์๋ ๋ด๋ถ์ ์ค์ฒฉ ํจ์ ๋๋ ์ฝ๋ฐฑ ํจ์์ 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}- person.foo์ ์ฝ๋ฐฑ ํจ์๊ฐ ํธ์ถ๋๊ธฐ ์ด์ (โ ์์ )์ this๊ฐ person ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํจ๋ค. ๊ทธ๋ฌ๋. person.foo์ ์ฝ๋ฐฑ ํจ์๊ฐ ์ผ๋ฐ ํจ์๋ก์ ํธ์ถ๋ โก ์์ ์์ this๋ ์ ์ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
const person = {
name: "Lee",
foo(callback) {
// โ this => person
setTimeout(callback, 100);
},
};
person.foo(function () {
console.log(`Hi! my name is ${this.name}.`); // โก Hi! my name is undefined.
// ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ ์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์ this.name์ ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ window.name๊ณผ ๊ฐ๋ค.
// ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ window.name์ ๋ธ๋ผ์ฐ์ ์ฐฝ์ ์ด๋ฆ์ ๋ํ๋ด๋ ๋นํธ์ธ ํ๋กํผํฐ์ด๋ฉฐ ๊ธฐ๋ณธ๊ฐ์ ''์ด๋ค.
// Node.js ํ๊ฒฝ์์ this.name์ undefined๋ค.
});ํด๊ฒฐํ๋ ์ฝ๋:
- person.foo์ ์ฝ๋ฐฑํจ์๋ ์ธ๋ถ ํจ์ person.foo์ ํฌํผ ํจ์์ ์ญํ ์ด๋ฏ๋ก, this๊ฐ ์์ดํ๋ฉด ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.(์ ์์ ์ฒ๋ผ)
๋ฐ๋ผ์, ์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์ this๋ฅผ ์ธ๋ถ ํจ์ ๋ด๋ถ์ this์ ์ผ์น์์ผ์ผํ๋ค.
=>
bind๋ฉ์๋ ์ฌ์ฉ
const person = {
name: "Lee",
foo(callback) {
// bind ๋ฉ์๋๋ก callback ํจ์ ๋ด๋ถ์ this ๋ฐ์ธ๋ฉ์ ์ ๋ฌ
setTimeout(callback.bind(this), 100);
},
};
person.foo(function () {
console.log(`Hi! my name is ${this.name}.`); // Hi! my name is Lee.
});

