๐Ÿ” [๋‹จ๊ณจ์งˆ๋ฌธ] - 02. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ this๋ž€?

์กฐ์ค€ํ˜•ยท2021๋…„ 6์›” 16์ผ
2

interview

๋ชฉ๋ก ๋ณด๊ธฐ
3/20
post-thumbnail
  • ex) ํ™”์‚ดํ‘œ ํ•จ์ˆ˜, call, bind, apply ๋“ฑ

๐Ÿ’ฌ Answer

๐ŸŒ ์—„๊ฒฉ๋ชจ๋“œ (Strict Mode)

this์— ๋Œ€ํ•ด ์ฐพ์•„๋ณด๋ฉด ์—„๊ฒฉ๋ชจ๋“œ์— ๋Œ€ํ•ด ๋งŽ์ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—„๊ฒฉ๋ชจ๋“œ๋ž€ ๋ฌด์—‡์ผ๊นŒ?
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๊ฝค ์˜ค๋žซ๋™์•ˆ ํ˜ธํ™˜์„ฑ ์ด์Šˆ ์—†์ด ๋ฐœ์ „ํ•ด์™”์Šต๋‹ˆ๋‹ค.
๊ธฐ์กด์˜ ๊ธฐ๋Šฅ์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์œผ๋ฉด์„œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋•๋ถ„์— ๊ธฐ์กด์— ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋Š” ์ ˆ๋Œ€ ๋ง๊ฐ€์ง€์ง€ ์•Š๋Š”๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฐฝ์‹œ์ž๋“ค์ด ํ–ˆ๋˜ ์‹ค์ˆ˜๋‚˜ ๋ถˆ์™„์ „ํ•œ ๊ฒฐ์ •์ด ์–ธ์–ด ์•ˆ์— ์˜์›ํžˆ ๋ฐ•์ œ๋œ๋‹ค๋Š” ๋‹จ์ ๋„ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์ƒˆ๋กญ๊ฒŒ ์ œ์ •๋œ ES5์—์„œ๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜๊ณ  ๊ธฐ์กด ๊ธฐ๋Šฅ ์ค‘ ์ผ๋ถ€๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด ๊ธฐ๋Šฅ์„ ๋ณ€๊ฒฝํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— ํ•˜์œ„ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ ๋ณ€๊ฒฝ์‚ฌํ•ญ ๋Œ€๋ถ€๋ถ„์€ ES5์˜ ๊ธฐ๋ณธ ๋ชจ๋“œ์—์„  ํ™œ์„ฑํ™”๋˜์ง€ ์•Š๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
๋Œ€์‹  use strict๋ผ๋Š” ํŠน๋ณ„ํ•œ ์ง€์‹œ์ž๋ฅผ ์‚ฌ์šฉํ•ด ์—„๊ฒฉ ๋ชจ๋“œ(strict mode)๋ฅผ ํ™œ์„ฑํ™” ํ–ˆ์„ ๋•Œ๋งŒ ์ด ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ํ™œ์„ฑํ™”๋˜๊ฒŒ ํ•ด๋†“์•˜์Šต๋‹ˆ๋‹ค.

์—„๊ฒฉ๋ชจ๋“œ
1. ๊ธฐ์กด์—๋Š” ์กฐ์šฉํžˆ ๋ฌด์‹œ๋˜๋˜ ์—๋Ÿฌ๋“ค์„ throwingํ•ฉ๋‹ˆ๋‹ค.
2.JavaScript ์—”์ง„์˜ ์ตœ์ ํ™” ์ž‘์—…์„ ์–ด๋ ต๊ฒŒ ๋งŒ๋“œ๋Š” ์‹ค์ˆ˜๋“ค์„ ๋ฐ”๋กœ์žก์Šต๋‹ˆ๋‹ค.
๊ฐ€๋”์”ฉ ์—„๊ฒฉ ๋ชจ๋“œ์˜ ์ฝ”๋“œ๊ฐ€ ๋น„-์—„๊ฒฉ๋ชจ๋“œ์˜ ๋™์ด๋ž—ใ„ด ์ฝ”๋“œ๋ณด๋‹ค ๋” ๋นจ๋ฆฌ ์ž‘๋™ํ•˜๋„๋ก ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค.
3. ECMAScript์˜ ์ฐจ๊ธฐ ๋ฒ„์ „๋“ค์—์„œ ์ •์˜ ๋  ๋ฌธ๋ฒ•์„ ๊ธˆ์ง€ํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋ฐฉ๋ฒ•
"use strict";(๋˜๋Š” 'use strict';) ์„ ๋‹ค๋ฅธ ๊ตฌ๋ฌธ ์ž‘์„ฑ ์ „์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.

// ์ „์ฒด ์Šคํฌ๋ฆฝํŠธ ์—„๊ฒฉ ๋ชจ๋“œ ๊ตฌ๋ฌธ
'use strict';
var v = "Hi!  I'm a strict mode script!";

