๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
javascript/๐Ÿ“– study

[3์ฃผ์ฐจ ์Šคํ„ฐ๋””] 17์žฅ-์ƒ์„ฑ์ž ํ•จ์ˆ˜

by HomieKim 2022. 2. 14.

์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ

Object ์ƒ์„ฑ์ž ํ•จ์ˆ˜

  • new์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ Object ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋นˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•จ
  • Object ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์ด์™ธ์—๋„ String, Number, Boolean, Function, Array, Date, RegExp, Promise ๋“ฑ ๋นŒํŠธ์ธ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ œ๊ณต
// ๋นˆ ๊ฐ์ฒด์˜ ์ƒ์„ฑ
const person = new Object();

// ํ”„๋กœํผํ‹ฐ ์ถ”๊ฐ€
person.name = 'Lee';
person.sayHello = function () {
  console.log('Hi! My name is ' + this.name);
};

console.log(person); // {name: "Lee", sayHello: ฦ’}
person.sayHello(); // Hi! My name is Lee

// Function ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•œ Function ๊ฐ์ฒด(ํ•จ์ˆ˜) ์ƒ์„ฑ
const func = new Function('x', 'return x * x');
console.log(typeof func); // function
console.dir(func);        // ฦ’ anonymous(x)

// Array ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•œ Array ๊ฐ์ฒด(๋ฐฐ์—ด) ์ƒ์„ฑ
const arr = new Array(1, 2, 3);
console.log(typeof arr); // object
console.log(arr);        // [1, 2, 3]

// RegExp ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•œ RegExp ๊ฐ์ฒด(์ •๊ทœ ํ‘œํ˜„์‹) ์ƒ์„ฑ
const regExp = new RegExp(/ab+c/i);
console.log(typeof regExp); // object
console.log(regExp);        // /ab+c/i

// Date ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•œ Date ๊ฐ์ฒด ์ƒ์„ฑ
const date = new Date();
console.log(typeof date); // object
console.log(date);        // Mon May 04 2020 08:36:33 GMT+0900 (๋Œ€ํ•œ๋ฏผ๊ตญ ํ‘œ์ค€์‹œ)

์ƒ์„ฑ์ž ํ•จ์ˆ˜

  • ๋™์ผํ•œ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–๋Š” ๊ฐ์ฒด๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ์ƒ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ๋ฐฉ์‹์ด ๋น„ํšจ์œจ์  (์ฝ”๋“œ ์ค‘๋ณต)
  • ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์กฐ๊ฐ€ ๋™์ผํ•œ ๊ฐ์ฒด ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ƒ์„ฑ ๊ฐ€๋Šฅ
// ์ƒ์„ฑ์ž ํ•จ์ˆ˜
function Circle(radius) {
  // ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  this.radius = radius;
  this.getDiameter = function () {
    return 2 * this.radius;
  };
}

// ์ธ์Šคํ„ด์Šค์˜ ์ƒ์„ฑ
const circle1 = new Circle(5);  // ๋ฐ˜์ง€๋ฆ„์ด 5์ธ Circle ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
const circle2 = new Circle(10); // ๋ฐ˜์ง€๋ฆ„์ด 10์ธ Circle ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ

console.log(circle1.getDiameter()); // 10
console.log(circle2.getDiameter()); // 20

this๋Š” ๊ฐ์ฒด ์ž์‹ ์˜ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐธ์กฐํ•˜๊ธฐ ์œ„ํ•œ ์ž๊ธฐ ์ฐธ์กฐ ๋ณ€์ˆ˜

  • js ์—์„œ๋Š” ์ผ๋ฐ˜ ํ•จ์ˆ˜์™€ ๋™์ผํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์ •์˜
  • new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•˜๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ๋™์ž‘ (new์—†์œผ๋ฉด ์ผ๋ฐ˜ ํ•จ์ˆ˜)

์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๊ณผ์ •

  • ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์—ญํ•  : ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ, ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค ์ดˆ๊ธฐํ™”
  • ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์—์„œ ์ธ์Šคํ„ด์Šค ๊ฐ’ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์•„๋„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์ด ์•”๋ฌต์ ์œผ๋กœ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜
  • ์ƒ์„ฑ ๊ณผ์ •
  1. ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ๊ณผ this๋ฐ”์ธ๋”ฉ

