JS ๐Ÿจ์˜ ๋งˆ์Šคํ„ฐ ๊ฐœ์ฒด(3๋ถ€)

10213 ๋‹จ์–ด reactcodenewbiewebdevjavascript

์ƒ์„ฑ์ž๋ฅผ ์ƒˆ๋กœ์šด ๋ถˆ๊ฐ€์ง€๋ก ์ž๋กœ ๋งŒ๋“œ์„ธ์š” ๐Ÿ—๏ธ



User ํ•จ์ˆ˜์™€ ๊ฐ™์€ ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค ๋•Œ ํ˜ธ์ถœ์ž๋Š” new ์—ฐ์‚ฐ์ž๋กœ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๊ฐ€ ์ˆ˜์‹ ๊ธฐ๊ฐ€ ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ผ๊ณ  ๊ฐ€์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ์ฃผ๋ชฉํ•˜์„ธ์š”.

function User(name, passwordHash) {
  this.name = name;
  this.passwordHash = passwordHash;
}


ํ˜ธ์ถœ์ž๊ฐ€ new ํ‚ค์›Œ๋“œ๋ฅผ ์žŠ์–ด๋ฒ„๋ฆฐ ๊ฒฝ์šฐ ํ•จ์ˆ˜์˜ ์ˆ˜์‹ ์ž๋Š”
์ „์—ญ ๊ฐ์ฒด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

var u = User("baravelli", "d8b74df393528d51cd19980ae0aa028e");
u; // undefined
this.name; // "baravelli"
this.passwordHash; // "d8b74df393528d51cd19980ae0aa028e"


Not only does the function uselessly return undefined, it also disas-
trously creates (or modifies, if they happen to exist already) the global
variables name and passwordHash.



์‚ฌ์šฉ์ž ๊ธฐ๋Šฅ์ด ES5 ์—„๊ฒฉํ•œ ์ฝ”๋“œ๋กœ ์ •์˜๋œ ๊ฒฝ์šฐ ์ˆ˜์‹ ์ž๋Š”
๊ธฐ๋ณธ๊ฐ’์€ ์ •์˜๋˜์ง€ ์•Š์Œ:

function User(name, passwordHash) {
  "use strict";
  this.name = name;
  this.passwordHash = passwordHash;
}
var u = User("baravelli", "d8b74df393528d51cd19980ae0aa028e");
// error: this is undefined


In this case, the faulty call leads to an immediate error: The first line
of User attempts to assign to this.name, which throws a TypeError. So,
at least with a strict constructor function, the caller can quickly dis-
cover the bug and fix it.



๊ทธ๋Ÿฌ๋‚˜ ๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ ์‚ฌ์šฉ์ž ๊ธฐ๋Šฅ์€ ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๊ฒƒ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉ์‹œ
์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€๋งŒ ์ผ๋ฐ˜ ๊ธฐ๋Šฅ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ใ…
๋ณด๋‹ค ๊ฐ•๋ ฅํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์€ ์—ฐ๊ฒฐ ์—ญํ• ์„ ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์–ด๋–ป๊ฒŒ ๋ถˆ๋Ÿฌ๋„ ๊ตฌ์กฐ์ฒด. ์ด๊ฒƒ์„ ๊ตฌํ˜„ํ•˜๋Š” ์‰ฌ์šด ๋ฐฉ๋ฒ•์€
์ˆ˜์‹ ์ž ๊ฐ’์ด User์˜ ์ ์ ˆํ•œ ์ธ์Šคํ„ด์Šค์ธ์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

function User(name, passwordHash) {
  if (!(this instanceof User)) {
    return new User(name, passwordHash);
  }
  this.name = name;
  this.passwordHash = passwordHash;
}


์ด๋ ‡๊ฒŒ ํ•˜๋ฉด User ํ˜ธ์ถœ์˜ ๊ฒฐ๊ณผ๋Š” ํ•จ์ˆ˜ ๋˜๋Š” ์ƒ์„ฑ์ž๋กœ ํ˜ธ์ถœ๋˜๋Š”์ง€ ์—ฌ๋ถ€์— ๊ด€๊ณ„์—†์ด User.prototype ์—์„œ ์ƒ์†๋˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

