λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

javascript/ES6

ES6 javascript 객체 : ν”„λ‘œν† νƒ€μž…(prototype), __proto__

728x90

javascriptλŠ” ν”„λ‘œν† νƒ€μž… 기반 언어이닀.->이λ₯Ό 기반으둜 ν™•μž₯κ³Ό μž¬μ‚¬μš©μ„±μ„ 높인닀.(like 클래슀)
ν”„λ‘œν†  νƒ€μž…μ˜ 사전적 의미 = 'μ›ν˜•'
객체의 ν”„λ‘œν† νƒ€μž…(μ›ν˜•)을 κ°€μ§€κ³  μƒˆλ‘œμš΄ κ°μ²΄λ₯Ό μƒμ„±ν•΄κ°€λŠ” ν”„λ‘œκ·Έλž˜λ° λ°©μ‹

 

μƒμ„±λœ κ°μ²΄λŠ” μžκΈ°μžμ‹ μ˜ ν”„λ‘œν† νƒ€μž…μ„ κ°–λŠ”λ‹€. -> μžκΈ° μžμ‹ μ΄ λ§Œλ“€μ–΄μ§€κ²Œ 된 μ›ν˜•을 μ•ˆλ‹€.
μ§€κΈˆμ€ javascriptμ—μ„œ 클래슀λ₯Ό μ§€μ›ν•˜κΈ° μ‹œμž‘ν–ˆμ§€λ§Œ,

μ›λž˜ μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν”„λ‘œν† νƒ€μž… 기반의 μ–Έμ–΄λ‘œ 객체의 ν™•μž₯κ³Ό μž¬μ‚¬μš©, 상속을 κ΅¬ν˜„ν–ˆλ‹€.

const animal={ name:'tiger' };
console.log(animal.name); //tiger

animal.birthday='20220101';
console.log(animal.birthday); //20220101
		
//속성이 μžˆλŠ”μ§€ μ—†λŠ”μ§€ μ²΄ν¬ν•˜λŠ” hasOwnProperty()λ©”μ„œλ“œ μ‚¬μš© - 'hasOwnProperty()'λŠ” Object(μ΅œμƒμœ„)객체의 λ©”μ„œλ“œ
console.log(animal.hasOwnProperty('birthday')); //true
console.log(animal.hasOwnProperty('country'));	//false

console.log(animal)
/*
{name: 'tiger', birthday: '20220101'}
birthday: "20220101"
name: "tiger"
[[Prototype]]: Object
*/
// 빈 객체도 ν”„λ‘œν† κ°μ²΄(Object)λ₯Ό κ°€μ§€κ³  μžˆλ‹€.
const aaa={}
console.log(aaa)
/*
{} 
[[Prototype]]: Object
*/
// hasOwnPropertyλ₯Ό animal() 객체에 μ •μ˜ν•˜λ©΄, λΆ€λͺ¨λ‘œ μ˜¬λΌκ°€μ§€ μ•Šκ³  μžκΈ°μžμ‹ μ˜ λ©”μ„œλ“œλ‘œμ„œ μ‚¬μš©
const animal={
    hasOwnProperty:function(){
        console.log("ν˜Έλž‘μ΄λ ")
    }
}

animal.hasOwnProperty(); //ν˜Έλž‘μ΄λ 

 

 

μžλ°”μŠ€ν¬λ¦½νŠΈ ν•¨μˆ˜μ˜ 내뢀와 κ°μ²΄κ°„μ˜ 관계

 

1. ν•¨μˆ˜κ°€ λ§Œλ“€μ–΄μ§€κ³  μˆ˜ν–‰μ΄ λ˜μ–΄μ§€λ©΄, λ‚΄λΆ€μ—μ„œλŠ” ν•¨μˆ˜ μžμ‹ κ³Ό 같은 μ΄λ¦„μ˜ 객체가 생성

( Fruit ν•¨μˆ˜ / Fruit ν”„λ‘œν† νƒ€μž… 객체 )

