Chapter 1: this Or That? - hochan222/Everything-in-JavaScript GitHub Wiki
ํ,,์๋ฐ์คํฌ๋ฆฝํธ์์ ๋๋ ต๊ณ ๋๋ ค์ด this ํค์๋๋ค.
์ฐ๋ฆฌ ๋ชจ๋ ์ด๋ฒ ๊ธฐํ์ ๋๋ ค์์ ๋ ๋ ค๋ฒ๋ ค๋ณด์.
this
?
Why this
๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์์๊ฒ ๋ง์ ํผ๋์ค๋ฌ์์ ์ค๋ค. ๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ this
๋ ์ ๊ฐ์น์์๊น?
function identify() {
return this.name.toUpperCase();
}
function speak() {
var greeting = "Hello, I'm " + identify.call( this );
console.log( greeting );
}
var me = {
name: "Kyle"
};
var you = {
name: "Reader"
};
identify.call( me ); // KYLE
identify.call( you ); // READER
speak.call( me ); // Hello, I'm KYLE
speak.call( you ); // Hello, I'm READER
์์ code snippet์ ์ฌ์ฉํ๋ฉด ๊ฐ๊ฐ ๊ฐ์ฒด์ ๋ฐ๋ฅธ ๋ณ๋์ ํจ์๋ฅผ ๋ง๋ค์ง ์๋๋ผ๋ ์ฌ์ฌ์ฉํด์ ์ธ ์ ์๋ค. ๋ง์ฝ this๋ฅผ ์ฌ์ฉํ์ง ์๋๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํด์ผ ํ๋ค.
function identify(context) {
return context.name.toUpperCase();
}
function speak(context) {
var greeting = "Hello, I'm " + identify( context );
console.log( greeting );
}
identify( you ); // READER
speak( me ); // Hello, I'm KYLE
์ฌ์ฉ ํจํด์ด ๋ณต์กํ ์๋ก ์ฌ์ฌ์ฉํ๊ธฐ ์ฝ๊ณ , API ๋์์ธ์ ๊น๋ํ๊ฒ ์ด๋๋ค.
Confusions
this
์ ์ ํํ ์๋ ๋ฐฉ์์ ์์๋ณด๊ธฐ์ ์ ์ ํํ ์๋ฏธ๋ฅผ ์์๋ณด์. ์ข
์ข
๊ฐ๋ฐ์๋ค์ this
๋ฅผ 2๊ฐ์ง๋ก ๋ถ๋ฅํด์ ์๊ฐํ๋๋ฐ ๋๊ฐ ๋ค ์ณ์ง ๋ชปํ๋ค.
Itself
this
๊ฐ ํจ์์์ ๋ฌธ๋ฒ์ ์ผ๋ก ์๊ธฐ ์์ ์ ์ฐธ์กฐํ๋ค๊ณ ์๊ฐํ๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์ ๋ฉ์ปค๋์ฆ์ ์ฒ์ ์ ํ๋ ๊ฐ๋ฐ์๋ ํจ์๋ฅผ ๊ฐ์ฒด(JavaScript์ ๋ชจ๋ ํจ์๊ฐ ๊ฐ์ฒด์ด๋ค.)๋ก ์ฐธ์กฐํ๋ฉด ํจ์ ํธ์ถ ์ฌ์ด์ ์ํ (์์ฑ ๊ฐ)๋ฅผ ์ ์ฅํ ์ ์๋ค๊ณ ์๊ฐํ๋ค.
(์ด๊ฒ๋ ๋์์ง ์์ ๋ฐฉ๋ฒ์ด์ง๋ง ๋ท์ฅ์์ ๋ ์ข์ ๋ฐฉ๋ฒ์ ์๋ ค์ค ๊ฒ์ด๋ค.)
์์ ๋ฅผ ๋ณด์.
function foo(num) {
console.log( "foo: " + num );
// keep track of how many times `foo` is called
this.count++;
}
foo.count = 0;
var i;
for (i=0; i<10; i++) {
if (i > 5) {
foo( i );
}
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9
// how many times was `foo` called?
console.log( foo.count ); // 0 -- WTF?
์ค.. ๋๋ฐ...
foo.count = 0
๊ฐ ์คํ ๋ ๋, ์ฌ์ค foo ํจ์ ๊ฐ์ฒด์ count๊ฐ ์ถ๊ฐ๋๋ค. ๊ทธ๋ฌ๋ this.count๋ ํจ์ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฅดํค์ง ์๋๋ค.
๋ฐ๋ผ์ค๋ ๋น์ฐํ ์ง๋ฌธ์ ์ฐ๋ฆฌ๋ this.count๋ก ์ ์ญ ๋ณ์๋ฅผ ๋ง๋ค์๊ณ , NAN์ด ๋ค์ด๊ฐ ์์๊ฒ์ด๋ค. ์๋๋ฉด undefined๋ฅผ ++ ํด์ฃผ์์ผ๋๊น. (2์ฅ์์ ๋ฐฐ์)
๋ด๋ถ์์ ํจ์ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ ค๋ฉด lexical identifier ๊ฐ ํ์ํ๋ค.
function foo() {
foo.count = 4; // `foo` refers to itself
}
setTimeout( function(){
// anonymous function (no name), cannot
// refer to itself
}, 10 );
์ฒซ๋ฒ์งธ ํจ์๋ name identifier ๊ฐ ์์ผ๋ฏ๋ก ์๊ธฐ ์์ ์ ์ฐธ์กฐ ๊ฐ๋ฅํ๋ค.
๋๋ฒ์งธ ํจ์๋ ์ต๋ช
ํจ์๋ก ์ฐธ์กฐ ํ ์ ์ ํ ๋ฐฉ๋ฒ์ด ์๋ค.
arguments.callee๋ ์ต๋ช ํจ์์์ ์๊ธฐ ์์ ์ ์ฐธ์กฐํ ์ ์ผํ ๋ฐฉ๋ฒ์ด์์ง๋ง deprecated๋์๋ค.
๋ค์์ ๊ฐ์ ๋ ์๋ฃจ์ ์ด๋ค.
function foo(num) {
console.log( "foo: " + num );
// keep track of how many times `foo` is called
foo.count++;
}
foo.count = 0;
var i;
for (i=0; i<10; i++) {
if (i > 5) {
foo( i );
}
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9
// how many times was `foo` called?
console.log( foo.count ); // 4
๊ทธ๋ฌ๋ this์ ๋ํ ๊ทผ๋ณธ์ ์ธ ์ดํด๋ ํผํ๊ณ ์๋ค. ๋ค์์ ๋ณด์.
function foo(num) {
console.log( "foo: " + num );
// keep track of how many times `foo` is called
// Note: `this` IS actually `foo` now, based on
// how `foo` is called (see below)
this.count++;
}
foo.count = 0;
var i;
for (i=0; i<10; i++) {
if (i > 5) {
// using `call(..)`, we ensure the `this`
// points at the function object (`foo`) itself
foo.call( foo, i );
}
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9
// how many times was `foo` called?
console.log( foo.count ); // 4
this
๋ฅผ ํผํ์ง๋ง๊ณ ํฌ์ฉํ์!
Its Scope
๊ทธ ๋ค์ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ์๋ชป๋ ์๊ฐ์ this
๊ฐ ์ด๋ป๊ฒ๋ ํจ์ ๋ฒ์๋ฅผ ์ฐธ์กฐํ๋ค๋ ๊ฒ์ด๋ค. this
๋ ์ด๋ป๊ฒ๋ ํจ์์ lexical scope๋ฅผ ์ฐธ์กฐ ํ ์ ์๋ค. object์ scope๋ ์์ง์ ๋ด๋ถ ๊ตฌํ์ค ํ๋์ด๊ธฐ ๋๋ฌธ์ด๋ค.
function foo() {
var a = 2;
this.bar();
}
function bar() {
console.log( this.a );
}
foo(); //undefined
์ค์ JS forum์์ ๋์จ ์ง๋ฌธ ์์ ๋ค. ์ด snippet์๋ ๋ ๋ง์ด ์๋ชป๋๊ฒ ์๋ค.
์ฐ์ bar๋ฅผ this๋ก ์ฐธ์กฐํ๋๊ฒ ์๋ชป๋๋ค. ์กฐ๊ธ ๋ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ ์๋ณ์๋ก lexical ์ฐธ์กฐ๋ฅผ ํ๋๊ฒ์ด๋ค. ๋๋ฒ์งธ๋ก ๋ญ๊ฐ fooํจ์ ๋ด๋ถ์ barํจ์์ lexical ์๋ณ์๋ฅผ ๋ ์ผ๋ก์จ ์ฐธ์กฐํ๋๋ฐ this๋ฅผ ํตํ ์ด๋คํ ์ฐ๊ฒฐ๊ณ ๋ฆฌ๊ณ ์๊ธธ ์ ์๋ค.
What's this?
์ฐ์ this
๋ ๋ฐํ์ ๋ฐ์ธ๋ฉ์ด๊ณ , ํจ์ ์ ์ธ ์์น์๋ ๊ด๋ จ์์ง๋ง ํจ์ ํธ์ถ ๋ฐฉ์๊ณผ๋ ๊ด๋ จ์ด ์๋ค.
ํจ์๊ฐ ํธ์ถ๋๋ฉด ์คํ ์ปจํ ์คํธ(execution context)๋ก ์๋ ค์ ธ ์๋ activation record๊ฐ ๋ง๋ค์ด์ง๋ค. ์ด ๋ ์ฝ๋์๋ ํจ์๊ฐ ํธ์ถ ๋ ์์น (ํธ์ถ ์คํ), ํจ์๊ฐ ํธ์ถ ๋ ๋ฐฉ๋ฒ, ์ ๋ฌ ๋ ๋งค๊ฐ ๋ณ์ ๋ฑ์ ๋ํ ์ ๋ณด๊ฐ ํฌํจ๋๋ค. ๋ ์ฝ๋ ์์ ์ค ํจ์ ์คํ ์ค ์ฌ์ฉ๋ this ์ฐธ์กฐ์ ๊ดํ ์์๋ ์๋ค.
๋ค์ ์ฅ์์๋ ํจ์์ call-site๋ฅผ ํตํด ์ด๋ป๊ฒ this
๊ฐ ๋ฐ์ธ๋ฉํ๋์ง ๋ฐฉ๋ฒ์ ๊ฒฐ์ ํ ๊ฒ์ด๋ค.
Review (TL;DR)
์ฐ๋ฆฌ๋ this์ ์๋ฆฌ๋ฅผ ์ ํํ ์๋ คํ๋๋ฐ ์๊ฐ์ ํฌ์ํ์ง์๊ณ ๊ธฐํ ์ฌ์ดํธ๋ค์์ ํธ๋ฆญ๋ง ๋ฐฐ์์ ์ฌ๋ฌ ํผ๋๋ค์ ์ ๋ฐํ๋ค.
์ฐ๋ฆฌ๋ this๋ฅผ ๋ฐฐ์์ผํ๋ค. ํจ์ ์์ฒด๋์๋๊ณ ํจ์์ lexical scope๋ ์๋๋ค.
this
๋ ์ค์ ๋ก ํจ์๊ฐ ํธ์ถ๋ ๋ ๋ง๋ค์ด์ง๋ ๋ฐ์ธ๋ฉ์ด๋ฉฐ this
๊ฐ ์ฐธ์กฐํ๋ ๊ฒ์ ์ ์ ์ผ๋ก call-site์ ์์กดํ๋ค.