this

summereuna๐Ÿฅยท2024๋…„ 6์›” 3์ผ

JS ๋ฌธ๋ฒ• ์ •๋ฆฌ

๋ชฉ๋ก ๋ณด๊ธฐ
13/20

๐Ÿ’ก ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋Š” ์‹คํ–‰ํ•  ์ฝ”๋“œ์— ์ œ๊ณตํ•  ํ™˜๊ฒฝ ์ •๋ณด๋“ค์„ ๋ชจ์•„๋†“์€ ๊ฐ์ฒด์ด๋‹ค.

  • ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ๊ฐ์ฒด ์•ˆ์—๋Š” 3๊ฐ€์ง€๊ฐ€ ์กด์žฌ
    • VariableEnvironment
    • LexicalEnvironment
    • ๐ŸŒŸ ThisBindings

this(์ •์˜, ํ™œ์šฉ๋ฐฉ๋ฒ•, ๋ฐ”์ธ๋”ฉ, call, apply, bind)


๋‹ค๋ฅธ ๊ฐ์ฒด์ง€ํ–ฅ ์–ธ์–ด์—์„œ์˜ this๋Š” ๊ณง ํด๋ž˜์Šค๋กœ ์ƒ์„ฑํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งํ•˜์ง€๋งŒ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” this๊ฐ€ ์–ด๋””์—์„œ๋‚˜ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

this๊ฐ€ ์ƒํ™ฉ๋ณ„๋กœ ์–ด๋–ป๊ฒŒ ๋‹ฌ๋ผ์ง€๋Š”์ง€, ์ด์œ ๋Š” ๋ญ”์ง€, this๋ฅผ ์ถ”์ ํ•˜๋Š” ๋ฐฉ๋ฒ• ๋“ฑ์„ ์•Œ์•„๋ณด์ž.

1. ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š” this


1-1. this๋Š” ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ๊ฒฐ์ •๋œ๋‹ค.

์ด ๋ง์„ this๋ฅผ bindํ•œ๋‹ค(=๋ฌถ๋Š”๋‹ค) ๋ผ๊ณ ๋„ ํ•œ๋‹ค.
๋‹ค์‹œ ๋งํ•˜๋ฉด. this๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๊ฒฐ์ •๋œ๋‹ค. ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

1. ์ „์—ญ ๊ณต๊ฐ„์—์„œ์˜ this
    1. ์ „์—ญ ๊ณต๊ฐ„์—์„œ this๋Š” **์ „์—ญ ๊ฐ์ฒด**๋ฅผ ๊ฐ€๋ฆฌ์ผœ์š”.
    2. ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ this๋Š” window(๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ) ๋˜๋Š” global(node ํ™˜๊ฒฝ)๋ฅผ ๊ฐ๊ฐ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.
        
        <aside>
        ๐Ÿ’ก **๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ?**
        
        ์—ฌ๋Ÿฌ๋ถ„๋“ค์ด javascript๋กœ ๋งŒ๋“ค์–ด๋†“์€ ํ”„๋กœ๊ทธ๋žจ์ด ๊ตฌ๋™์ค‘์ธ ํ™˜๊ฒฝ์„ ๋งํ•˜์ฃ . ์šฐ๋ฆฌ๋Š” node ํŒŒ์ผ์ด๋ฆ„.js๋กœ vscode ์ƒ์—์„œ ๊ตฌ๋™ํ•˜๊ณ  ์žˆ์œผ๋‹ˆ **node ํ™˜๊ฒฝ**์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๊ตฌ์š”. html ํŒŒ์ผ ์•ˆ์— ์ˆจ๊ฒจ๋†“์•„์„œ ํฌ๋กฌ๋ธŒ๋ผ์šฐ์ € ๋“ฑ์—์„œ ์—ฐ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด **๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ**์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๊ฒ ๋„ค์š”.
        
        </aside>
        
        <๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ this ํ™•์ธ>
        
        ```jsx
        console.log(this);
        console.log(window);
        console.log(this === window);
        ```
        
        <node ํ™˜๊ฒฝ this ํ™•์ธ>
        
        ```jsx
        console.log(this);
        console.log(global);
        console.log(this === global);
        ```
        

1-2. ๋ฉ”์„œ๋“œ๋กœ์„œ ํ˜ธ์ถœํ•  ๋•Œ ๊ทธ ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ์˜ this


1-2-1. ํ•จ์ˆ˜ vs ๋ฉ”์„œ๋“œ


ํ•จ์ˆ˜์™€ ๋ฉ”์„œ๋“œ๋Š” ์ƒ๋‹นํžˆ ๋น„์Šทํ•ด ๋ณด์ด์ง€๋งŒ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.
๊ธฐ์ค€์€ ๋…๋ฆฝ์„ฑ์ด๋‹ค.

