Skip to content

Instantly share code, notes, and snippets.

@ibare
Last active July 11, 2017 05:34
Show Gist options
  • Save ibare/398ceb9c612c4dcf162d92cbf155cbb6 to your computer and use it in GitHub Desktop.
Save ibare/398ceb9c612c4dcf162d92cbf155cbb6 to your computer and use it in GitHub Desktop.
javascript 실행 콘텍스트의 변화
function Foo() {
// this 는 new 연산자로 호출되었을 때를 전제한다
// this 는 인스턴스 객체
this.myname = 'Foo';
this.displayName = function() {
// this 는 인스턴스 객체를 전제한다.
// 따라서 반드시 [인스턴스].displayName() 으로 호출되어야한다
// 그렇게 하지 못할 경우 인스턴스 객체를 바인딩 시켜줘야야 this 가 인스턴스 객체를 가르킨다
// ㄴ displayName.bind([인스턴스])
console.log(this.myname);
};
}
// 함수를 대신 호출해 주는 함수
function call(fn) {
fn();
}
var foo = new Foo();
foo.displayName(); // this 는 foo 가 된다
call(foo.displayName); // this 는 window 객체가 된다
call(foo.displayName.bind(foo)); // this 는 바인딩된 foo(인스턴스) 객체가 된다
setTimeout(foo.displayName, 100); // this 는 window 객체가 된다
setTimeout(function() {
foo.displayName(); // this 는 foo 객체가 된다
}, 200);
@gomin8or
Copy link

line 23에서, this가 왜 window가 되는건지 모르겠어요...
혹시 line21에서는 foo.displayName()으로 실행하고 있고, line23에서는 call()이 실행을 하고 있기 때문에 그런건가요? call()은 실제로는 window.call()이니까???

@ibare
Copy link
Author

ibare commented Jul 11, 2017

맞습니다. 호출 시점(실행 시점)에 소유자가 this 가 되는데요 foo.displayName() 이러면 소유자가 foo 가 되고요 마침표 연산자의 왼쪽에 있는 녀석이 소유자가 된다고 볼 수 있습니다. 그러니 마침표 연산자가 없는 호출인 경우 window 즉 전역 객체가 소유자가 되어서 함수 내에서 this 가 가르키는 객체가 달라지는 것이죠.

bind 는 이를 임의로 고정시켜주는 역할을 합니다. 함수 객체가 모두 가지고 있는 Function.call 또는 Function.apply 는 소유자를 호출 시점에 지정할 수 있는 기능을 제공하지요. 그래서 결론적으로 this 는 실행이 어떻게 되느냐에 따라 유동적으로 변화하는 실행 콘텍스트라 불리우는 것이지요.

@gomin8or
Copy link

아... 이제 논리가 완전히 이해되었습니다! 한번 들었을 때에는 몰랐어요... 감사합니다 ㅠㅠ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment