this란?
this의 역할
- 자신이 속한 객체나 인스턴스를 가리키는 자기 참조 변수
- 자신이 속한 객체나 인스턴스의 프로퍼티나 메서드 참조 가능
- 함수를 호출할 때, 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정됨
- 즉, 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 결정된다는 뜻
바인딩?
- 식별자와 값을 연결하는 과정
- this 바인딩은 this와 this가 가리킬 객체를 바인딩 하는 과정
호출
- 기본적으로 this는 전역객체(Global object)에 바인딩됨
- 일반 전역함수는 물론이고 내부함수의 경우도 this는 외부함수가 아닌 전역객체에 바인딩됨
- 예시 코드 1
function a1Fn() {
console.log("a1Fn is...", this);
function a2Fn() {
console.log("a2Fn is...", this);
}
a2Fn();
}
a1Fn();
- 객체의 메서드로 호출될 때 this는 해당 객체를 가리킴
var apple = '독사과';
var home = {
apple: '사과',
eatApple: 'eatAppleFn
}
function eatAppleFn() {
console.log(`백설공주가 ${this.apple}를 먹습니다.`);
}
home.eatApple();
eatAppleFn();
- 객체 메서드로 호출 된 상황의 경우, home의 메서드로써 호출되었기 때문에 여기서 this는 home을 가리키기 때문에 보통 사과를 먹게 됨
- 함수를 직접 호출하는 상황의 경우, eatAppleFn()은 어디에도 바인드 되어 있지 않기 때문에 this는 window를 뜻하고 위에 apple을 독사과로 정의해 두었기 때문에 독사과를 먹게 됨
- 이와 같이 같은 eatAppleFn()을 호출했지만 어떤 방식으로 호출했느냐에 따라 this가 참조하는 객체가 달라짐
- 예시 코드 2
var sejelye = '백설공주';
function mirrorReply() {
console.log(`세상에서 제일 예쁜 사람은 ${this.sejelye}입니다.`);
}
function MagicMirror(name) {
this.sejelye = name;
this.reply = mirrorReply;
}
var newMirror = new MagicMirror('왕비님');
newMirror.reply();
- new 키워드로 MagicMirror의 인스턴스를 생성하였고 name에 해당하는 부분이 '왕비님' 이므로 여기서 newMirror 인스턴스의 mirrorReply 함수 내의 this는 '왕비님'이 됨
call, apply, bind를 이용한 호출
- call, apply, bind를 이용하면 'this'를 원하는 객체에 연결할 수 있음
- 내부함수를 사용하면서도 this가 원하는 객체를 가리키도록 연결해 줄 수 있음
var apple = '독사과';
var home = {
apple: '사과',
eatApple: function() {
eatAppleFn();
},
eatAppleCall: function() {
eatAppleFn.call(this);
},
eatAppleBind: function() {
(eatAppleFn.bind(this))();
}
}
function eatAppleFn() {
console.log(`백설공주가 ${this.apple}를 먹습니다.`);
}
home.eatApple();
home.eatAppleCall();
home.eatAppleBind();
- eatAppleCall과 eatAppleBind 메서드의 this는 home
- 이 this를 call 또는 bind의 인자로 제공하여 eatAppleFn 함수 내에서의 this로 사용할 수 있음.
- call vs bind
- 즉시 호출 vs 캐싱
- call은 함수를 즉시 호출함
- bind는 함수를 호출하지 않고 새로운 함수를 반환, 반환된 함수는 나중에 필요할 때 호출 가능
- 매개변수 전달
- call은 함수에 대한 매개변수를 순서대로 전달
- bind는 함수에 대한 매개변수를 전달하지 않고 나중에 반환된 함수를 호출할 때 매개변수 전달
- call vs bind 예시 코드
var obj = { value: 42 };
function getValue(prefix) {
console.log(prefix + this.value);
}
getValue.call(obj, "The value is: ");
var boundFunction = getValue.bind(obj, "The value is: ");
boundFunction();
- call은 함수를 즉시 호출하고, bind는 함수를 호출하지 않고 새로운 함수를 반환 후, 나중에 boundFunction이 호출될 때 원래 함수가 호출되면서 this 값과 매개변수가 전달
- 즉, call은 즉시 함수를 호출하고 매개변수를 전달할 때 사용
- bind는 새로운 함수를 생성하고 나중에 필요한 시점에 호출할 때 this 값을 설정하는 데 사용