ํ•จ์ˆ˜๋Š” ๊ทธ ์ž์ฒด๋กœ ๋…๋ฆฝ์ ์ธ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰

ํ•จ์ˆ˜๋ช…();

๋ฉ”์„œ๋“œ๋Š” ์ž์‹ ์„ ํ˜ธ์ถœํ•œ ๋Œ€์ƒ ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋™์ž‘์„ ์ˆ˜ํ–‰, ์ฆ‰ ํ˜ธ์ถœ ์ฃผ์ฒด๊ฐ€ ๋”ฐ๋กœ ์กด์žฌ

๊ฐ์ฒด.๋ฉ”์„œ๋“œ๋ช…();

1-2-2. ํ•จ์ˆ˜์™€ ๋ฉ”์„œ๋“œ์˜ this์˜ ํ• ๋‹น ์ฐจ์ด


// CASE1 : ํ•จ์ˆ˜
// ํ˜ธ์ถœ ์ฃผ์ฒด๋ฅผ ๋ช…์‹œํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— this๋Š” ์ „์—ญ ๊ฐ์ฒด๋ฅผ ์˜๋ฏธํ•ด์š”.
var func = function (x) {
	console.log(this, x);
};
func(1); // Window { ... } 1

// CASE2 : ๋ฉ”์„œ๋“œ
// ํ˜ธ์ถœ ์ฃผ์ฒด๋ฅผ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— this๋Š” ํ•ด๋‹น ๊ฐ์ฒด(obj)๋ฅผ ์˜๋ฏธํ•ด์š”.
// obj๋Š” ๊ณง { method: f }๋ฅผ ์˜๋ฏธํ•˜์ฃ ?
var obj = {
	method: func,
};
obj.method(2); // { method: f } 2

1-2-3. ํ•จ์ˆ˜๋กœ์„œ์˜ ํ˜ธ์ถœ๊ณผ ๋ฉ”์„œ๋“œ๋กœ์„œ์˜ ํ˜ธ์ถœ ๊ตฌ๋ถ„ ๊ธฐ์ค€ : . []


์ (.)์œผ๋กœ ํ˜ธ์ถœํ•˜๋“ , ๋Œ€๊ด„ํ˜ธ([])๋กœ ํ˜ธ์ถœํ•˜๋“  ๊ฒฐ๊ณผ๋Š” ๊ฐ™๋‹ค.

var obj = {
	method: function (x) { console.log(this, x) }
};
obj.method(1); // { method: f } 1
obj['method'](2); // { method: f } 2

1-2-4. ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ์˜ this


this์—๋Š” ํ˜ธ์ถœ์„ ๋ˆ„๊ฐ€ ํ–ˆ๋Š”์ง€์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ๋‹ด๊ธด๋‹ค.

var obj = {
	methodA: function () { console.log(this) },
	inner: {
		methodB: function() { console.log(this) },
	}
};

obj.methodA();             // this === obj
obj['methodA']();          // this === obj

obj.inner.methodB();       // this === obj.inner
obj.inner['methodB']();    // this === obj.inner
obj['inner'].methodB();    // this === obj.inner
obj['inner']['methodB'](); // this === obj.inner

1-3. ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•  ๋•Œ ๊ทธ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ์˜ this


1-3-1. โœ… ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ์˜ this


  1. ์–ด๋–ค ํ•จ์ˆ˜๋ฅผ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ, this๋Š” ์ง€์ •๋˜์ง€ ์•Š์Œ
    (ํ˜ธ์ถœ ์ฃผ์ฒด๋ฅผ ์•Œ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ)

  2. ์‹คํ–‰์ปจํ…์ŠคํŠธ๋ฅผ ํ™œ์„ฑํ™”ํ•  ๋‹น์‹œ this๊ฐ€ ์ง€์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ,
    this๋Š” ์ „์—ญ ๊ฐ์ฒด๋ฅผ ์˜๋ฏธ

  3. ๋”ฐ๋ผ์„œ, ํ•จ์ˆ˜๋กœ์„œ โ€˜๋…๋ฆฝ์ ์œผ๋กœโ€™ ํ˜ธ์ถœํ•  ๋•Œ๋Š” this๋Š” ํ•ญ์ƒ ์ „์—ญ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค๋Š” ๊ฒƒ์„ ์ฃผ์˜!

1-3-2. ๋ฉ”์„œ๋“œ์˜ โœ… ๋‚ด๋ถ€ ํ•จ์ˆ˜์—์„œ์˜ this


  1. ์˜ˆ์™ธ ์—†์Œ!
    ๋ฉ”์„œ๋“œ์˜ ๋‚ด๋ถ€๋ผ๊ณ  ํ•ด๋„, ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•œ๋‹ค๋ฉด this๋Š” ์ „์—ญ ๊ฐ์ฒด๋ฅผ ์˜๋ฏธ
