var example = function(a,b,c){
return a + b + c;
};
example(1,2,3);
example.call(null,1,2,3);
example.apply(null,[1,2,3]);
함수를 호출하는 세 가지 예시이다.
함수 뒤에 ()를 붙이는 것, call, apply의 방법이 있다.
call은 보통 함수와 똑같이 인자를 넣고, apply는 배열의 형태로 인자를 넣는다. call과 apply가 공통적으로 가진 null은 this를 대체하는 부분이다.
var obj = {
str: 'zero',
f1: function(){
alert(this.str);
}
};
var obj2 = {
str: 'test'
}
obj.f1(); // zero
obj.f1.call(obj2); // test
마지막 줄에서 this가 가리키는 객체가 obj2로 변했다. f1은 obj에 속한 메서드이지만 call의 context parameter에 obj2를 넣어 this가 가리키는 객체를 변경했다. apply 또한 같은 역할을 한다.
var obj = {
str: 'zero',
f1: function(){
alert(this.str);
}
};
var obj2 = {
str: 'test'
};
var testFunction = obj.f1.bind(obj2);
testFunction(); // test
bind를 통해서 f1의 this가 obj2로 바뀌었다. call이나 apply와 비슷하지만 함수만 반환하는 형태이다.
크롬 개발자 도구의 콘솔에서 console.log(this)를 쳐보면 window 객체가 나온다.
기본적으로 this는 javascript 실행 환경의 전역 객체를 나타낸다.
함수 안에서 쓴 this는 2가지 동작을 한다. use strict의 옵션에 따라서 방식이 나뉘는데, 먼저 strict mode가 아닌 경우에서는 아래와 같다.
var num = 0;
function test(){
this.num = 100;
num++;
console.log(num); // 101
console.log(this.num); // 101
}
위의 예시에서 this는 window 객체를 가리킨다.
strict mode가 적용된 환경에서는
"use strict"
function test(){
return this;
}
console.log(test()); // undefined
strict mode에서는 함수 내의 this에 디폴트 바인딩이 없기 때문에 undefined가 된다.
메서드 호출 시에는 메서드 내부 코드에서 사용된 this는 해당 메서드를 호출한 객체로 바인딩된다.
var obj = {
name: 'test',
f1: function(){
console.log(this.name);
}
}
obj.f1(); // test
생성자 함수가 생성하는 객체로 this가 바인딩된다.
function Person(name){
this.name = name;
}
let kim = new Person('kim');
console.log(kim.name) // kim
하지만 new 키워드를 사용하지 않으면 일반 함수 호출이기 때문에 this가 window로 바인딩된다.
function Person(name){
this.name = name;
}
let kim = Person('kim');
console.log(kim.name) // undefined
console.log(window.name) // kim
function test(){
console.log(this);
}
test(); // window
let obj = {
x: 123
}
test.call(obj); // {x:123}
test.apply(obj); // {x:123}
let test2 = test.bind(obj);
test2() // {x:123}
화살표 함수는 전역 컨텍스트에서 실행되더라도 this를 새로 정의하지 않고, 바로 바깥 함수나 클래스의 this를 사용한다.
var Person = function (name, age) {
this.name = name;
this.age = age;
this.say = function () {
console.log(this); // Person {name: "Nana", age: 28}
setTimeout(function () {
console.log(this); // Window
console.log(this.name + ' is ' + this.age + ' years old');
}, 100);
};
};
var me = new Person('Nana', 28);
me.say(); //global is undefined years old
위의 코드에선 this가 전역 객체를 가리키고 있어 의도와는 다른 결과가 나왔다.
var Person = function (name, age) {
this.name = name;
this.age = age;
this.say = function () {
console.log(this); // Person {name: "Nana", age: 28}
setTimeout(() => {
console.log(this); // Person {name: "Nana", age: 28}
console.log(this.name + ' is ' + this.age + ' years old');
}, 100);
};
};
var me = new Person('Nana', 28); //Nana is 28 years old
화살표 함수를 사용해 원하는 결과를 얻었다.