// ํ•จ์ˆ˜์—์„œ strict mode ์ ์šฉ
function strict(){
// ํ•จ์ˆ˜-๋ ˆ๋ฒจ strict mode ๋ฌธ๋ฒ•
  'use strict';
  function nested() { return "And so am I!"; }
  return "Hi!  I'm a strict mode function!  " + nested();
}
function notStrict() { return "I'm not strict."; }

// module์—์„œ strict mode ์ ์šฉ
function strict() {
    // ๋ชจ๋“ˆ์ด๊ธฐ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ์ ์œผ๋กœ ์—„๊ฒฉํ•ฉ๋‹ˆ๋‹ค
}
export default strict;

๐ŸŒ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ this

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

-์ผ๋ฐ˜ ํ•จ์ˆ˜์—์„œ this๋Š” window ๊ฐ์ฒด
-event Listener์—์„œ๋Š” ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ ๊ฐ์ฒด
-๋ฉ”์†Œ๋“œ์—์„œ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด

์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๊ฒฐ์ •๋œ๋‹ค.
1. ํ•จ์ˆ˜์—์„œ์˜ this
2. ๋ฉ”์†Œ๋“œ์—์„œ์˜ this
3. ์ƒ์„ฑ์ž์—์„œ์˜ this
4. ๊ฐ์ฒด์—์„œ์˜ this
5. ๊ฐ„์ ‘ ์‹คํ–‰์—์„œ์˜ this
6. ๋ฐ”์ธ๋”ฉ ํ•จ์ˆ˜์—์„œ์˜ this
7. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—์„œ์˜ this

๐Ÿ‘‰ this์˜ ์ „์—ญ ๊ฐ์ฒด

๋ธŒ๋ผ์šฐ์ €์—์„œ this์˜ ์ „์—ญ๊ฐ์ฒด๋Š” window์ด๋‹ค.

๐Ÿ‘‰ ๋ฉ”์†Œ๋“œ ์—์„œ์˜ this

๋ฉ”์†Œ๋“œ์—์„œ์˜ this๋Š” ๋ฉ”์†Œ๋“œ ์‹คํ–‰๋•Œ ๋ฉ”์†Œ๋“œ๋ฅผ ์†Œ์œ ํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด.

๐Ÿ‘‰ ์ƒ์„ฑ์ž ์—์„œ์˜ this

์ƒ์„ฑ์ž๋Š” new ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์•ผํ•œ๋‹ค. new๋ฅผ ๋ถ™์ด์ง€ ์•Š์„ ์‹œ ์—๋Ÿฌ ๋ฐœ์ƒ!
ES6๋ถ€ํ„ฐ๋Š” class๋ฅผ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.
์ƒ์„ฑ์ž์—์„œ this

function person(_name, _age) {
    this.name = _name;
    this.age = _age;
}

/* Peson๊ฐ์ฒด ๋ฉ”์†Œ๋“œ ์ถ”๊ฐ€ */
person.prototype.changeName = function(newName) {
    this.name = newName;
}

// 1 
const p = new person('Youngjin', '22');
console.log(p.name); // Youngjin ์ด ์ถœ๋ ฅ
// 2 
p.changeName('Requiem');
console.log(p.name); // Requiem ์ด ์ถœ๋ ฅ

1์—์„œ ๊ฐ€๋ฆฌํ‚ค๋Š” this๋Š” ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์งˆ person์„ ๊ฐ€๋ฆฌํ‚ค๊ณ  p๊ฐ€ ๋งŒ๋“ค์–ด์งˆ ๋•Œ Youngjin๊ณผ 22๊ฐ€ ๋“ค์–ด์™€ p.name์€ p๊ฐ€ ๋งŒ๋“ค์–ด ์งˆ ๋•Œ ์ด๋ฆ„ Youngjin์ด ๋จ.

changeName๋ฉ”์†Œ๋“œ์—์„œ this๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š”๊ฒŒ ๋งŒ๋“ค์–ด์ง„ person์ด๋ผ p.changeName('Requiem')์„ ํ•˜๊ฒŒ๋˜๋ฉด ๋งŒ๋“ค์–ด์ง„ p์˜ ์ด๋ฆ„์ด Youngjin -> Requiem์œผ๋กœ ๋ณ€๊ฒฝ๋จ.

class์ƒ์„ฑ์ž์—์„œ์˜ this

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    changeName(newName) {
        this.name = newName;
    }
}

const p = new Person('Youngjin', '22');
console.log(p.name); // Youngjin ์ด ์ถœ๋ ฅ
p.changeName('Requiem');
console.log(p.name); // Requiem ์ด ์ถœ๋ ฅ

๐Ÿ‘‰ ๊ฐ์ฒด์—์„œ์˜ this

๊ฐ์ฒด์—์„œ์˜ this๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ด.

๐Ÿ‘‰ ๊ฐ„์ ‘ ์‹คํ–‰์—์„œ์˜ this