var obj1 = {
	outer: function() {
		console.log(this); // (1)
		var innerFunc = function() {
			console.log(this); // (2), (3)
		}
		innerFunc();

		var obj2 = {
			innerMethod: innerFunc
		};
		obj2.innerMethod();
	}
};
obj1.outer();

์œ„ ์ฝ”๋“œ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ (1), (2), (3)์„ ์˜ˆ์ธก

(1) : obj1
(2) : ์ „์—ญ๊ฐ์ฒด
(3) : obj2

โ— this ๋ฐ”์ธ๋”ฉ์— ๊ด€ํ•ด์„œ๋Š” ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋‹น์‹œ์˜ ์ฃผ๋ณ€ ํ™˜๊ฒฝ(๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์ธ์ง€, ํ•จ์ˆ˜ ๋‚ด๋ถ€์ธ์ง€)์€ ์ค‘์š”ํ•˜์ง€ ์•Š๊ณ ,
์˜ค์ง ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ตฌ๋ฌธ ์•ž์— ์  ๋˜๋Š” ๋Œ€๊ด„ํ˜ธ ํ‘œ๊ธฐ๊ฐ€ ์žˆ๋Š”์ง€๊ฐ€ ๊ด€๊ฑด์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

1-3-3. ๋ฉ”์„œ๋“œ์˜ ๋‚ด๋ถ€ ํ•จ์ˆ˜์—์„œ์˜ this ์šฐํšŒ


this์— ๋Œ€ํ•ด์„œ ์ดํ•ด๋Š” ํ•˜๊ฒ ์ง€๋งŒโ€ฆ ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ ์ฆ‰, ๊ฐœ๋ฐœ์ž ์ž…์žฅ์—์„œ ์ด๊ฒŒ ์‰ฝ๊ฒŒ ๋ฐ›์•„๋“ค์—ฌ์ง€์ง€ ์•Š๋Š”๋‹ค ใ… ใ… 

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์šฐํšŒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์šฐ๋ฆฌ๋Š” ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค!

1-3-3-1. ๋ณ€์ˆ˜๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

๋‚ด๋ถ€ ์Šค์ฝ”ํ”„์— ์ด๋ฏธ ์กด์žฌํ•˜๋Š” this๋ฅผ ๋ณ„๋„์˜ ๋ณ€์ˆ˜(ex : self)์— ํ• ๋‹นํ•˜๋Š” ๋ฐฉ๋ฒ•

var obj1 = {
	outer: function() {
		console.log(this); // (1) outer

		// AS-IS
		var innerFunc1 = function() {
			console.log(this); // (2) ์ „์—ญ๊ฐ์ฒด
		}
		innerFunc1();

		// TO-BE
		var self = this;
		var innerFunc2 = function() {
			console.log(self); // (3) outer
		};
		innerFunc2();
	}
};

// ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ๋ถ€๋ถ„
obj1.outer();

1-3-3-2. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜(= this๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜์ง€ ์•Š๋Š” ํ•จ์ˆ˜)

  1. ES6์—์„œ ์ฒ˜์Œ ๋„์ž…๋œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š”, ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ this ๋ฐ”์ธ๋”ฉ ๊ณผ์ • ์ž์ฒด๊ฐ€ ์—†๋‹ค. ๋”ฐ๋ผ์„œ, this๋Š” ์ด์ „์˜ ๊ฐ’-์ƒ์œ„๊ฐ’-์ด ์œ ์ง€๋œ๋‹ค.

    ES6์—์„œ๋Š” ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ this๊ฐ€ ์ „์—ญ๊ฐ์ฒด๋ฅผ ๋ฐ”๋ผ๋ณด๋Š” ๋ฌธ์ œ ๋•Œ๋ฌธ์— ํ™”์‚ดํ‘œํ•จ์ˆ˜๋ฅผ ๋„์ž…ํ–ˆ๋‹ค.


    Q. ์ผ๋ฐ˜ ํ•จ์ˆ˜์™€ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์€?
    A. ๐ŸŒŸ this binding ์—ฌ๋ถ€

var obj = {
	outer: function() {
		console.log(this); // (1) obj
		var innerFunc = () => {
			console.log(this); // (2) obj
		};
		innerFunc();
	}
}

obj.outer();

1-4. ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ ๊ทธ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ์˜ this


์ฝœ๋ฐฑํ•จ์ˆ˜๋Š” โ€œ์–ด๋– ํ•œ ํ•จ์ˆ˜, ๋ฉ”์„œ๋“œ์˜ ์ธ์ž(๋งค๊ฐœ๋ณ€์ˆ˜)๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ํ•จ์ˆ˜โ€์ด๋‹ค.

