[TIL] 220111

dev·2022년 1ė›” 11ėž
0

TIL

ëŠĐ록 ëģīęļ°
146/204
post-thumbnail

📝 ė˜Ī늘 한 ęēƒ

  1. í”„ëĄœí† íƒ€ėž…

📚 ë°°ėšī ęēƒ

6. í”„ëĄœí† íƒ€ėž…

ėžë°”ėŠĪ큎ëĶ―íŠļ는 í”„ëĄœí† íƒ€ėž… ęļ°ë°˜ ė–ļė–īėīë‹Ī.
íī래ėŠĪ ęļ°ë°˜ ė–ļė–īė—ė„œëŠ” 'ėƒė†'ė„ ė‚ŽėšĐí•˜ė§€ë§Œ í”„ëĄœí† íƒ€ėž… ęļ°ë°˜ ė–ļė–īė—ė„œëŠ” ė–īë–Ī 객ėēīëĨž ė›í˜•ėœžëĄœ ė‚žęģ  ėīëĨž ëģĩ렜(ė°ļėĄ°)í•ĻėœžëĄœėĻ ėƒė†ęģž ëđ„ėŠ·í•œ íšĻęģžëĨž ė–ŧ는ë‹Ī.

1) í”„ëĄœí† íƒ€ėž…ė˜ 개념 ėīí•ī

(1) constructor, prototype, instance

prototype / __proto__

ė–īë–Ī ėƒė„ąėž í•Ļ눘ëĨž new ė—°ė‚°ėžė™€ í•Ļęŧ˜ í˜ļėķœí•˜ëĐī
ėƒė„ąėž í•Ļėˆ˜ė— ė •ė˜ëœ ë‚īėšĐė„ ë°”íƒ•ėœžëĄœ ėƒˆëĄœėšī ėļėŠĪí„īėŠĪ가 ėƒė„ąëœë‹Ī.

ėī때 ėļėŠĪí„īėŠĪė—ëŠ” __proto__띾는 (ėƒëžĩ 가ëŠĨ한) 프로퍾티가 ėžë™ėœžëĄœ ëķ€ė—Žë˜ëŠ”ë°
ėī 프로퍾티는 ėƒė„ąėž í•Ļėˆ˜ė˜ prototypeėī띾는 프로퍾티ëĨž ė°ļėĄ°í•œë‹Ī.

ė—Žęļ°ė„œ prototypeė€ 객ėēīėīęģ , ėīëĨž ė°ļėĄ°í•˜ëŠ” __proto__ ė—­ė‹œ 객ėēīėīë‹Ī.
prototype 객ėēī ë‚īëķ€ė— ėļėŠĪí„īėŠĪ가 ė‚ŽėšĐ할 눘 ėžˆëŠ” ëĐ”ė„œë“œëĨž ė €ėžĨ하ëĐī
ėļėŠĪí„īėŠĪė—ė„œëŠ” __proto__ëĨž í†ĩí•ī ėī ëĐ”ė„œë“œė— ė ‘ę·ží•  눘 ėžˆęēŒ ëœë‹Ī.

ė‹ĪëŽīė—ė„œëŠ” 가ęļ‰ė  __proto__ ëŒ€ė‹  Object.getPrototypeOf() í˜đė€ Object.create()ëĨž ėīėšĐ하도록 한ë‹Ī.

ėƒëžĩ 가ëŠĨ한 프로퍾티 __proto__

var Person = function (name) {
  this._name = name;
};

Person.prototype.getName = function () {
  return this._name;
}

var suzi = new Person("Suzi");
suzi.__proto__.getName(); // undefined

suzi.__proto__.getName()가 undefinedëĨž return 했ë‹Ī.
ėī는 getName()ė€ ëĐ”ė„œë“œėļ데 ëĐ”ė„œë“œëŠ” í˜ļėķœ ė‹œ ëĐ”ė„œë“œëŠ… 바로 ė•žė˜ 객ėēī가 ęģ§ this가 되ęļ° ë•ŒëŽļėīë‹Ī.
ėī ęē―뚰 suzi.__proto__가 this가 되는데 ėī 객ėēīė—ëŠ” _name 프로퍾티가 ėĄīėžŽí•˜ė§€ ė•Šęļ° ë•ŒëŽļ뗐 undefined가 반환된 ęēƒėīë‹Ī.

