본문 바로가기
javascript

Prototype method vs Object method

by rami_ 2022. 2. 27.

Object에서 생성시점에 Method를 선언하는 방법.

1. 객체 생성자 내부에서 this.func = function ()  {}

2. obj.prototype.func = function () {} 과 같이 prototype을 이용하는것.

 

1. Prototype

상속(inheritance)은 객체지향 프로그래밍의 핵심 개념으로, 어떤 객체의 프로퍼티 또는 메서드를 상속받아 그대로 사용할 수 있는것

자바스크립트는 프로토타입을 기반으로 상속을 구현하여 불필요한 중복을 제거함. 중복을 제거하는 방법은 기존의 코드를 적극적으로 재사용하는것.

function Circle(radius) {
  this.radius = radius;
  this.getArea = function () {
    return Math.PI * this.radius**2;
  };
}

const circle1 = new Circle(1);
const circle2 = new Circle(2);

//Circle 생성자 함수는 인스턴스를 생성할 때마다 동일한 동작을 하는 
//getArea 메서드를 중복 생성하고 모든 인스턴스를 중복소유한다.
//getArea 메서드는 하나만 생성하여 모든 인스턴스가 공유해서 사용하는 것이 바람직하다.

console.log(circle1.getArea === circle2.getArea); //false
console.log(circle1.getArea()); // 3.14..
console.log(circle2.getArea()); // 12.56..

동일한 생성자 함수에 의해 생성된 모든 인스턴스가 동일한 메서드를 중복으로 소유하는 것은 메모리를 불필요하게 낭비함. 이럴때 상속을 통해 불필요한 중복을 제거해야함.

function Circle(radius) {
  this.radius = radius;
}

//Circle 생성자 함수가 생성한 모든 인스턴스가 getArea 메서드를 
//공유해서 사용할 수 있도록 프로토타입에 추가함.
//프로토타입은 Circle 생성자 함수의 prototype 프로퍼티에 바인딩되어있다.

Circle.prototype.getArea = function () {
  return Math.PI * this.radius **2;
};

//인스턴스생성
const circle1 = new Circle(1);
const circle2 = new Circle(2);

//Circle 생성자 함수가 생성한 모든 인스턴스는 부모 객체의 역할을 하는
//프로토타입 Circle.prototype으로부터 getArea 메서드를 상속받음.
//즉, Circle 생성자 함수가 생성하는 모든 인스턴스는 하나의 getArea메서드를 공유한다.

console.log(circle1.getArea === circle2.getArea); //true
console.log(circle1.getArea()); //3.14...
console.log(circle2.getArea()); //12.56...

 

Object method

자바스크립트에 메소드라는 것은 없음. 자바스크립트는 객체의 속성으로 함수를 지정할 수 있고 속성값을 사용하듯 쓸수 있다.

var o = {
  a: 2,
  m: function(b){
    return this.a + 1;
  }
};

console.log(o.m()); // 3
// o.m을 호출하면 'this' 는 o를 가리킨다.

var p = Object.create(o);
// p 는 프로토타입을 o로 가지는 오브젝트이다.

p.a = 12; // p 에 'a'라는 새로운 속성을 만들었다.
console.log(p.m()); // 13
// p.m이 호출 될 때 'this' 는 'p'를 가리킨다.
// 따라서 o의 함수 m을 상속 받으며,
// 'this.a'는 p.a를 나타내며 p의 개인 속성 'a'가 된다.

 

 

 

 

Prototype method vs Object method

//Prototype

function Parent(gender){
  this.gender = gender;
}

// Attach the common function to prototype.
Parent.prototype.yellAtChild = function(){
  console.log('Somebody gonna get a hurt real bad!');
};

// Let's create dad and mom and start yelling at kids.
var dad = new Parent('male');
var mom = new Parent('female');
dad.yellAtChild(); // Somebody gonna get a hurt real bad!
mom.yellAtChild(); // Somebody gonna get a hurt real bad!

// but, Russell has decide to sue you if you use his catch phrase.
// Simple: Just modify the function at Parent.prototype.

Parent.prototype.yellAtChild = function(){
  console.log('You are grounded.');
};

dad.yellAtChild(); // You are grounded
mom.yellAtChild(); // You are grounded
//Object method

function Parent(gender){
  this.gender = gender;

  // attach the common function to each object instance.
  this.yellAtChild = function(){
    console.log('Somebody gonna get a hurt real bad!');
  }
}

// Let's create dad and mom and start yelling at kids.
var dad = new Parent('male');
var mom = new Parent('female');
dad.yellAtChild(); // Somebody gonna get a hurt real bad!
mom.yellAtChild(); // Somebody gonna get a hurt real bad!

// but, Russell has decide to sue you if you use his catch phrase.
// Let's try to tell our already created dad & mon to use different phrase.

// ERROR: Not possible to do this way.
Parent.yellAtChild = function() { .... }

// You need to override the `yellAtChild` method for each object instance.
dad.yellAtChild = function(){
  console.log('Shut up!');
};
mom.yellAtChild = function(){
  console.log('Go to bed!');
}
dad.yellAtChild(); // Shut up!
mom.yellAtChild(); // Go to bed!
function Fruit (fruit) {
  this.fruit = fruit;
  
  this.taste = function (feel) {
    console.log(this.fruit + " : " + feel);
    };
  }
  
  var orange = new Fruit("oragne");
  var strawberry = new Fruit("strawberry");
  orange.taste("good"); // "oragne : good"
  strawberry.taste("bad"); //"strawberry : bad"
  
  //taste를 'so good'으로 바꾸기
  Fruit.taste = function () {
    console.log(`${this.fruit} : so good`);
  };
  
  //변화 없음.
  orange.taste(); // "oragne : undefined"
  strawberry.taste(); //"strawberry : undefined"

//새로 생성된 객체에서도 안됨.
  var peer = new Fruit("peer");
  peer.taste(); //"peer : undefined"

orange.taste = function () {
  console.log("orange : so good");
};
strawberry.taste = function () {
  console.log("strawberry : so good");
};

orange.taste(); //"orange : so good"
strawberry.taste(); //"orange : so good"




--- prototype을 이용 ---
function Fruit (fruit) {
  this.fruit = fruit;
}

Fruit.prototype.taste = function (feel) {
  console.log(this.fruit + " : " + feel);
};

var orange = new Fruit("orange");
var strawberry = new Fruit("strawberry");
orange.taste("good"); 
strawberry.taste("bad");

Fruit.prototype.taste = function () {
  console.log(`${this.fruit} : so good`);
};

orange.taste(); //"orange : so good"
strawberry.taste();//"strawberry : so good"

출처 : https://veerasundar.com/blog/javascript-prototype-methods-vs-object-methods/

'javascript' 카테고리의 다른 글

break && continue  (0) 2022.03.05
new 연산자  (0) 2022.02.27
if..else / if.. else if  (0) 2022.02.27
Early Return  (0) 2022.02.27
Tree / Binary Search Tree  (0) 2022.02.26