์ด ๋•Œ, ์ฝœ๋ฐฑํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this๋Š” ํ•ด๋‹น ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ๋„˜๊ฒจ๋ฐ›์€ ํ•จ์ˆ˜(๋ฉ”์„œ๋“œ)๊ฐ€ ์ •ํ•œ ๊ทœ์น™์— ๋”ฐ๋ผ ๊ฐ’์ด ๊ฒฐ์ •๋œ๋‹ค.

  • ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋„ ํ•จ์ˆ˜๊ธฐ ๋•Œ๋ฌธ์— this๋Š” ์ „์—ญ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐ(ํ˜ธ์ถœ ์ฃผ์ฒด๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ)
  • ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ๋„˜๊ฒจ๋ฐ›์€ ํ•จ์ˆ˜์—์„œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์— ๋ณ„๋„๋กœ this๋ฅผ ์ง€์ •ํ•œ ๊ฒฝ์šฐ์—๋Š” ์˜ˆ์™ธ์ ์œผ๋กœ ๊ทธ ๋Œ€์ƒ์„ ์ฐธ์กฐ

โ— ๋กœ์ง์„ ์ดํ•ดํ•˜๋Š” ๊ฒƒ ๋ณด๋‹ค๋Š”, this์˜ ์ƒํƒœ๋ฅผ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ๋” ์ค‘์š”!

// โœ… ๋ณ„๋„ ์ง€์ • ์—†์Œ : ์ „์—ญ๊ฐ์ฒด
setTimeout(function () { console.log(this) }, 300);

// โœ… ๋ณ„๋„ ์ง€์ • ์—†์Œ : ์ „์—ญ๊ฐ์ฒด
[1, 2, 3, 4, 5].forEach(function(x) {
	console.log(this, x);
});

// ๐Ÿ”ฅ ์ฝœ๋ฐฑํ•จ์ˆ˜ ์˜ˆ์™ธ
// addListener ์•ˆ์—์„œ์˜ this๋Š” ํ•ญ์ƒ ํ˜ธ์ถœํ•œ ์ฃผ์ฒด์˜ element๋ฅผ returnํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Œ
// ๐Ÿ”ฅ ๋”ฐ๋ผ์„œ this๋Š” button์„ ์˜๋ฏธํ•จ
document.body.innerHTML += '<button id="a">ํด๋ฆญ</button>';
document.body.querySelector('#a').addEventListener('click', function(e) {
	console.log(this, e);
});
  1. setTimeout ํ•จ์ˆ˜, forEach ๋ฉ”์„œ๋“œ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋Œ€์ƒ์ด ๋  this๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, this๋Š” ๊ณง window๊ฐ์ฒด

  2. addEventListner ๋ฉ”์„œ๋“œ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ, ์ž์‹ ์˜ this๋ฅผ ์ƒ์†ํ•˜๋ฏ€๋กœ, this๋Š” addEventListner์˜ ์•ž๋ถ€๋ถ„(button ํƒœ๊ทธ)

1-5. ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ์˜ this


  1. ์ƒ์„ฑ์ž : ๊ตฌ์ฒด์ ์ธ ์ธ์Šคํ„ด์Šค(์–ด๋ ค์šฐ๋ฉด ๊ฐ์ฒด๋กœ ์ดํ•ด!)๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์ผ์ข…์˜ ํ‹€
  2. ๊ณตํ†ต ์†์„ฑ๋“ค์ด ์ด๋ฏธ ์ค€๋น„๋˜์–ด ์žˆ๋‹ค.

๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์—์„œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ์˜ this๋ฅผ ๋ณธ ์ ์ด ์žˆ์Œ!

var Cat = function (name, age) {
	this.bark = '์•ผ์˜น';
	this.name = name;
	this.age = age;
};

var choco = new Cat('์ดˆ์ฝ”', 7); //this : choco ์ธ์Šคํ„ด์Šค ๊ฐ€๋ฆฌํ‚ด
var nabi = new Cat('๋‚˜๋น„', 5);  //this : nabi ์ธ์Šคํ„ด์Šค ๊ฐ€๋ฆฌํ‚ด

2. ๋ช…์‹œ์  this ๋ฐ”์ธ๋”ฉ: call, apply, bind ๋ฉ”์„œ๋“œ


์ž๋™์œผ๋กœ ๋ถ€์—ฌ๋˜๋Š” ์ƒํ™ฉ๋ณ„ this์˜ ๊ทœ์น™์„ ๊นจ๊ณ  this์— ๋ณ„๋„์˜ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•

ํฌ๊ฒŒ, call / apply / bind๋ฉ”์„œ๋“œ๋กœ ๋ช…์‹œ์  this ๋ฐ”์ธ๋”ฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