suzi.getName(); // Suzi

__proto__는 ėƒëžĩ 가ëŠĨ한 프로퍾티ėīęļ° ë•ŒëŽļ뗐 ėœ„ė™€ 같ėī ėž‘ė„ąí•˜ëĐī Suzi ę°’ė„ ė–ŧė„ 눘 ėžˆë‹Ī.
suzi.__proto__ė˜ getName ëĐ”ė„œë“œëĨž ė‚ŽėšĐ하ëĐīė„œë„ getName ëĐ”ė„œë“œ ė•ˆė—ė„œė˜ this가 suzi.__proto__가 ė•„ë‹ˆëž suziëĨž 가ëĶŽí‚Ī도록 하는 ęēƒėīë‹Ī.
__proto__는 ėƒëžĩ 가ëŠĨ한 프로퍾티ėīęļ° ë•ŒëŽļ뗐 ėƒė„ąėž í•Ļėˆ˜ė˜ prototype뗐 ė–īë–Ī ëĐ”ė„œë“œë‚˜ 프로퍾티가 ėžˆë‹ĪëĐī, ėļėŠĪí„īėŠĪė—ė„œë„ 마ėđ˜ ėžė‹ ė˜ ęēƒėē˜ëŸž í•īë‹đ ëĐ”ė„œë“œë‚˜ í”„ëĄœíží‹°ė— ė ‘ę·ží•  눘 ėžˆęēŒ ëœë‹Ī.

큎륎 ę°œë°œėž 도ęĩŽëĄœ ė‚īíŽīëģīęļ°

var arr = [1, 2];
console.dir(arr);
console.dir(Array);

ė–īë–Ī ėƒė„ąėž í•Ļėˆ˜ė˜ ėļėŠĪí„īėŠĪ는 í•īë‹đ ėƒė„ąėž í•Ļėˆ˜ė˜ ėīëĶ„ė„ 표ęļ°í•ĻėœžëĄœėĻ í•īë‹đ í•Ļėˆ˜ė˜ ėļėŠĪí„īėŠĪėž„ė„ 표ęļ°í•œë‹Ī. ex) Array(2), Constructor(name) 등
ėƒė„ąėž í•Ļėˆ˜ė˜ prototypeęģž ėļėŠĪí„īėŠĪė˜ __proto__가 ë™ėží•œ ęēƒė„ 확ėļ할 눘 ėžˆë‹Ī. (ėą… ė°ļęģ )

한íŽļ, ėķœë Ĩ ęē°ęģžė—ė„œ ė§™ė€ėƒ‰ė€ ė—īęą° 가ëŠĨ한 프로퍾티, ė͉ for in ë“ąėœžëĄœ 객ėēīė˜ 프로퍾티 ė „ėēī뗐 ė ‘ę·ží•˜ęģ ėž 할 때 ė ‘ę·ž 가ëŠĨ한 프로퍾티ëĨž 말한ë‹Ī.

(2) constructor 프로퍾티

ėƒė„ąėž í•Ļėˆ˜ė˜ 프로퍾티ėļ prototype 객ėēī ë‚īëķ€ė—ëŠ” constructor띾는 프로퍾티가 ėžˆë‹Ī.
ėƒė„ąėž í•Ļėˆ˜ė˜ prototype 프로퍾티ëĨž ė°ļėĄ°í•˜ëŠ” ėļėŠĪí„īėŠĪė˜ __proto__ 객ėēī ë‚īëķ€ė—ë„ ë§ˆė°Žę°€ė§€ėīë‹Ī.
constructor 프로퍾티는 ë‹Ļė–ī ę·ļ대로 ė›ëž˜ė˜ ėƒė„ąėž í•Ļ눘ëĨž ė°ļėĄ°í•˜ëŠ” ęēƒėœžëĄœ ėļėŠĪí„īėŠĪ로ëķ€í„° ę·ļ ė›í˜•ėī ëŽīė—‡ėļė§€ëĨž ė•Œ 눘 ėžˆëŠ” 눘ë‹Ļėīë‹Ī.

var arr = [1, 2];

var arr2 = arr.constructor(3, 4);
console.log(arr2); // [3, 4]