-> ν”„λ‘œν† νƒ€μž…μ— λ©”μ„œλ“œλ₯Ό μΆ”κ°€, λ¬Όλ‘  ν•¨μˆ˜μ—λ„ μΆ”κ°€ν•  μˆ˜ μžˆμœΌλ‚˜ λ©”λͺ¨λ¦¬ λ¬Έμ œλ‘œ ν”„λ‘œν† νƒ€μž…μ— μΆ”κ°€


2. Fruit ν•¨μˆ˜ λ©€λ²„λ‘œ prototype 속성이 생성

- λ‹€λ₯Έ 곳에 μƒμ„±λœ 같은 ν•¨μˆ˜ μ΄λ¦„μ˜ animal ν”„λ‘œν† νƒ€μž… 객체λ₯Ό 가리킴.(μ°Έμ‘°)

Fruit ν•¨μˆ˜ Fruit ν”„λ‘œν† νƒ€μž… 객체
+prototype --> Fruit ν”„λ‘œν† νƒ€μž… 객체(μ°Έμ‘°) + constructor --> Fruit ν•¨μˆ˜(μ°Έμ‘°)
+ grow()

이런 μƒν™©μΌλ•Œ "Fruit ν”„λ‘œν† νƒ€μž… 객체"λŠ”

μƒμ„±μž ν•¨μˆ˜μ™€ new μ—°μ‚°μžλ₯Ό ν†΅ν•΄μ„œ λ§Œλ“€μ–΄λ‚΄λŠ” λͺ¨λ“  객체의 μ›ν˜•μ΄ λ˜λŠ” 객체이닀. 

function Fruit(){}
let apple=new Fruit();
let banana= new Fruit();

console.log(apple);
console.log(banana);

  • μ΄λ ‡κ²Œ new μ—°μ‚°μžμ™€ μƒμ„±μž ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ κ°μ²΄ μƒμ„±μ‹œ κ° κ°μ²΄μ—λŠ”--> __proto__속성이 μžλ™μœΌλ‘œ μƒμ„±
  • 이 속성(__proto__)은 객체가 λ§Œλ“€μ–΄μ§ˆ 수 μžˆλ„λ‘ ν•΄ μ€€ μ›ν˜•μ„ 가리킴.--> "Fruit ν”„λ‘œν† νƒ€μž… 객체"λ₯Ό μˆ¨μ€ 링크둜 가리킨닀(μ°Έμ‘°) 

 

 

 

"Fruit ν”„λ‘œν† νƒ€μž… 객체"λŠ” apple, banana와 같은 κ°μ²΄λ“€μ˜ μ›ν˜•μ΄ λ˜λŠ” 객체.

--> apple, banana와 같은 객체듀은 "Fruit ν”„λ‘œν† νƒ€μž… 객체"에 접근이 κ°€λŠ₯ν•˜κ³ ,

"Fruit ν”„λ‘œν† νƒ€μž… 객체"에 멀버 ν•œ 개λ₯Ό μΆ”κ°€ν•˜λ©΄, μΆ”κ°€λœ 멀버λ₯Ό κ³΅μœ ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆλ‹€

//"ν”„λ‘œν† νƒ€μž… 객체"에 멀버 μΆ”κ°€ν•˜κΈ°
Fruit.prototype.Grow=function(){
    return "μ„±μž₯ν•œλ‹€";
}

console.log(apple.Grow());	//μ„±μž₯ν•œλ‹€.
console.log(banana.Grow());	//μ„±μž₯ν•œλ‹€.

λΆ€λͺ¨(μ›ν˜•)에 μžˆλŠ” Grow() λ©”μ„œλ“œλ₯Ό apple, banana 객체 λ‚΄μ—μ„œ μž¬μ •μ˜ν•˜λ©΄-> 이게 μ μš©λœλ‹€.

//apple 객체내에 Grow() λ©”μ„œλ“œ μΆ”κ°€
apple.Grow=function(){
    return "사과가 μ„±μž₯ν•œλ‹€"
}

console.log(apple.Grow());	//사과가 μ„±μž₯ν•œλ‹€.
console.log(banana.Grow());	//μ„±μž₯ν•œλ‹€.
//속성 μΆ”κ°€
apple.hasRed=true
console.log(apple.hasRed)	//true
console.log(banana.hasRed)	//undefined