2-1. call ๋ฉ”์„œ๋“œ


  1. ํ˜ธ์ถœ ์ฃผ์ฒด์ธ ํ•จ์ˆ˜๋ฅผ ์ฆ‰์‹œ ์‹คํ–‰ํ•˜๋Š” ๋ช…๋ น์–ด

  2. call ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์— this๋กœ bindingํ•  ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ๋ช…์‹œ์ ์œผ๋กœ bindingํ•  ์ˆ˜ ์žˆ.

์˜ˆ์‹œ

var func = function (a, b, c) {
	console.log(this, a, b, c);
};

// no binding
func(1, 2, 3); // Window{ ... } 1 2 3

// ๋ช…์‹œ์  binding
// func ์•ˆ์— this์—๋Š” {x: 1}์ด binding๋ผ์š”
func.call({ x: 1 }, 4, 5, 6}; // { x: 1 } 4 5 6

์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด, ์˜ˆ์ƒ๋˜๋Š” this๊ฐ€ ์žˆ์Œ์—๋„ ์ผ๋ถ€๋Ÿฌ ๋ฐ”๊พธ๋Š” ์—ฐ์Šต

var obj = {
	a: 1,
	method: function (x, y) {
		console.log(this.a, x, y);
	}
};

obj.method(2, 3); // 1 2 3
obj.method.call({ a: 4 }, 5, 6); // 4 5 6

2-2. apply ๋ฉ”์„œ๋“œ


  1. call ๋ฉ”์„œ๋“œ์™€ ๋น„์Šทํ•˜๋‹ค.
  2. ๋‹ค๋งŒ, this์— bindingํ•  ๊ฐ์ฒด๋Š” ๋˜‘๊ฐ™์ด ๋„ฃ์–ด์ฃผ๊ณ  ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„๋งŒ ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ๋„˜๊ฒจ์ค€๋‹ค.

์˜ˆ์‹œ

var func = function (a, b, c) {
	console.log(this, a, b, c);
};
func.apply({ x: 1 }, [4, 5, 6]); // { x: 1 } 4 5 6

var obj = {
	a: 1,
	method: function (x, y) {
		console.log(this.a, x, y);
	}
};

obj.method.apply({ a: 4 }, [5, 6]); // 4 5 6

2-3. call, apply ๋ฉ”์„œ๋“œ ํ™œ์šฉํ•˜๊ธฐ


๋ฌผ๋ก  this binding์„ ์œ„ํ•ด call, apply method๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•˜์ง€๋งŒ ๋” ์œ ์šฉํ•œ ์ธก๋ฉด๋„ ์žˆ๋‹ค.

2-3-1. ์œ ์‚ฌ๋ฐฐ์—ด๊ฐ์ฒด(array-like-object)์— ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์ ์šฉ


์œ ์‚ฌ ๋ฐฐ์—ด์˜ ์กฐ๊ฑด

๊ฐ์ฒด์ด์ง€๋งŒ ๋ฐฐ์—ด๊ณผ ์œ ์‚ฌํ•œ ๋ฐฐ์—ด์„ ์˜๋ฏธํ•œ๋‹ค.
1. ๋ฐ˜๋“œ์‹œ length๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์ด ์กฐ๊ฑด์€ ํ•„์ˆ˜๋กœ, ์ด ์กฐ๊ฑด์ด ์—†์œผ๋ฉด ์œ ์‚ฌ๋ฐฐ์—ด์ด๋ผ๊ณ  ์ธ์‹ํ•˜์ง€ ์•Š๋Š”๋‹ค.
2. index ๋ฒˆํ˜ธ๊ฐ€ 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ 1 ์”ฉ ์ฆ๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค. ์ด ์กฐ๊ฑด์€ ํ•„์ˆ˜๋Š” ์•„๋‹ˆ์ง€๋งŒ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

Array.slice() ๋ฉ”์„œ๋“œ

slice() ๋ฉ”์„œ๋“œ๋Š” ๋ฐฐ์—ด๋กœ ๋ถ€ํ„ฐ ํŠน์ • ๋ฒ”์œ„๋ฅผ ๋ณต์‚ฌํ•œ ๊ฐ’๋“ค์„ ๋‹ด๊ณ  ์žˆ๋Š” ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.
์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ์‹œ์ž‘ ์ธ๋ฑ์Šค, ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ์ข…๋ฃŒ ์ธ๋ฑ์Šค๋ฅผ ๋ฐ›๊ณ , ์‹œ์ž‘ ์ธ๋ฑ์Šค ๋ถ€ํ„ฐ ์ข…๋ฃŒ ์ธ๋ฑ์Šค๊นŒ์ง€์˜ ๊ฐ’์„ ๋ณต์‚ฌํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