한íŽļ, constructor는 ė―ęļ° ė „ėšĐ ė†ė„ąėī ëķ€ė—Žëœ 똈ė™ļ렁ėļ ęē―뚰(ęļ°ëģļ형 ëĶŽí„°ëŸī ëģ€ėˆ˜ - number, string, boolean)ëĨž 렜ė™ļ하ęģ ëŠ” ę°’ė„ 바ęŋ€ 눘 ėžˆë‹Ī.
ę·ļ런데 constructorė˜ ę°’ė„ 바ęŋ”도 ėīëŊļ 만ë“Īė–īė§„ ėļėŠĪí„īėŠĪė˜ ė›í˜•ėī 바뀌거나 데ėī터 íƒ€ėž…ėī ëģ€í•˜ė§€ëŠ” ė•ŠëŠ”ë‹Ī.
ė͉, constructorëĨž ëģ€ęē―하더띾도 ę·ļė € ė°ļėĄ°í•˜ëŠ” ëŒ€ėƒėī ëģ€ęē―될 ëŋėīëŊ€ëĄœ ė–īë–Ī ėļėŠĪí„īėŠĪė˜ ėƒė„ąėž ė •ëģīëĨž ė•Œė•„ë‚īęļ° ėœ„í•ī constructor 프로퍾티ëĨž ė‚ŽėšĐ하는 ęēƒėī í•­ėƒ ė•ˆė „í•˜ė§€ëŠ” ė•Šė€ ęēƒėīë‹Ī.

var Person = function (name) {
  this.name = name;
}

var p1 = new Person("ė‚ŽëžŒ1");
var p1Proto = Object.getPrototypeOf(p1);
var p2 = new p1Proto.constructor("ė‚ŽëžŒ2");

p1ęģž p2는 ëŠĻ두 Personė˜ ėļėŠĪí„īėŠĪ가 된ë‹Ī.

2) í”„ëĄœí† íƒ€ėž… ėēīėļ

(1) ëĐ”ė„œë“œ ė˜Īëē„띞ėī드

ė•žė„œ ė‚īíŽīëģļ ęēƒėē˜ëŸž prototype 객ėēīëĨž ė°ļėĄ°í•˜ëŠ” __proto__ëĨž ėƒëžĩ하ëĐī ėļėŠĪí„īėŠĪ는 prototype뗐 ė •ė˜ëœ 프로퍾티나 ëĐ”ė„œë“œëĨž ėžė‹ ė˜ ęēƒėē˜ëŸž ė‚ŽėšĐ할 눘 ėžˆë‹Ī.
한íŽļ, ėļėŠĪí„īėŠĪ가 prototype 객ėēī뗐 ė •ė˜ëœ 프로퍾티 또는 ëĐ”ė„œë“œė™€ ë™ėží•œ ėīëĶ„ė˜ 프로퍾티 또는 ëĐ”ė„œë“œëĨž 氀맀ęģ  ėžˆëŠ” ęē―ėš°ė—ëŠ” ëĐ”ė„œë“œ ė˜Īëē„띞ėī드가 ë°œėƒí•œë‹Ī.
ëĐ”ė„œë“œ ė˜Īëē„띞ėī드란 뛐ëģļ ëĐ”ė„œë“œę°€ ę·ļ대로 ėžˆëŠ” ėƒíƒœė—ė„œ ë‹ĪëĨļ ëĐ”ė„œë“œëĨž ę·ļ ėœ„ė— ëŪė–īė”Œėš°ëŠ” ęēƒė„ 말한ë‹Ī.

var Person = function (name) {
  this.name = name;
}

Person.prototype.getName = function (name) {
  return this.name
}

var iu = new Person("ė§€ęļˆ");
iu.getName = function () {
  return "바로" + this.name;
};

console.log(iu.getName()); // 바로 ė§€ęļˆ(o), ė§€ęļˆ(x)