멀버λ₯Ό μΆ”κ°€, μˆ˜μ •, μ‚­μ œ -->prototype 속성을 ν†΅ν•΄μ„œ 적용
멀버λ₯Ό μ½λŠ” 것 --> 객체λͺ… or ν•¨μˆ˜μ˜ prototype 속성을 ν†΅ν•΄μ„œ 접근이 κ°€λŠ₯

console.log(banana.Grow());		//μ„±μž₯ν•œλ‹€.
console.log(Fruit.prototype.Grow()); //μ„±μž₯ν•œλ‹€.

 

 

객체 μƒμ„±μ‹œ μƒμ„±μž μ•ˆμ—μ„œ λ©”μ„œλ“œλ₯Ό μ •μ˜ν•˜λ©΄, 객체λ₯Ό μƒμ„±ν• λ•Œλ§ˆλ‹€ λ©”μ„œλ“œλ„ μƒˆλ‘œ 생성됨 -> λ©”λͺ¨λ¦¬ λ‚­λΉ„

κ·ΈλŸ¬λ―€λ‘œ ν”„λ‘œν† νƒ€μž… 객체에 λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•˜λŠ”κ²Œ μ’‹μŒ.

function Add(x,y){
    this.x=x;
    this.y=y;
    this.plus=()=>{
        return this.x+this.y;
    }
}

let add1=new Add(100,20);
console.log(add1.plus()); //120
console.log(add1) // Add {x: 100, y: 20, plus: ƒ}

let add2=new Add(200,30);
let add3=new Add(300,40);
console.log(add2); // Add {x: 200, y: 30, plus: ƒ}
console.log(add3); // Add {x: 300, y: 40, plus: ƒ}

function Add2(x,y){
    this.x=x;
    this.y=y;
}

Add2.prototype.plus=function(){
    return this.x+this.y;
}

let newadd1=new Add2(100,20);
let newadd2=new Add2(200,30);

console.log(newadd1); // Add2 {x: 100, y: 20} - plus λ©”μ„œλ“œκ°€ μƒˆλ‘œ μƒμ„±λ˜μ§€ μ•ŠμŒ
console.log(newadd2); // Add2 {x: 200, y: 30}
console.log(newadd1.plus()); // 120
console.log(newadd2.plus()); // 230

 

 

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 객체 μ§€ν–₯ μ–Έμ–΄λ‘œ ν”„λ‘œν† νƒ€μž… 상속에 κΈ°λ°˜μ„ λ‘” OOP언어이닀. μ΅œκ·Όμ—μ•Ό 클래슀 문법이 μ§€μ›λ˜κΈ° μ‹œμž‘ν–ˆλ‹€.

 

μƒμ†μ˜ ν•„μš”μ„± - 1. μž¬μ‚¬μš©μ„± 2. ν™•μž₯μ„±

 

ν”„λ‘œν† νƒ€μž… 체인 = '__proto__' : μ›ν˜•(λΆ€λͺ¨)λ₯Ό 가리킴.

μžμ‹ κ°μ²΄κ°€ __proto__κ°€ κ°€λ¦¬ν‚€λŠ” λΆ€λͺ¨κ°μ²΄μ˜ λ©€λ²„(속성, λ©”μ„œλ“œ)λ₯Ό μ‚¬μš©ν•  μˆ˜ μžˆλ‹€.

__proto__속성이 κ°€λ¦¬ν‚€λŠ” 것을 λ°”κΏ€ 수 μžˆλŠ”κ°€? = μ›ν˜•(λΆ€λͺ¨)λ₯Ό λ°”κΏ€ 수 μžˆλŠ”κ°€? YES

let obj1={
    name:'주우재',
    age : 36,
    sayHi(){
        console.log("hi~ " + this.name);
    }
}

let obj2={
    name:"윀보미"
}

console.log(obj2) //{name: '윀보미'} Prototype은 Object(μ΅œμƒμœ„)객체

obj2.__proto__=obj1; // μ›ν˜•(λΆ€λͺ¨)λ°”κΎΈκΈ°
console.log(obj2); // {name: '윀보미'} Prototype은 Object(obj1)객체 - μ•„λž˜ 이미지 μ°Έκ³ 

 

빈 객체λ₯Ό μƒμ„±ν•œ 후에 __proto__속성에 μ›ν•˜λŠ” 객체(λΆ€λͺ¨, μ›ν˜•μ΄ 될)λ₯Ό ν• λ‹Ή

let obj3={}; //ν˜„μž¬ obj3의 μ›ν˜•(λΆ€λͺ¨)λŠ” Object(μ΅œμƒμœ„)
console.log(obj3); // 우츑 이미지 μ°Έκ³ 

obj3.__proto__=obj2;
console.log(obj3.hasOwnProperty()); // false
//μ΅œμƒμœ„ Objectλ₯Ό ν”„λ‘œν† νƒ€μž… 체인으둜 μ‚¬μš©ν•  수 μžˆλ‹€.

 

javascriptλŠ” "ν”„λ‘œν† νƒ€μž… 기반의 객체지ν–₯μ–Έμ–΄"

1. μžμ‹ μ—κ²Œ μ—†λŠ” νŠΉμ„±(속성, λ©”μ„œλ“œ)을 __proto__κ°€ κ°€λ¦¬ν‚€λŠ” μ›ν˜•(λΆ€λͺ¨)μ—κ²Œ κ°€μ Έμ˜¨λ‹€.
2. μ΄λ•Œ, λ§¨ ν•˜μœ„ μžμ‹ κ°μ²΄μ—μ„œλΆ€ν„° μˆœμ°¨μ μœΌλ‘œ μ—°κ²°λ˜μ–΄μžˆλŠ” μ›ν˜•을 μ°Ύμ•„κ°„λ‹€ ="ν”„λ‘œν† νƒ€μž… μ²΄μΈ"
3. ν”„λ‘œν† νƒ€μž… 체인을 μ‚¬μš©ν•΄μ„œ 객체의 νŠΉμ„±μ„ μ „νŒŒ ="ν”„λ‘œν† νƒ€μž… 상속"

console.log(obj3.name); // 윀보미
console.log(obj3.age); // 36
obj3.sayHi(); //hi~ 윀보미

 

객체의 ν”„λ‘œν† νƒ€μž…μ„ 좜λ ₯ν•˜λŠ” 방법은 2κ°€μ§€κ°€ μžˆλ‹€.

'__proto__' vs ' Object.getPrototypeOf() ' 

λ‘˜ λ‹€ μ™ λ§Œν•˜λ©΄ λ˜‘κ°™μ§€λ§Œ, κ°„ν˜Ή '__proto__' λŠ” μ§€μ›ν•˜μ§€ μ•ŠλŠ” λΈŒλΌμš°μ €κ°€ μ‘΄μž¬ν•œλ‹€κ³  ν•œλ‹€.

 

function A(){}
let obj=new A();

console.log(obj.__proto__); // {constructor: ƒ}
console.log(obj)
console.log(Object.getPrototypeOf(obj)); //{constructor: ƒ}



function B(){}
let obj2=new B();

console.log(obj2.__proto__===Object.getPrototypeOf(obj2)) //true

 

μƒμ„±μž ν•¨μˆ˜μ™€ λ‚΄λΆ€μ—μ„œ μ²˜λ¦¬λ˜λŠ” λ™μž‘λ“€

function Add(a,b){
    this.a=a;
    this.b=b;
}

Add.prototype.plus=function(){
    return this.a+this.b
}

const newobj = {}; // ν˜„μž¬ protoλŠ” Object(μ΅œμƒμœ„)
newobj.__proto__= Add.prototype;   //newobj의 protoλ₯Ό Add의 ν”„λ‘œν† νƒ€μž… 객체둜 λ°”κΏˆ.
console.log(newobj) // Add{}

Add.apply(newobj, [111,222]) //μΈμžκ°’λ“€μ„ ν•˜λ‚˜λ‘œ λ¬Άμ–΄μ„œ 적용
console.log(newobj) // Add {a: 111, b: 222}
console.log(newobj.plus()); // 333
function Animal(name, age){
    this.name=name;   
    this.age=age;
}
Animal.prototype.aaa=function(){
    console.log('aaa');
}

function Animal2(name, age){
    this.name=name;   
    this.age=age;
}
Animal2.prototype.bbb=function(){
    console.log('bbb');
}

let obj1=new Animal('tiger',20);
obj1.aaa();	// aaa

obj1.__proto__=Animal2.prototype;
obj1.bbb(); // bbb

μΈμŠ€ν„΄μŠ€κ°€ μ–΄λ–€ μƒμ„±μž ν•¨μˆ˜λ‘œ μƒμ„±λœ 것인지 μ°ΎκΈ°!

1. ν”„λ‘œν†  νƒ€μž… 객체λ₯Ό μ°Ύκ³ , 2. κ·Έ ν”„λ‘œν† νƒ€μž… 객체 μ•ˆμ˜ 'constructor'값을 확인

function A(){}
const testObj=new A();

console.log(testObj.constructor); // ƒ A(){}
console.log(A.prototype.__proto__)  // Object(μ΅œμƒμœ„)
console.log(A.prototype) // constructor: ƒ A()

testObj μΈμŠ€ν„΄μŠ€κ°€ A둜 μƒμ„±λœ 것인지 νŒλ³„ - instanceof μ—°μ‚°μž, isPrototypeOf μ—°μ‚°μž

console.log(testObj instanceof A) //true

 

 

 

 

μ—°μŠ΅λ¬Έμ œ

const housing={
    toilet:1,
    turnon() {
		console.log( "turn on.." );
	}
}

const apt = {
	color: "red",
	rooms: 4
};

const villa = {
	color: "black",
	rooms: 3
};

const oneroom = {
	color: "blue",
	rooms: 1
};

apt.__proto__=housing
villa.__proto__=housing
oneroom.__proto__=housing 

console.log(apt)
console.log(villa)
console.log(oneroom)

const ipark={
    name:'μ•„μ΄νŒŒν¬',
    rooms:5
}
ipark.__proto__=apt

console.log(ipark.name); //μ•„μ΄νŒŒν¬
console.log(ipark.rooms); //5
console.log(ipark.color); //red
console.log(ipark.toilet); //1
ipark.turnon(); // turn on..

μ•žμ„  예제λ₯Ό μƒμ„±μž ν•¨μˆ˜μ™€ newμ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜λŠ” 예제둜 μž‘μ„±ν•΄λ³΄μž!

const Housing=function(name, color, rooms){
    this.name=name;
    this.color=color;
    this.rooms=rooms;
}

Housing.prototype.toilet=1;
Housing.prototype.turnon=function(){
    console.log("turn on..")
}

const apt=new Housing('apt', 'red','4')
console.log(apt.name); //apt
console.log(apt.color); //red
console.log(apt.rooms); //4
console.log(apt.toilet); //1
apt.turnon(); //turn on..

const oneroom = new Housing('oneroom','white','1')
console.log(oneroom.name) //oneroom
console.log(oneroom.color) //white
console.log(oneroom.rooms) //1
console.log(oneroom.toilet) //1
oneroom.turnon(); //turn on..


const ipark=new Housing ('μ•„μ΄νŒŒν¬','blue','5');
console.log(ipark.name) //μ•„μ΄νŒŒν¬
console.log(ipark.color) //blue
console.log(ipark.rooms) //5
console.log(ipark.toilet) //1
ipark.turnon(); 

ipark.name="λ ˆλ―Έμ•ˆ"
console.log(ipark.name); //λ ˆλ―Έμ•ˆ
// μ™ΈλΆ€μ—μ„œ μ†μ‰½κ²Œ μˆ˜μ •μ΄ κ°€λŠ₯함. -> μˆ˜μ •μ΄ μ•ˆλ˜κ²Œλ” ν•˜λ €λ©΄..?!
728x90