//๊ฐ์ฒด์—๋Š” ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์ง์ ‘ ์ ์šฉํ•  ์ˆ˜ ์—†์–ด์š”.
//์œ ์‚ฌ๋ฐฐ์—ด๊ฐ์ฒด์—๋Š” call ๋˜๋Š” apply ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์ฐจ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.
var obj = {
	0: 'a',
	1: 'b',
	2: 'c',
	length: 3
};
Array.prototype.push.call(obj, 'd');
console.log(obj); // { 0: 'a', 1: 'b', 2: 'c', 3: 'd', length: 4 }

var arr = Array.prototype.slice.call(obj);
console.log(arr); // [ 'a', 'b', 'c', 'd' ]

2-3-2. Array.from ๋ฉ”์„œ๋“œ(ES6)


์‚ฌ์‹ค, call/apply๋ฅผ ํ†ตํ•ด this binding์„ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ฐ์ฒด โ†’ ๋ฐฐ์—ด๋กœ์˜ ํ˜• ๋ณ€ํ™˜ ๋งŒ์„ ์œ„ํ•ด์„œ๋„ ์“ธ ์ˆ˜ ์žˆ์ง€๋งŒ ์›๋ž˜ ์˜๋„์™€๋Š” ๊ฑฐ๋ฆฌ๊ฐ€ ๋จผ ๋ฐฉ๋ฒ•์ด๋ผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ, ES6์—์„œ๋Š” Array.from์ด๋ผ๋Š” ๋ฐฉ๋ฒ•์ด ๋‚˜์™”๋‹ค.

// ์œ ์‚ฌ๋ฐฐ์—ด
var obj = {
	0: 'a',
	1: 'b',
	2: 'c',
	length: 3
};

// ๊ฐ์ฒด -> ๋ฐฐ์—ด
var arr = Array.from(obj);

// ์ฐ์–ด๋ณด๋ฉด ๋ฐฐ์—ด์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.
console.log(arr);

2-3-3. ์ƒ์„ฑ์ž ๋‚ด๋ถ€์—์„œ ๋‹ค๋ฅธ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœ(๊ณตํ†ต๋œ ๋‚ด์šฉ์˜ ๋ฐ˜๋ณต ์ œ๊ฑฐ)


Student, Employee ๋ชจ๋‘ Person์ด๋‹ค.
name๊ณผ gender ์†์„ฑ ๋ชจ๋‘ ํ•„์š”ํ•˜๋‹ค.

๊ทธ๋Ÿฌ๋‹ˆ Student์™€ Employee ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ ๋งˆ๋‹ค ์„ธ ๊ฐ€์ง€ ์†์„ฑ์„ ๋ชจ๋‘ ๊ฐ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ๋„ฃ๊ธฐ ๋ณด๋‹ค๋Š” Person์ด๋ผ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ๋ณ„๋„๋กœ ๋นผ๋Š”๊ฒŒ โ€˜๊ตฌ์กฐํ™”โ€™์— ๋„์›€์ด ๋˜๊ณ  ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

function Person(name, gender) {
	this.name = name;
	this.gender = gender;
}
function Student(name, gender, school) {
	Person.call(this, name, gender); // ์—ฌ๊ธฐ์„œ this๋Š” student ์ธ์Šคํ„ด์Šค!
	this.school = school;
}
function Employee(name, gender, company) {
	Person.apply(this, [name, gender]); // ์—ฌ๊ธฐ์„œ this๋Š” employee ์ธ์Šคํ„ด์Šค!
	this.company = company;
}
var kd = new Student('๊ธธ๋™', 'male', '์„œ์šธ๋Œ€');
var ks = new Employee('๊ธธ์ˆœ', 'female', '์‚ผ์„ฑ');

2-3-4. ์—ฌ๋Ÿฌ ์ธ์ˆ˜๋ฅผ ๋ฌถ์–ด ํ•˜๋‚˜์˜ ๋ฐฐ์—ด๋กœ ์ „๋‹ฌํ•  ๋•Œ apply ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค


  1. apply๋ฅผ ํ†ตํ•ด ๋น„ํšจ์œจ์ ์ธ ์˜ˆ์‹œ๋ฅผ ํšจ์œจ์ ์ธ ์˜ˆ์‹œ๋กœ ๋ฐ”๊พธ๊ธฐ
//๋น„ํšจ์œจ
var numbers = [10, 20, 3, 16, 45];
var max = min = numbers[0];
numbers.forEach(function(number) {
	// ํ˜„์žฌ ๋Œ์•„๊ฐ€๋Š” ์ˆซ์ž๊ฐ€ max๊ฐ’ ๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ
	if (number > max) {
		// max ๊ฐ’์„ ๊ต์ฒด
		max = number;
	}

	// ํ˜„์žฌ ๋Œ์•„๊ฐ€๋Š” ์ˆซ์ž๊ฐ€ min๊ฐ’ ๋ณด๋‹ค ์ž‘์€ ๊ฒฝ์šฐ
	if (number < min) {
		// min ๊ฐ’์„ ๊ต์ฒด
		min = number;
	}
});