iu.__proto__.getNameėī ė•„ë‹Œ iu 객ėēī뗐 ėžˆëŠ” getName ëĐ”ė„œë“œę°€ í˜ļėķœëœ ęēƒė„ 확ėļ할 눘 ėžˆë‹Ī.
ėī는 ėžë°”ėŠĪ큎ëĶ―íŠļ 뗔맄ėī ëĐ”ė„œë“œëĨž ė°ūė„ 때 ėš°ė„  가ėžĨ 가ęđŒėšī ëŒ€ėƒėļ iu 객ėēī ėžė‹ ė˜ 프로퍾티ëĨž ęē€ėƒ‰í•˜ęģ , ė—†ėœžëĐī ę·ļ ë‹ĪėŒėœžëĄœ 가ęđŒėšī ëŒ€ėƒėļ __proto__ëĨž ęē€ėƒ‰í•˜ęļ° ë•ŒëŽļėīë‹Ī.

ëĐ”ė„œë“œ ė˜Īëē„띞ėīë”Đėī ėīëĢĻė–īė ļ ėžˆëŠ” 냁í™Đė—ė„œ prototype뗐 ėžˆëŠ” ëĐ”ė„œë“œė— ė ‘ę·ží•˜ë ĪëĐī call ëĐ”ė„œë“œëĨž ėīėšĐí•ī getName ëĐ”ė„œë“œ ë‚īëķ€ė—ė„œė˜ thisëĨž iu.__proto__ 객ėēīė—ė„œ iu 객ėēī로 바ęŋ”ėĪ˜ė•ž 한ë‹Ī.

iu.__proto__.getName(); // undefined
iu.__proto__.getName.call(iu); // ė§€ęļˆ

(2) í”„ëĄœí† íƒ€ėž… ėēīėļ

큎륎 ę°œë°œėž 도ęĩŽė˜ ėķœë Ĩ ęē°ęģžëĨž ë‹Īė‹œ ė‚īíŽīëģīëĐī, ë°°ė—ī ėļėŠĪí„īėŠĪė˜ 프로퍾티ėļ __proto__ 객ėēī ė•ˆė— 또 ë‹Īė‹œ __proto__ 프로퍾티가 ėžˆëŠ” ęēƒė„ 확ėļ할 눘 ėžˆë‹Ī.
ėī는 prototype 객ėēī 또한 말 ę·ļ대로 '객ėēī'ėīęļ° ë•ŒëŽļėīë‹Ī.
ęļ°ëģļė ėœžëĄœ ëŠĻ든 객ėēīė˜ __proto__ė—ëŠ” Object.prototypeėī ė—°ęē°ëœë‹Ī.

var arr = [1, 2];
arr(.__proto__).push(3);
arr(.__proto__)(.__proto__).hasOwnProperty(2); // true

ë”°ëžė„œ, ėļėŠĪí„īėŠĪ는 ę·ļ ėļėŠĪí„īėŠĪė˜ ėƒė„ąėž í•Ļėˆ˜ė˜ prototypeė˜ ëĐ”ė„œë“œëŋ ė•„ë‹ˆëž Object.prototypeė˜ ëĐ”ė„œë“œë„ ėžė‹ ė˜ ęēƒėē˜ëŸž ė‚ŽėšĐ할 눘 ėžˆë‹Ī.
ėƒëžĩ 가ëŠĨ한 __proto__ëĨž 한 ëēˆ ë” 따띾가ëĐī Object.prototypeė„ ė°ļėĄ°í•  눘 ėžˆęļ° ë•ŒëŽļėīë‹Ī.

ėīėē˜ëŸž ė–īë–Ī 데ėīí„°ė˜ __proto__ 프로퍾티 ë‚īëķ€ė— ë‹Īė‹œ __proto__ 프로퍾티가 ė—°ė‡„ė ėœžëĄœ ėīė–īė§„ ęēƒė„ í”„ëĄœí† íƒ€ėž… ėēīėļėī띞ęģ  í•œë‹Ī.
ėī ėēīėļė„ 따띾가ëа ęē€ėƒ‰í•˜ëŠ” ęēƒė„ í”„ëĄœí† íƒ€ėž… ėēīėī닝ėī띞ęģ  í•œë‹Ī.

var arr = [1, 2];
Array.prototype.toString.call(arr); // 1,2
Object.prototype.toString.call(arr); // [ object Array ]
arr.toString(); // 1,2

arr.toString = function () {
  return this.join("_");
};
arr.toString(); // 1_2

