this의 값은 함수를 호출한 방법이 결정합니다.
함수를 호출하는 방법에는 어떻게 있을까요?
console.log(this); // window {...}
this.a = 'A';
console.log(window.a) // 'A'
this.hello = 'world';
console.log(window.hello) // 'world'
cat = "Meow";
console.log(window.cat) // 'Meow'
console.log(cat) // 'Meow'
this는 기본적으로 전역 객체인 window에 바인딩됩니다.
function foo() {
return this;
}
console.log(foo()); // window {...}
dog = "bow";
function bar () {
return this.dog;
}
console.log(bar()); // bow;
함수안에 있는 this가 window객체를 가르키고 있다는 걸 확인할 수 있습니다.
call, apply를 이용해서 this를 window가 아닌 다른 객체의 속성 값을 사용할 수 있게 할 수 있습니다.
world = 'world'
function hello () {
return this.world
}
console.log(hello()); // 'world'
const hello2 = {
world: 'world~!'
}
console.log(hello.call(hello2)) // 'world~!';
console.log(hello.apply(hello2)) // 'world~!';
처음의 매개변수가 this를 어디 객체에 속하게 할 것인지 결정합니다. 뒤에 오는 것들은 실행함수의 매개변수로 들어갈 값들입니다. call과 apply의 차이점이 있습니다. call은 낱개로 값을 전달하고 apply는 배열을 이용해서 매개변수에 전달합니다.
// call somthing.call(thisArgu, parameter1, parmeter2, ...)
// apply somthing.apply(thisArgu, [parameter1, parmeter2, ...]);
function sum (a, b) {
return this.one + this.two + a + b;
}
const number = {
one: 1,
two: 2,
}
let callResult = sum.call(number, 5, 15);
console.log(callResult) // 23
let applyResult = sum.apply(number, [3, 4]);
console.log(applyResult) // 10
객체에서 생성한 함수, 메소드에 내부에 있는 this는 그 객체에 할당됩니다.
const foo = {
a: 'A',
objFunc: function () {
return this;
}
}
let result = foo.objFunc();
console.log(result); // {a: 'A', objFunc: ƒ}
const bar = {
num1: 5,
num2: 30,
sum: function () {
return this.num1 + this.num2
}
}
result = bar.sum();
console.log(result); // 35
메소드 호출도 call과 apply를 이용해서 다른 객체의 속성을 이용할 수 있습니다.
const foo = {
character: 'a',
output: function () {
return this.character;
}
}
let normal = foo.output();
console.log(normal); // 'a'
const bar = {
character: '가'
}
let callResult = foo.output.call(bar);
console.log(callResult); // '가'
생성자 함수로 생성한 인스턴스는 만들어진 인스턴스가 this로 결정됩니다.
const Basicwizard (wand, magic) {
this.wand = wand;
this.magic = magic;
this.cast = function () {
return `Use ${this.magic} with ${this.wand}`;
}
const fireWizard = new Basicwizard('firewand', 'fireball');
console.log(fireWizard.cast()); // Use fireball with firewand
내부함수와 콜백함수에서의 this는 window를 가르키고 있다. 메소드를 실행 시키면 this는 undefined를 반환합니다.
var foo = {
a: 'Hello World',
b: function () {
console.log(this, 'outer'); // {a: 'Hello world', b: f} outer
function inner () {
console.log(this, 'inner'); // window {...} inner
return this.a;
}
return inner();
}
}
let result = foo.b();
console.log(result) // undefined;
result의 값이 undefined가 아니고 Hello World로 나오게 할려면 어떻게 해야될까요?
외부함수에서 변수 선언, bind, 화살표 함수(arrow function)을 이용하는 방법이 있습니다.
// 외부함수 변수 선언
var foo = {
a: 'Hello World',
b: function () {
var that = this; // 변수 선언
function inner () {
return that.a; // 변수 활용
}
return inner();
}
}
var result = foo.b();
console.log(result); // Hello World
// bind
var foo = {
a: 'Hello World',
b: function () {
function inner () {
return this.a;
}
return inner.bind(this)(); // bind로 this를 결정해주고 함수실행
}
}
var result = foo.b();
console.log(result); // Hello World
bind는 call, apply와 차이점은 call과 apply는 this는 결정는 동시에 실행하고, bind는 객체만 결정해줍니다. 실행은 따로 해야합니다.