console.log(max, min);

์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ๊ธธ๊ณ  ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.
pply๋ฅผ ์ ์šฉํ•ด ๊ฐ€๋…์„ฑ๋„ ๋†’์ด๊ณ  ํšจ์œจ์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด์ž.

//ํšจ์œจ
var numbers = [10, 20, 3, 16, 45];
var max = Math.max.apply(null, numbers);
var min = Math.min.apply(null, numbers);
console.log(max, min);

// ํŽผ์น˜๊ธฐ ์—ฐ์‚ฐ์ž(Spread Operation)๋ฅผ ํ†ตํ•˜๋ฉด ๋” ๊ฐ„ํŽธํ•˜๊ฒŒ ํ•ด๊ฒฐ๋„ ๊ฐ€๋Šฅํ•ด์š”
const numbers = [10, 20, 3, 16, 45];
const max = Math.max(...numbers);
const min = Math.min(...numbers);
console.log(max min);

2-4. bind ๋ฉ”์„œ๋“œ


2-4-1. bind ๋ฉ”์„œ๋“œ, ๋ชฉ์ , ์˜ˆ์‹œ


call๊ณผ ๋น„์Šทํ•ด ๋ณด์ด์ง€๋งŒ, ์ฆ‰์‹œ call๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ์ฆ‰์‹œ ํ˜ธ์ถœํ•˜์ง€๋Š” ์•Š๊ณ  ๋„˜๊ฒจ๋ฐ›์€ this ๋ฐ ์ธ์ˆ˜๋“ค์„ ๋ฐ”ํƒ•์œผ๋กœ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ

๋ชฉ์ 

  1. ํ•จ์ˆ˜์— this๋ฅผ ๋ฏธ๋ฆฌ ์ ์šฉ
  2. ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜ ๊ตฌํ˜„ํ•  ๋•Œ ์šฉ์ด

์˜ˆ์‹œ

var func = function (a, b, c, d) {
	console.log(this, a, b, c, d);
};
func(1, 2, 3, 4); // window๊ฐ์ฒด

// ํ•จ์ˆ˜์— this ๋ฏธ๋ฆฌ ์ ์šฉ
var bindFunc1 = func.bind({ x: 1 }); // ๋ฐ”๋กœ ํ˜ธ์ถœ๋˜์ง€๋Š” ์•Š์•„์š”! ๊ทธ ์™ธ์—๋Š” ๊ฐ™์•„์š”.
bindFunc1(5, 6, 7, 8); // { x: 1 } 5 6 7 8

// ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜ ๊ตฌํ˜„
var bindFunc2 = func.bind({ x: 1 }, 4, 5); // 4์™€ 5๋ฅผ ๋ฏธ๋ฆฌ ์ ์šฉ
bindFunc2(6, 7); // { x: 1 } 4 5 6 7
bindFunc2(8, 9); // { x: 1 } 4 5 8 9

2-4-2. name ํ”„๋กœํผํ‹ฐ


  1. bind ๋ฉ”์„œ๋“œ๋ฅผ ์ ์šฉํ•ด์„œ ์ƒˆ๋กœ ๋งŒ๋“  ํ•จ์ˆ˜๋Š” name ํ”„๋กœํผํ‹ฐ์— โ€˜boundโ€™ ๋ผ๋Š” ์ ‘๋‘์–ด๊ฐ€ ๋ถ™๋Š”๋‹ค.
    (์ถ”์ ํ•˜๊ธฐ๊ฐ€ ์‰ฌ์›€)
var func = function (a, b, c, d) {
	console.log(this, a, b, c, d);
};
var bindFunc = func.bind({ x:1 }, 4, 5);

// func์™€ bindFunc์˜ name ํ”„๋กœํผํ‹ฐ์˜ ์ฐจ์ด๋ฅผ ์‚ดํŽด๋ณด์„ธ์š”!
console.log(func.name); // func
console.log(bindFunc.name); // bound func

2-4-3. ์ƒ์œ„ ์ปจํ…์ŠคํŠธ์˜ this๋ฅผ ๋‚ด๋ถ€ํ•จ์ˆ˜๋‚˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ช…์‹œ์  ๋ฐ”์ธ๋”ฉ ์‚ฌ์šฉํ•˜๊ธฐ

1. ๋‚ด๋ถ€ํ•จ์ˆ˜

  1. ๋ฉ”์„œ๋“œ์˜ ๋‚ด๋ถ€ํ•จ์ˆ˜์—์„œ ๋ฉ”์„œ๋“œ์˜ this๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•
    (์ด์ „์—๋Š” ๋‚ด๋ถ€ํ•จ์ˆ˜์— this๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด self๋ฅผ ์ผ์—ˆ์Œ! ๊ทธ๊ฒƒ ์ฒ˜๋Ÿผ ํ•˜๋ฉด ๋จ)
var self = this;

var innerFunc2 = function() {
  console.log(self); // ๋‚ด๋ถ€ํ•จ์ˆ˜์— this ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด self ๋ณ€์ˆ˜ ๋”ฐ๋กœ ์ž‘์„ฑํ•ด ์‚ฌ์šฉ
}

innerFunc2();
  1. self ๋“ฑ์˜ ๋ณ€์ˆ˜๋ฅผ ํ™œ์šฉํ•œ ์šฐํšŒ๋ฒ•๋ณด๋‹ค call, apply, bind๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊น”๋”ํ•˜๊ฒŒ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅํ•˜
var obj = {
	outer: function() {
		console.log(this); // obj
		var innerFunc = function () {
			console.log(this);
		};

		// call์„ ์ด์šฉํ•ด์„œ ์ฆ‰์‹œ์‹คํ–‰ํ•˜๋ฉด์„œ this๋ฅผ ๋„˜๊ฒจ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค
		innerFunc.call(this); // obj
	}
};
obj.outer();
  1. bind ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„
var obj = {
	outer: function() {
		console.log(this);
		var innerFunc = function () {
			console.log(this);
		}.bind(this); // innerFunc์— this๋ฅผ ๊ฒฐํ•ฉํ•œ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ํ• ๋‹น
		innerFunc();
	}
};
obj.outer();

2. ์ฝœ๋ฐฑํ•จ์ˆ˜

  1. ์ฝœ๋ฐฑํ•จ์ˆ˜๋„ ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์—, ํ•จ์ˆ˜๊ฐ€ ์ธ์ž๋กœ ์ „๋‹ฌ๋  ๋•Œ๋Š” ํ•จ์ˆ˜ ์ž์ฒด๋กœ ์ „๋‹ฌํ•จ
    (this๊ฐ€ ์œ ์‹ค)
  2. bind๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด this๋ฅผ ์ž…๋ง›์— ๋งž๊ฒŒ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ
var obj = {
	logThis: function () {
		console.log(this);
	},
	logThisLater1: function () {
		// 0.5์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ์ถœ๋ ฅํ•ด์š”. ์ •์ƒ๋™์ž‘ํ•˜์ง€ ์•Š์•„์š”.
		// ์ฝœ๋ฐฑํ•จ์ˆ˜๋„ ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— this๋ฅผ bindํ•ด์ฃผ์ง€ ์•Š์•„์„œ ์žƒ์–ด๋ฒ„๋ ธ์–ด์š”!(์œ ์‹ค)
		setTimeout(this.logThis, 500);
	},
	logThisLater2: function () {
		// 1์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ์ถœ๋ ฅํ•ด์š”. ์ •์ƒ๋™์ž‘ํ•ด์š”.
		// ์ฝœ๋ฐฑํ•จ์ˆ˜์— this๋ฅผ bind ํ•ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .
		setTimeout(this.logThis.bind(this), 1000);
	}
};

obj.logThisLater1();
obj.logThisLater2();

2-5. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ ์˜ˆ์™ธ์‚ฌํ•ญ


  1. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์‹คํ–‰ ์ปจํ…์ŠคํŠธ ์ƒ์„ฑ ์‹œ, this๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๊ณผ์ •์ด ์ œ์™ธ๋œ๋‹ค.

  2. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—๋Š” this์˜ ํ• ๋‹น๊ณผ์ •(๋ฐ”์ธ๋”ฉ ๊ณผ์ •)์ด ์•„์— ์—†์œผ๋ฉฐ, ์ ‘๊ทผ ํ•˜๊ณ ์ž ํ•˜๋ฉด ์Šค์ฝ”ํ”„ ์ฒด์ธ์ƒ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด this์— ์ ‘๊ทผํ•˜๊ฒŒ ๋จ

  3. ๋”ฐ๋ผ์„œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ this์šฐํšŒํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Š” call, apply, bind๋ณด๋‹ค ๋” ํŽธ๋ฆฌํ•œ ๋ฐฉ๋ฒ•!

var obj = {
	outer: function () {
		console.log(this);
		var innerFunc = () => {
			console.log(this);
		};
		innerFunc();
	};
};
obj.outer();
profile
Always have hope๐Ÿ€ & constant passion๐Ÿ”ฅ

0๊ฐœ์˜ ๋Œ“๊ธ€