// cf. Object.prototype.toString() ė€ ė‚ŽėšĐėž 맀렕 객ėēīė—ė„œ ėžŽė •ė˜ë˜ė§€ ė•ŠėœžëĐī [ object type ]ė„ return 한ë‹Ī.

(3) 객ėēī ė „ėšĐ ëĐ”ė„œë“œė˜ 똈ė™ļė‚Ží•­

ė–īë–Ī ėƒė„ąėž í•Ļ눘ėī든 prototypeė€ ë°˜ë“œė‹œ 객ėēīėīęļ° ë•ŒëŽļ뗐 Object.prototypeėī ė–ļė œë‚˜ í”„ëĄœí† íƒ€ėž… ėēīėļė˜ ėĩœėƒë‹Ļ뗐 ėĄīėžŽí•œë‹Ī.
ë”°ëžė„œ 객ėēīė—ė„œë§Œ ė‚ŽėšĐ할 ëĐ”ė„œë“œëŠ” ë‹ĪëĨļ ė—ŽëŠ 데ėī터 íƒ€ėž…ėē˜ëŸž í”„ëĄœí† íƒ€ėž… 객ėēī ė•ˆė— ė •ė˜í•  눘 ė—†ë‹Ī.
객ėēīė—ė„œë§Œ ė‚ŽėšĐ할 ëĐ”ė„œë“œëĨž 객ėēī가 ė•„ë‹Œ 데ėī터 íƒ€ėž…ė— ė‚ŽėšĐ하ëĐī ė˜ĪëĨ˜ëĨž ë˜ė§€ë„ëĄ í•īė•ž 하는데 Object.prototypeė€ ė–ļė œë‚˜ ëŠĻ든 í”„ëĄœí† íƒ€ėž… ėēīėļė˜ ėĩœėƒë‹Ļ뗐 ėĄīėžŽí•˜ęļ° ë•ŒëŽļ뗐 ė–īë–Ī 데ėī터 íƒ€ėž…ėīęąī ęą°ė˜ ëŽīėĄ°ęąī í”„ëĄœí† íƒ€ėž… ėēīėīë‹ė„ í†ĩí•ī í•īë‹đ ëĐ”ė„œë“œė— ė ‘ę·ží•  눘 ėžˆęēŒ ë˜ęļ° ë•ŒëŽļėīë‹Ī.
ėī ę°™ė€ ėīėœ ëĄœ 객ėēī ė „ėšĐ ëĐ”ė„œë“œë“Īė€ Object.prototypeėī ė•„ë‹ˆëž Object뗐 ėŠĪ태틱 ëĐ”ė„œë“œëĄœ ëķ€ė—Žë˜ė–ī ėžˆë‹Ī. ex) Object.freeze(instance) (o) / instance.freeze() (x)
반대로 Object.prototypeė—ëŠ” ė–īë–Ī 데ėīí„°ė—ė„œë„ 활ėšĐ할 눘 ėžˆëŠ” ëē”ėšĐ렁ėļ ëĐ”ė„œë“œë“Ī만 ėĄīėžŽí•œë‹Ī.

똈ė™ļė ėœžëĄœ Object.createëĨž ėīėšĐ하ëĐī Object.prototypeė˜ ëĐ”ė„œë“œė— ė ‘ę·ží•  눘 ė—†ëŠ” ęē―ėš°ë„ ėžˆë‹Ī.
Object.create(null)ė€ __proto__가 ė—†ëŠ” 객ėēīëĨž ėƒė„ąí•œë‹Ī.

var _proto = Object.create(null);
_proto.getValue = function (key) {
  return this[key];
};

var obj = Object.create(_proto);
obj.a = 1;

console.log(obj.getValue("a")); // 1
console.dir(obj);
// Ojbect
//   a: 1
//   __proto__:
//     getValue: f (key)

