[TIL] 220111

Lee Syong·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
ëŠĨ동ė ėœžëĄœ ė‚īėž, 행ëģĩ하ęēŒðŸ˜

0개ė˜ 댓ęļ€