๋ฐ”์ธ๋”ฉ ์ด๋ž€? ์‹๋ณ„์ž์™€ ๊ฐ’์„ ์—ฐ๊ฒฐํ•˜๋Š” ๊ณผ์ •, this ๋ฐ”์ธ๋”ฉ์ด๋ž€ this๊ฐ€ ๊ฐ€๋ฆฌํ‚ฌ ๊ฐ์ฒด๋ฅผ ๋ฐ”์ธ๋”ฉ ํ•˜๋Š” ๊ฒƒ
๋Ÿฐํƒ€์ž„ ์ด์ „์— ์•”๋ฌต์ ์œผ๋กœ ๋นˆ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  this์— ๋ฐ”์ธ๋”ฉ

  1. ์ธ์Šคํ„ด์Šค ์ดˆ๊ธฐํ™”

    ์ฝ”๋“œ ์‹คํ–‰ ์‹œ ์ดˆ๊ธฐํ™” ๋จ

  2. ์ธ์Šคํ„ด์Šค ๋ฐ˜ํ™˜

    ๋ฐ”์ธ๋”ฉ ๋œ this๊ฐ€ ์•”๋ฌต์ ์œผ๋กœ ๋ฐ˜ํ™˜
    ๋ช…์‹œ์ ์œผ๋กœ ๊ฐ์ฒด return this ๋ฐ˜ํ™˜ ๋ฌด์‹œ๋จ

๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ [[ Call ]] , [[ Construct ]]

  • ํ•จ์ˆ˜๋„ ๊ฐ์ฒด์ด๋ฏ€๋กœ ๋‚ด๋ถ€ ์Šฌ๋กฏ๊ณผ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํ•จ์ˆ˜์™€ ๊ฐ์ฒด ๋‹ค๋ฅธ์  : ์ผ๋ฐ˜ ๊ฐ์ฒด๋Š” ํ˜ธ์ถœ ๋ถˆ๊ฐ€๋Šฅ, ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” ํ˜ธ์ถœ ๊ฐ€๋Šฅ
  • ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” ์ผ๋ฐ˜ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€์Šฌ๋กฏ, ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ์— ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ์œ„ํ•œ ๋‚ด๋ถ€์Šฌ๋กฏ๊ณผ ๋‚ด๋ถ€๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์Œ
  • [[ Environment ]] , [[ Formal Parameters ]] : ํ•จ์ˆ˜ ๊ฐ์ฒด ์œ„ํ•œ ๋‚ด๋ถ€ ์Šฌ๋กฏ
  • [[ Call ]], [[ Construct ]] : ํ•จ์ˆ˜ ๊ฐ์ฒด ์œ„ํ•œ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ
  • ๋ชจ๋“  ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ [[ Call ]] ์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฏ€๋กœ ํ˜ธ์ถœ ๊ฐ€๋Šฅ
  • ๋ชจ๋“  ํ•จ์ˆ˜ ๊ฐ์ฒด๊ฐ€ [[ Construct ]] ๊ฐ€์ง€์ง€๋Š” ์•Š์Œ (= ์ƒ์„ฑ์ž ์ผ ์ˆ˜ ์žˆ๊ณ  ์•„๋‹ ์ˆ˜ ์žˆ๋‹ค.)
  • ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ [[ Call ]] ํ˜ธ์ถœ, new๋กœ ์ƒ์„ฑ์ž ํ˜ธ์ถœ ์‹œ [[ Construct ]] ํ˜ธ์ถœ

construct, non-construct ๊ตฌ๋ถ„

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง€์ด ํ•จ์ˆ˜ ์ •์˜๋ฅผ ํ‰๊ฐ€ํ•˜์—ฌ ๊ตฌ๋ถ„
  • construct : ํ•จ์ˆ˜ ์„ ์–ธ๋ฌธ, ํ•จ์ˆ˜ ํ‘œํ˜„์‹, ํด๋ž˜์Šค (= ์ผ๋ฐ˜ ํ•จ์ˆ˜)
  • non-construct : ๋ฉ”์„œ๋“œ, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜
  • ๋ฉ”์„œ๋“œ๋Š” ES6์˜ ๋ฉ”์„œ๋“œ ์ถ•์•ฝ ํ‘œํ˜„๋งŒ ๋ฉ”์„œ๋“œ๋กœ ์ธ์ •ํ•ฉ๋‹ˆ๋‹ค.