objė˜ __proto__ė—ëŠ” getValue ëĐ”ė„œë“œë§Œ ėĄīėžŽí•  ëŋ __proto__ 및 constructor 프로퍾티가 ėĄīėžŽí•˜ė§€ ė•ŠëŠ”ë‹Ī.
ėī렇ęēŒ ë§Œë“Īė–īė§„ 객ėēī는 ėžë°˜ė ėļ 데ėīí„°ė—ė„œ ë°˜ë“œė‹œ ėĄīėžŽí•˜ë˜ ë‚īėžĨ ëĐ”ė„œë“œ 및 프로퍾티ë“Īėī ė œęą°ë˜ė–ī ęļ°ëģļ ęļ°ëŠĨ뗐 ė œė•―ė€ ėƒęēžė§€ë§Œ 객ėēī ėžėēīė˜ ëŽīęēŒę°€ 가ëēžė›Œė ļ ė„ąëŠĨė„ą ėīė ė„ 氀맄ë‹Ī.

(4) ë‹ĪėĪ‘ í”„ëĄœí† íƒ€ėž… ėēīėļ

ëŒ€ę°ė„ ė˜ __proto__ëĨž ė—°ęē°í•ī나가ęļ°ë§Œ 하ëĐī ëŽī한대로 í”„ëĄœí† íƒ€ėž… ėēīėļ ęī€ęģ„ëĨž ėīė–ī나갈 눘 ėžˆë‹Ī.
__proto__가 ė°ļėĄ°í•˜ëŠ” ëŒ€ėƒ(ė͉, ėƒė„ąėž í•Ļėˆ˜ė˜ prototype)ėī, ė—°ęē°í•˜ęģ ėž 하는 'ėƒėœ„ ėƒė„ąėž í•Ļėˆ˜ė˜ ėļėŠĪí„īėŠĪ'ëĨž 바띾ëģī도록 í•īėĢžëĐī 된ë‹Ī.

var Grade = function () {
  var args = Array.prototype.slice.call(arguments);
  for (var i = 0; i < arguments.length; i++) {
    this[i] = args[i];
  }
  this.length = args.length;
};

var g = new Grade(100, 80);

ëģ€ėˆ˜ gė—ëŠ” Grade ėƒė„ąėž í•Ļėˆ˜ė˜ ėļėŠĪí„īėŠĪ가 ë‹īęēĻ ėžˆëŠ”ë°, ėī는 ėœ ė‚Žë°°ė—ī객ėēīėīë‹Ī.
ėœ ė‚Žë°°ė—ī객ėēī뗐 ë°°ė—ī ëĐ”ė„œë“œëĨž 렁ėšĐ하ë Īęģ  í•œë‹Ī.

ėēŦ ëēˆėžŽ ë°Đëē•ėœžëĄœ call/apply ëĐ”ė„œë“œëĨž ė‚ŽėšĐ할 눘 ėžˆë‹Ī.

var arr2 = Array.prototype.push.call(g, 60);
console.log(arr2); // [100, 80, 60]

두 ëēˆė§ļ ë°Đëē•ėœžëĄœ ė•„ė˜ˆ ėļėŠĪí„īėŠĪė—ė„œ ë°°ė—ī ëĐ”ė„œë“œëĨž 링렑 ė“ļ 눘 ėžˆęēŒë” 할 눘 ėžˆë‹Ī.
ėī ęē―뚰 ë°°ė—ī ëĐ”ė„œë“œëĨž ė‚ŽėšĐ하ęļ° ėœ„í•ī ė—°ęē°ėī í•„ėš”í•œ ėƒėœ„ ėƒė„ąėž í•Ļėˆ˜ëŠ” Array() ėīëŊ€ëĄœ ë‹ĪėŒęģž ę°™ė€ ė―”ë“œëĨž ėķ”ę°€í–ˆë‹Ī.
ėƒė„ąėž í•Ļ눘 Gradeė˜ prototypeėī ë°°ė—īė˜ ėļėŠĪí„īėŠĪëĨž 바띾ëģī도록 한 ęēƒėīë‹Ī.

var Grade = function () {
  var args = Array.prototype.slice.call(arguments);
  for (var i = 0; i < arguments.length; i++) {
    this[i] = args[i];
  }
  this.length = args.length;
};

Grade.prototype = []; // ėļėŠĪí„īėŠĪ ėƒė„ą 렄뗐 ėķ”ę°€í•īė•ž 한ë‹Ī

var g = new Grade(100, 80);

g.pop();
console.log(g); // Grade(1) [100]

âœĻ ë‚īėž 할 ęēƒ

  1. íī래ėŠĪ
profile
dev log

0ę°œė˜ 댓ęļ€