들어가기전
자바스크립트의 함수는 호출될 때, 매개변수로 전달되는 인자값 이외에,
arguments 객체와 this를 암묵적으로 전달 받는다.
자바스크립트의 경우 함수 호출 방식에 따라 this에 바인딩 되는 객체가 달라진다.
1. 함수 호출
기본적으로 this는 전역객체에 바인딩된다.
전역함수, 내부함수, 메소드의 내부함수, 콜백함수 모두 전역객체에 바인딩된다.
내부함수는 일반함수, 메소드, 콜백함수 어디에 선언되었든 this는 전역객체를 바인딩한다.
function foo() { // 전역함수
console.log("foo's this: ", this); // window
function bar() { // 내부함수
console.log("bar's this: ", this); // window
}
bar();
}
foo();
var value = 1;
var obj = {
value: 100,
foo: function() {
console.log("foo's this: ", this); // obj
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();
var value = 1;
var obj = {
value: 100,
foo: function() {
setTimeout(function() { // 콜백 함수
console.log("callback's this: ", this); // window
console.log("callback's this.value: ", this.value); // 1
}, 100);
}
};
obj.foo();
2. 메소드 호출
함수가 메소드로써 호출될 때, 메소드 내부의 this는 자신을 호출한 객체를 가리킨다.
var obj1 = {
name: 'Lee',
sayName: function() {
console.log(this.name); // obj1
}
}
var obj2 = {
name: 'Kim'
}
obj2.sayName = obj1.sayName;
obj1.sayName();
obj2.sayName();
3. 생성자 함수 호출
생성자 함수 호출시에는 새로 생성된 인스턴스에 this가 바인딩 된다.
// 생성자 함수
function Person(name) {
this.name = name;
}
var me = new Person('Lee');
console.log(me); //{name: "Lee"}
// new 연산자와 함께 생성자 함수를 호출하지 않으면 생성자 함수로 동작하지 않는다.
var you = Person('Kim');
console.log(you); // undefined
4. apply / call / bind 호출
자바스크립트엔진은 함수 호출 패턴에 따라 this가 어떻게 바인딩될지 결정된다. 이러한 방식은 암묵적인 반면
명시적으로 this를 바인딩하는 방법도 있다.
apply
func.apply(thisArg, [argsArray])
// thisArg: 함수 내부의 this에 바인딩할 객체
// argsArray: 함수에 전달할 argument의 배열
var Person = function (name) {
this.name = name;
};
var foo = {};
// apply 메소드는 생성자함수 Person을 호출한다. 이때 this에 객체 foo를 바인딩한다.
Person.apply(foo, ['name']);
console.log(foo); // { name: 'name' }
함수는 apply 메소드를를 호출하고, apply() 메소드는 this를 특정 객체에 바인딩하고 매개변수 배열을 전달한다.
즉, apply는 기능은 this를 객체에 할당하고, 매개변수를 전달하여 함수를 호출한다.
call
Person.apply(foo, [1, 2, 3]);
Person.call(foo, 1, 2, 3);
call() 메소드의 경우, apply()와 기능은 같지만 두번째 인자를 넘기는 형태가 다르다.
apply는 배열형태로 넘기지만, call은 각각 하나의 인자로 넘긴다.
bind
const module = {
x: 42,
getX: function() {
return this.x;
}
};
const unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// expected output: undefined
const boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// expected output: 42
bind는 함수를 호출하지 않고, this를 바인딩할 객체를 매개변수로 넘겨 준 후에 함수만 반환하는 것.
주로 변수에 할당한 후 사용된다.
5. 화살표 함수
화살표함수는 조금 특별한 케이스다.
위 4가지 상황과 달리, 화살표함수에서는 this가 정적으로 결정된다.
여기서 this는 상위 스코프에 바인딩 된다. 아래 예시를 통해 확인할 수 있다.
var a = 10;
var obj = {
a: 1,
func: () => console.log(this.a)
};
obj.func(); // 10
#Ref
www.zerocho.com/category/JavaScript/post/57433645a48729787807c3fd
'프론트엔드 > Javascript' 카테고리의 다른 글
싱글스레드 자바스크립트 (0) | 2020.10.16 |
---|---|
Class vs Object vs Instance 정리 (0) | 2020.10.10 |
자바스크립트 클로저 (0) | 2020.09.10 |
자바스크립트 호이스팅 (0) | 2020.09.10 |
Javascript - 세미콜론 사용해야 하는가? (0) | 2020.08.28 |