let x = User("baravelli", "d8b74df393528d51cd19980ae0aa028e");
let y = new User("baravelli", "d8b74df393528d51cd19980ae0aa028e");
x instanceof User; // true
y instanceof User; // true


์ด ํŒจํ„ด์˜ ํ•œ ๊ฐ€์ง€ ๋‹จ์ ์€ ์ถ”๊ฐ€ ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ํ•„์š”ํ•˜๋ฏ€๋กœ ์•ฝ๊ฐ„ ๋” ๋น„์Œ‰๋‹ˆ๋‹ค. ๊ฐ€๋ณ€ ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑ์ž๋กœ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•œ ์ ์šฉ ๋ฉ”์„œ๋“œ์™€ ์ง์ ‘์ ์ธ ์œ ์‚ฌ์ ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋ณ€ ํ•จ์ˆ˜์—๋„ ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ์ข€ ๋” ์ด๊ตญ์ ์ธ ์ ‘๊ทผ ๋ฐฉ์‹์€ ES5Object.create๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

function User(name, passwordHash) {
  let self = this instanceof User ? this : Object.create(User.prototype);
  self.name = name;
  self.passwordHash = passwordHash;
  return self;
}


Object.create takes a prototype object and returns a new object that inherits from it. So when this version of User is called as a function, the result is a new object inheriting from User.prototype, with the name and passwordHash properties initialized.



Object.create๋Š” ES5์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ทผ์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋กœ์ปฌ ์ƒ์„ฑ์ž์™€ ์ธ์Šคํ„ด์Šคํ™”๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ด์ „ ํ™˜๊ฒฝ์—์„œ
์ƒˆ๋กœ์šด ๊ฒƒ์œผ๋กœ ๊ทธ๊ฒƒ์„ ing:

if (typeof Object.create === "undefined") {
  Object.create = function (prototype) {
    function C() {}
    C.prototype = prototype;
    return new C();
  };
}


Note that this only implements the single-argument version of Object.create. The real version also accepts an optional second argument that describes a set of property descriptors to define on the new object.



๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ด ์ƒˆ ๋ฒ„์ „์˜ ์‚ฌ์šฉ์ž๋ฅผ new๋กœ ํ˜ธ์ถœํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ฉ๋‹ˆ๊นŒ?
์ƒ์„ฑ์ž ์žฌ์ •์˜ ํŒจํ„ด ๋•๋ถ„์— ํ•จ์ˆ˜ ํ˜ธ์ถœ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ JavaScript๊ฐ€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ๋ช…์‹œ์  ๋ฐ˜ํ™˜์œผ๋กœ ์ƒˆ ํ‘œํ˜„์‹์˜ ๊ฒฐ๊ณผ๋ฅผ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ self๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ ์ƒˆ ํ‘œํ˜„์‹์˜ ๊ฒฐ๊ณผ๋Š” self๊ฐ€ ๋˜๋ฉฐ ์ด๋Š” ์ด์— ๋ฐ”์ธ๋”ฉ๋œ ๊ฐ์ฒด์™€ ๋‹ค๋ฅธ ๊ฐ์ฒด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

๊ธฐ์–ตํ•ด์•ผ ํ•  ๊ฒƒ๋“ค ๐Ÿง 


  • new ๋˜๋Š” Object.create ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž์‹ ์„ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜์—ฌ ํ˜ธ์ถœ์ž์˜ ๊ตฌ๋ฌธ์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๋Š” ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • ํ•จ์ˆ˜๊ฐ€ new๋กœ ํ˜ธ์ถœ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋Š” ๊ฒฝ์šฐ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ฌธ์„œํ™”ํ•˜์‹ญ์‹œ์˜ค.

  • ๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰ ์ด ๊ธฐ์‚ฌ์˜ ์„ธ ๋ฒˆ์งธ ๋ถ€๋ถ„์„ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰



    ๊ทธ๋ฆฌ๊ณ  ์ข‹์•„ํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์— ๋Œ€ํ•ด ๋” ๊นŠ์ด ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ์ฃผ๋ฌธํ˜• ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๊ธฐ ์œ„ํ•ด ์ œ ๊ฐœ์ธ ์ •๋ณดblog๋ฅผ ํ™•์ธํ•˜์„ธ์š”. ๐Ÿ˜‰์—์„œ๋„ ์ €๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค๐Ÿ˜ƒ.

    ์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