new ์—ฐ์‚ฐ์ž

  • new์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ [[ Construct ]] ํ˜ธ์ถœ ๋จ
  • new ์—†์ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ [[ Call ]]์ด ํ˜ธ์ถœ ๋จ
  • ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ [[ Call ]] ๋กœ ํ˜ธ์ถœ ์‹œ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this๋Š” ์ „์—ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
// new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.
// ์ฆ‰, ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋œ๋‹ค.
const circle3 = Circle(15);

// ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋œ Circle์€ ๋ฐ˜ํ™˜๋ฌธ์ด ์—†์œผ๋ฏ€๋กœ ์•”๋ฌต์ ์œผ๋กœ undefined๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
console.log(circle3); // undefined

// ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋œ Circle๋‚ด์˜ this๋Š” ์ „์—ญ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
console.log(radius); // 15

new.target

  • ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ new ์—†์ด ํ˜ธ์ถœ ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ์œ„ํ•ด ES6์—์„œ ๋„์ž…๋œ ํ”„๋กœํผํ‹ฐ, ๋ฉ”ํƒ€ ํ”„๋กœํผํ‹ฐ๋ผ๊ณ  ๋ถ€๋ฆ„
  • new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ new.target์€ ์ž๊ธฐ ์ž์‹  ๊ฐ€๋ฆฌํ‚จ๋‹ค. ๋ฐ˜๋Œ€๋Š” undefined
  • ์Šค์ฝ”ํ”„ ์„ธ์ดํ”„ ์ƒ์„ฑ์ž ํŒจํ„ด
// Scope-Safe Constructor Pattern
function Circle(radius) {
  // ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋˜๋ฉด ํ•จ์ˆ˜์˜ ์„ ๋‘์—์„œ ๋นˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ 
  // this์— ๋ฐ”์ธ๋”ฉํ•œ๋‹ค. ์ด๋•Œ this์™€ Circle์€ ํ”„๋กœํ† ํƒ€์ž…์— ์˜ํ•ด ์—ฐ๊ฒฐ๋œ๋‹ค.

  // ์ด ํ•จ์ˆ˜๊ฐ€ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์ด ์‹œ์ ์˜ this๋Š” ์ „์—ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  // ์ฆ‰, this์™€ Circle์€ ํ”„๋กœํ† ํƒ€์ž…์— ์˜ํ•ด ์—ฐ๊ฒฐ๋˜์ง€ ์•Š๋Š”๋‹ค.
  if (!(this instanceof Circle)) {
    // new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•˜์—ฌ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    return new Circle(radius);
  }

  this.radius = radius;
  this.getDiameter = function () {
    return 2 * this.radius;
  };
}

// new ์—ฐ์‚ฐ์ž ์—†์ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ๋„ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋œ๋‹ค.
const circle = Circle(5);
console.log(circle.getDiameter()); // 10

์ฐธ๊ณ 

  • ๋นŒํŠธ์ธ ๊ฐ์ฒด ์ค‘ Object, Function ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” new ์—†์–ด๋„ ๊ฐ™์€ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
  • String, Number, Boolean์€ newํ‚ค์›Œ๋“œ ์—†์œผ๋ฉด ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค๋ฆ„
const str = String(123);
console.log(str, typeof str); // 123 string

const num = Number('123');
console.log(num, typeof num); // 123 number

const bool = Boolean('true');
console.log(bool, typeof bool); // true boolean

const str = new String(123);
console.log(str, typeof str); // String {'123'} 'object'

const num = new Number('123');
console.log(num, typeof num); // Number {123} 'object'

const bool = new Boolean('true');
console.log(bool, typeof bool); // Boolean {true} 'object'

๋Œ“๊ธ€