๊ฐ„์ ‘ ์‹คํ–‰์ด๋ž€ call(), apply()๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.
call()๋ฉ”์†Œ๋“œ๋Š” ์ฃผ์–ด์ง„ this๊ฐ’ ๋ฐ ๊ฐ๊ฐ ์ „๋‹ฌ๋œ ์ธ์ˆ˜์™€ ํ•จ๊ป˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•จ.
apply()๋ฉ”์†Œ๋“œ๋Š” ์ฃผ์–ด์ง„ this๊ฐ’๊ณผ ๋ฐฐ์—ด(๋˜๋Š” ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด)๋กœ ์ œ๊ณต๋˜๋Š” arguments๋กœ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•จ.

๋‘˜๋‹ค ์œ ์‚ฌํ•˜์ง€๋งŒ call()์€ ์ธ์ˆ˜ ๋ชฉ๋ก, apply()๋Š” ์ธ์ˆ˜ ๋ฐฐ์—ด์„ ๋ฐ›๋Š” ๊ฒƒ์ด ์ฐจ์ด.
๊ฐ„์ ‘ ์‹คํ–‰์—์„œ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ this

๐Ÿ‘‰ ๋ฐ”์ธ๋”ฉ ํ•จ์ˆ˜์—์„œ์˜ this

bind()๋ฉ”์†Œ๋“œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜๋ฉฐ bind()๋Š” ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š” ์—ญํ• ์„ ํ•จ.
strict mode์ผ๋•Œ ์•„๋‹ ๋•Œ ์ฐจ์ด๋ฅผ ๋ณด์ž„.

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

unboundGetX๋Š” ์ „์—ญ์—์„œ ํ˜ธ์ถœ์ด ๋˜์—ˆ๊ณ , boundGetX๋Š” module์˜ getX๋ฅผ ํ˜ธ์ถœํ•จ.

๐Ÿ‘‰ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—์„œ์˜ this

ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ๊ฐ„๋‹จํ•œ ํ˜•ํƒœ๋กœ ์ •์˜ํ•˜๊ฑฐ๋‚˜ ํ˜น์€ ๋ฌธ๋งฅ์„ ๋ฐ”์ธ๋“œ ํ•˜๊ธฐ ์œ„ํ•ด ์ฃผ๋กœ ์‚ฌ์šฉ๋จ.

let person = {
    name: "youngjin",
    getName: function () {
        console.log(this) // person ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค
        setTimeout(() => {
          console.log(this) // person๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค
          console.log(this.name); // youngjin ์„ ์ถœ๋ ฅํ•œ๋‹ค.
      }, 1000);
  }
}

person.getName();

๐Ÿ‘‰ ์ผ๋ฐ˜ํ•จ์ˆ˜์˜ this์™€ ํ™”์‚ดํ‘œํ•จ์ˆ˜์˜ this์˜ ์ฐจ์ด.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด๋ถ€ํ•จ์ˆ˜๋Š” ์ผ๋ฐ˜ํ•จ์ˆ˜, ๋ฉ”์†Œ๋“œ, ์ฝœ๋ฐฑํ•จ์ˆ˜ ์–ด๋””์„œ ์„ ์–ธ๋˜์—ˆ๋“ ์ง€ this๊ฐ€ ์ „์—ญ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ด.
์ผ๋ฐ˜ํ•จ์ˆ˜์˜ this๋Š” window(์ „์—ญ)์„ ๊ฐ€๋ฅดํ‚ค๋ฉฐ, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ this๋Š” ์–ธ์ œ๋‚˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ this๋ฅผ ๊ฐ€๋ฆฌํ‚ด.

๐Ÿ‘‰ Call, Apply, Bindํ•จ์ˆ˜์— ๋Œ€ํ•ด

3๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ this๋ฅผ ๋ฐ”์ธ๋”ฉ ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•.

  • Call() : this๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋ฉด์„œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ, ๋‘ ๋ฒˆ์งธ ์ธ์ž๋ฅผ ํ•˜๋‚˜์”ฉ ๋„˜๊ธฐ๋Š” ๊ฒƒ
  • Apply() : this๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋ฉด์„œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ, ๋‘ ๋ฒˆ์งธ ์ธ์ž๊ฐ€ ๋ฐฐ์—ด
  • bind() : ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ this๊ฐ€ ๋ฐ”์ธ๋”ฉ๋œ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•จ.

๐Ÿ‘‰ use strict๋ชจ๋“œ์—์„œ์˜ this

์ผ๋ฐ˜ ํ•จ์ˆ˜์—์„œ this๋Š” undefined๊ฐ€ ๋ฐ”์ธ๋”ฉ๋จ.

์ดํ•ด๊ฐ€ ํ•œ๋ฒˆ์— ์ž˜ ์•ˆ๋˜๋‹ˆ ์ž์ฃผ ์ฐพ์•„๋ด์•ผ๊ฒ ๋‹ค.

๐Ÿ“˜ ์ฐธ๊ณ 

https://ko.javascript.info/strict-mode
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Strict_mode
https://kkan0615.github.io/youngjin.github.io/javascript_this/#
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/call
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
https://sunnykim91.tistory.com/121

profile
๊นƒํ—ˆ๋ธŒ : github.com/JuneHyung

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