연습장

19. Object-Oriented Programming 객체지향 프로그래밍 본문

JavaScript

19. Object-Oriented Programming 객체지향 프로그래밍

js0616 2024. 7. 19. 15:39

https://poiemaweb.com/js-object-oriented-programming

 

Object-Oriented Programming | PoiemaWeb

오늘날 많은 유명한 프로그래밍 언어(Java, C++, C#, Python, PHP, Ruby, Object-C)는 객체지향 프로그래밍을 지원한다.

poiemaweb.com

 

 

1. 객체지향 프로그래밍 (Object-Oriented Programming) 개요

객체지향 프로그래밍은 실세계에 존재하고 인지하고 있는 객체(Object)를 소프트웨어의 세계에서 표현하기 위해 객체의 핵심적인 개념 또는 기능만을 추출하는 추상화(abstraction)를 통해 모델링하려는 프로그래밍 패러다임을 말한다. 다시 말해, 우리가 주변의 실세계에서 사물을 인지하는 방식을 프로그래밍에 접목하려는 사상을 의미한다.

객체지향 프로그래밍은 함수들의 집합 혹은 단순한 컴퓨터의 명령어들의 목록이라는 전통적인 절차지향 프로그래밍과는 다른, 관계성있는 객체들의 집합이라는 관점으로 접근하는 소프트웨어 디자인으로 볼 수 있다.

각 객체는 메시지를 받을 수도 있고, 데이터를 처리할 수도 있으며, 또다른 객체에게 메시지를 전달할 수도 있다. 각 객체는 별도의 역할이나 책임을 갖는 작은 독립적인 기계 또는 부품으로 볼 수 있다.

객체지향 프로그래밍은 보다 유연하고 유지보수하기 쉬우며 확장성 측면에서서도 유리한 프로그래밍을 하도록 의도되었고, 대규모 소프트웨어 개발에 널리 사용되고 있다.


2. 클래스 기반 vs. 프로토타입 기반

 

2.1 클래스 기반 언어
클래스 기반 언어(Java, C++, C#, Python, PHP, Ruby, Object-C)는 클래스로 객체의 자료구조와 기능을 정의하고 생성자를 통해 인스턴스를 생성한다.

클래스란 같은 종류의 집단에 속하는 속성(attribute)과 행위(behavior)를 정의한 것으로 객체지향 프로그램의 기본적인 사용자 정의 데이터형(user define data type)이라고 할 수 있다. 결국 클래스는 객체 생성에 사용되는 패턴 혹은 청사진(blueprint)일 뿐이며 new 연산자를 통한 인스턴스화 과정이 필요하다.

모든 인스턴스는 오직 클래스에서 정의된 범위 내에서만 작동하며 런타임에 그 구조를 변경할 수 없다. 이러한 특성은 정확성, 안정성, 예측성 측면에서 클래스 기반 언어가 프로토타입 기반 언어보다 좀 더 나은 결과를 보장한다.

아래의 예제는 Java로 구현된 클래스이다. Java는 class 키워드를 제공하고 이것으로 클래스를 정의한다. 생성자는 클래스명과 동일하며 메소드로 구현된다.

 

class Person {
  private String name;

  public Person(String name) {
    this.name = name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getName() {
    return this.name;
  }

  public static void main(String[] args) {
    Person me = new Person("Lee");

    String name= me.getName();
    System.out.println(name); // Lee
  }
}

 


 

2.2 프로토타입 기반 언어
자바스크립트는 멀티-패러다임 언어로 명령형(imperative), 함수형(functional), 프로토타입 기반(prototype-based) 객체지향 언어다. 비록 다른 객체지향 언어들과의 차이점에 대한 논쟁들이 있긴 하지만, 자바스크립트는 강력한 객체지향 프로그래밍 능력들을 지니고 있다. 간혹 클래스가 없어서 객체지향이 아니라고 생각하는 사람들도 있으나 프로토타입 기반의 객체지향 언어다.

자바스크립트는 클래스 개념이 없고 별도의 객체 생성 방법이 존재한다.

  • 객체 리터럴
  • Object() 생성자 함수
  • 생성자 함수
// 객체 리터럴
var obj1 = {};
obj1.name = 'Lee';

// Object() 생성자 함수
var obj2 = new Object();
obj2.name = 'Lee';

// 생성자 함수
function F() {}
var obj3 = new F();
obj3.name = 'Lee';

 

자바스크립트는 이미 생성된 인스턴스의 자료구조와 기능을 동적으로 변경할 수 있다는 특징이 있다.

객체 지향의 상속, 캡슐화(정보 은닉) 등의 개념은 프로토타입 체인과 클로저 등으로 구현할 수 있다.

자바스크립트에서는 함수 객체로 많은 것을 할 수 있는데 클래스, 생성자, 메소드도 모두 함수로 구현이 가능하다.

 

ES6의 Class는 기존 prototype 기반 객체지향 프로그래밍보다 Class 기반 언어에 익숙한 프로그래머가 보다 빠르게 학습할 수 있는 단순하고 깨끗한 새로운 문법을 제시하고 있다. ES6의 Class가 새로운 객체지향 모델을 제공하는 것이 아니며 Class도 사실 함수이고 기존 prototype 기반 패턴의 Syntactic sugar이다.


 

3. 생성자 함수와 인스턴스의 생성
자바스크립트는 생성자 함수와 new 연산자를 통해 인스턴스를 생성할 수 있다. 이때 생성자 함수는 클래스이자 생성자의 역할을 한다.

// 생성자 함수(Constructor)
function Person(name) {
  // 프로퍼티
  this.name = name;

  // 메소드
  this.setName = function (name) {
    this.name = name;
  };

  // 메소드
  this.getName = function () {
    return this.name;
  };
}

// 인스턴스의 생성
var me = new Person('Lee');
console.log(me.getName()); // Lee

// 메소드 호출
me.setName('Kim');
console.log(me.getName()); // Kim

 

var me  = new Person('Lee');
var you = new Person('Kim');
var him = new Person('Choi');

console.log(me);  // Person { name: 'Lee', setName: [Function], getName: [Function] }
console.log(you); // Person { name: 'Kim', setName: [Function], getName: [Function] }
console.log(him); // Person { name: 'Choi', setName: [Function], getName: [Function] }

 

위와 같이 인스턴스를 생성하면 각각의 인스턴스에 메소드 setName, getName이 중복되어 생성된다.

즉, 각 인스턴스가 내용이 동일한 메소드를 각자 소유한다.

이는 메모리 낭비인데 생성되는 인스턴스가 많아지거나 메소드가 크거나 많다면 무시할 수 없는 문제이다.

 

이같은 문제를 해결하려면 다른 접근 방식이 필요한데 그 해답은 프로토타입이다.


4. 프로토타입 체인과 메소드의 정의
모든 객체는 프로토타입이라는 다른 객체를 가리키는 내부 링크를 가지고 있다. 

즉, 프로토타입을 통해 직접 객체를 연결할 수 있는데 이를 프로토타입 체인이라 한다.

프로토타입을 이용하여 생성자 함수 내부의 메소드를 생성자 함수의 prototype 프로퍼티가 가리키는 프로토타입 객체로 이동시키면 생성자 함수에 의해 생성된 모든 인스턴스는 프로토타입 체인을 통해 프로토타입 객체의 메소드를 참조할 수 있다.

 

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

// 프로토타입 객체에 메소드 정의
Person.prototype.setName = function (name) {
  this.name = name;
};

// 프로토타입 객체에 메소드 정의
Person.prototype.getName = function () {
  return this.name;
};

var me  = new Person('Lee');
var you = new Person('Kim');
var him = new Person('choi');

console.log(Person.prototype);
// Person { setName: [Function], getName: [Function] }

console.log(me);  // Person { name: 'Lee' }
console.log(you); // Person { name: 'Kim' }
console.log(him); // Person { name: 'choi' }

 

 

 

프로토타입 객체는 상속할 것들이 저장되는 장소이다.

 

이해한것

기존 방식은 각각의 객체에서 메서드를 정의하게 되는데, 이는 인스턴스의 수가 증가하면 동일한 기능을 하는 메서드가 중복되므로 메모리 낭비가 된다. 이를 상위의 객체인 프로토타입에 메서드를 정의하고 하위 객체(인스턴스)에서 가져다 사용

 


아래는 더글라스 크락포드가 제안한 프로토타입 객체에 메소드를 추가하는 방식이다.

/**
 * 모든 생성자 함수의 프로토타입은 Function.prototype이다. 따라서 모든 생성자 함수는 Function.prototype.method()에 접근할 수 있다.
 * @method Function.prototype.method
 * @param ({string}) (name) - (메소드 이름)
 * @param ({function}) (func) - (추가할 메소드 본체)
 */
 
// 1.  Function.prototype.method 메소드 추가
 
Function.prototype.method = function (name, func) {
  // 생성자함수의 프로토타입에 동일한 이름의 메소드가 없으면 생성자함수의 프로토타입에 메소드를 추가
  // this: 생성자함수
  if (!this.prototype[name]) {
    this.prototype[name] = func;
  }
};

// 2. Person 생성자 함수 정의
 
function Person(name) {
  this.name = name;
}
 
// 3. Person.prototype에 메소드 추가
 
//생성자함수 Person의 프로토타입에 메소드 setName을 추가
Person.method('setName', function (name) {
  this.name = name;
});
 
// 생성자함수 Person의 프로토타입에 메소드 getName을 추가
Person.method('getName', function () {
  return this.name;
});
 
 
// 4. 인스턴스 생성 및 메소드 호출
 
var me  = new Person('Lee');
var you = new Person('Kim');
var him = new Person('choi');

console.log(Person.prototype);
// Person { setName: [Function], getName: [Function] }
 
console.log(me);  // Person { name: 'Lee' }
console.log(you); // Person { name: 'Kim' }
console.log(him); // Person { name: 'choi' }

console.log(me.getName()) // Lee
 

 

1. Function.prototype.method 메소드 추가

 

  • 이 함수는 Function.prototype 객체에 method라는 메소드를 추가합니다.
  • 이 메소드는 두 개의 매개변수 name (메소드 이름)과 func (추가할 메소드의 본체)를 받습니다.
  • this는 호출한 생성자 함수를 가리키게 되며, 여기서는 Person 생성자 함수가 됩니다.
  • if (!this.prototype[name]) 조건을 통해 해당 이름의 메소드가 이미 존재하지 않을 경우에만 메소드를 추가합니다.

 

 

2. Person 생성자 함수 정의

  • Person 생성자 함수는 name을 매개변수로 받아 객체의 name 속성을 초기화합니다.

 

3. Person.prototype에 메소드 추가

 

  • Person 생성자 함수의 프로토타입에 setName과 getName 메소드를 추가합니다.
  • setName 메소드는 객체의 name 속성을 설정합니다.
  • getName 메소드는 객체의 name 속성 값을 반환합니다.

 

4. 인스턴스 생성 및 메소드 호출

 

  • Person 생성자 함수를 이용하여 me, you, him 세 개의 인스턴스를 생성합니다.
  • 각 인스턴스는 getName 메소드를 통해 객체의 name 속성 값을 출력합니다.

 

 


 

5. 상속 (Inheritance)
Java같은 클래스 기반 언어에서 상속(또는 확장)은 코드 재사용의 관점에서 매우 유용하다. 새롭게 정의할 클래스가 기존에 있는 클래스와 매우 유사하다면, 상속을 통해 다른 점만 구현하면 된다. 코드 재사용은 개발 비용을 현저히 줄일 수 있는 잠재력이 있기 때문에 매우 중요하다.

클래스 기반 언어에서 객체는 클래스의 인스턴스이며 클래스는 다른 클래스로 상속될 수 있다.

자바스크립트는 기본적으로 프로토타입을 통해 상속을 구현한다.

자바스크립트의 상속 구현 방식은 크게 두 가지로 구분할 수 있다. 

하나는 클래스 기반 언어의 상속 방식을 흉내 내는 것(의사 클래스 패턴 상속. Pseudo-classical Inheritance)이고,

두번째는 프로토타입으로 상속을 구현하는 것(프로토타입 패턴 상속. Prototypal Inheritance)이다.


 

5.1 의사 클래스 패턴 상속 (Pseudo-classical Inheritance)
의사 클래스 패턴은 자식 생성자 함수의 prototype 프로퍼티를 부모 생성자 함수의 인스턴스로 교체하여 상속을 구현하는 방법이다. 부모와 자식 모두 생성자 함수를 정의하여야 한다.

 

// 부모 생성자 함수
var Parent = (function () {
  // Constructor
  function Parent(name) {
    this.name = name;
  }

  // method
  Parent.prototype.sayHi = function () {
    console.log('Hi! ' + this.name);
  };

  // return constructor
  return Parent;
}());

// 자식 생성자 함수
var Child = (function () {
  // Constructor
  function Child(name) {
    this.name = name;
  }

  // 자식 생성자 함수의 프로토타입 객체를 부모 생성자 함수의 인스턴스로 교체.
  Child.prototype = new Parent(); // ②

  // 메소드 오버라이드
  Child.prototype.sayHi = function () {
    console.log('안녕하세요! ' + this.name);
  };

  // sayBye 메소드는 Parent 생성자함수의 인스턴스에 위치된다
  Child.prototype.sayBye = function () {
    console.log('안녕히가세요! ' + this.name);
  };

  // return constructor
  return Child;
}());

var child = new Child('child'); // ①
console.log(child);  // Parent { name: 'child' }

console.log(Child.prototype); // Parent { name: undefined, sayHi: [Function], sayBye: [Function] }

child.sayHi();  // 안녕하세요! child
child.sayBye(); // 안녕히가세요! child

console.log(child instanceof Parent); // true
console.log(child instanceof Child);  // true

 

Child 생성자 함수가 생성한 인스턴스 child(①)의 프로토타입 객체는 Parent 생성자 함수가 생성한 인스턴스(②)이다.

그리고 Parent 생성자 함수가 생성한 인스턴스의 프로토타입 객체는 Parent.prototype이다.

 

이로써 child는 프로토타입 체인에 의해 Parent 생성자 함수가 생성한 인스턴스와 Parent.prototype의 모든 프로퍼티에 접근할 수 있게 되었다. 이름은 의사 클래스 패턴 상속이지만 내부에서는 프로토타입을 사용하는 것은 변함이 없다.

 

 

 

구동 상에 문제는 없지만 의사 클래스 패턴은 아래와 같은 문제를 가지고 있다.

 

 

1. new 연산자를 통해 인스턴스를 생성한다.

  • 생성자 함수와 new 연산자를 통해 객체를 생성하는 불필요한 간접적인 단계
  • new 연산자를 포함하는 것을 잊게 되면 this는 새로운 객체와 바인딩되지 않고 전역객체에 바인딩된다.

 

2. 생성자 링크의 파괴

  • child 객체를 생성한 것은 Child 생성자 함수이지만 child.constructor의 출력 결과는 Child 생성자 함수가 아닌 Parent 생성자 함수를 나타낸다. 이는 child 객체의 프로토타입 객체인 new Parent() 객체는 constructor가 없기 때문에 프로토타입 체인에 의해 Parent.prototype의 constructor를 참조했기 때문이다.
 
console.log(child.constructor);  // [Function: Parent]
 

 

 

3. 객체 리터럴

  • 객체 리터럴 패턴으로 생성한 객체의 생성자 함수는 Object()이고 이를 변경할 방법이 없기 때문이다.

 

이와 같은 문제점을  프로토타입 패턴 상속 (Prototypal Inheritance) 으로 해결 할 수 있다.


 

5.2 프로토타입 패턴 상속 (Prototypal Inheritance)
프로토타입 패턴 상속은 Object.create 함수를 사용하여 객체에서 다른 객체로 직접 상속을 구현하는 방식이다. 

new 연산자가 필요없으며, 생성자 링크도 파괴되지 않으며, 객체리터럴에도 사용할 수 있다.

 

 
Object.create(proto [, propertiesObject])

 

  • proto: 새로 생성될 객체의 프로토타입이 될 객체입니다. 이 매개변수는 필수적입니다.
  • propertiesObject (선택적): 객체의 속성을 정의하는 객체입니다. 이 객체는 프로퍼티 설명자(property descriptor)를 가질 수 있습니다.
// 부모 객체
const parent = {
  greet: function() {
    console.log('Hello!');
  }
};

// 자식 객체 생성 및 부모 객체를 프로토타입으로 설정
const child = Object.create(parent, {
  // name 프로퍼티
  name: {
    value: 'Child',      // 프로퍼티의 값
    writable: true,      // 값을 변경할 수 있는지 여부 (기본값: false)
    enumerable: true,    // 열거 가능한지 여부 (기본값: false)
    configurable: true   // 프로퍼티 설명자를 변경할 수 있는지 여부 (기본값: false)
  },
  // age 프로퍼티
  age: {
    value: 10,
    writable: true,
    enumerable: true,
    configurable: true
  }
});

console.log(child.name); // "Child"
console.log(child.age); // 10

child.greet(); // "Hello!"

// 열거 가능한 프로퍼티를 열거
for (let key in child) {
  console.log(key); // "name", "age"
}

 

 

 


생성자 함수를 사용한 프로토타입 패턴 상속은 아래와 같다.

// 부모 생성자 함수
var Parent = (function () {
  // Constructor
  function Parent(name) {
    this.name = name;
  }

  // method
  Parent.prototype.sayHi = function () {
    console.log('Hi! ' + this.name);
  };

  // return constructor
  return Parent;
}());

// create 함수의 인수는 프로토타입이다.
var child = Object.create(Parent.prototype);
child.name = 'child';

child.sayHi();  // Hi! child

console.log(child instanceof Parent); // true

 

 


객체리터럴 패턴으로 생성한 객체에도 프로토타입 패턴 상속을 사용할 수 있다.

 

var parent = {
  name: 'parent',
  sayHi: function() {
    console.log('Hi! ' + this.name);
  }
};

// create 함수의 인자는 객체이다.
var child = Object.create(parent);
child.name = 'child';

// var child = Object.create(parent, {name: {value: 'child'}});

parent.sayHi(); // Hi! parent
child.sayHi();  // Hi! child

console.log(parent.isPrototypeOf(child)); // true

 

 


 

정리
'의사 클래스 패턴 상속' 은 3가지의 문제점이 있으므로 '프로토타입 패턴 상속'을 해야한다.
Object.create 함수를 사용하여 객체에서 다른 객체로 직접 상속을 구현하는 방식으로


Object.create(proto [, propertiesObject])

 

각각의 상황에 따라 create 함수의 인자가 다르다.

 

1. 부모가 생성자 함수 인 경우

// create 함수의 인수는 프로토타입이다.
var child = Object.create(Parent.prototype);
child.name = 'child';

 

2. 부모가 객체 리터럴인 경우

// create 함수의 인자는 객체이다.
var child = Object.create(parent);
child.name = 'child';

 

 


 

기타.

Object.create 폴리필

  • 매개변수에 프로토타입으로 설정할 객체 또는 인스턴스를 전달하고 이를 상속하는 새로운 객체를 생성한다.
  • 표준에 비교적 늦게 추가되어 IE9 이상에서 정상적으로 동작한다

따라서 Object.create 함수의 폴리필(Polyfill: 특정 기능이 지원되지 않는 브라우저를 위해 사용할 수 있는 코드 조각이나 플러그인)을 살펴보면 상속의 핵심을 이해할 수 있다.

 

// Object.create 함수의 폴리필
if (!Object.create) {
  Object.create = function (o) {
    function F() {}  // 1
    F.prototype = o; // 2
    return new F();  // 3
  };
}

 

위 폴리필은 프로토타입 패턴 상속의 핵심을 담고 있다.

  1. 비어있는 생성자 함수 F를 생성한다.
  2. 생성자 함수 F의 prototype 프로퍼티에 매개변수로 전달받은 객체를 할당한다.
  3. 생성자 함수 F를 생성자로 하여 새로운 객채를 생성하고 반환한다.

 

 

 


6. 캡슐화(Encapsulation)와 모듈 패턴(Module Pattern)
캡슐화는 관련있는 멤버 변수와 메소드를 클래스와 같은 하나의 틀 안에 담고 외부에 공개될 필요가 없는 정보는 숨기는 것을 말하며 다른 말로 정보 은닉(information hiding)이라고 한다.

Java의 경우, 클래스를 정의하고 그 클래스를 구성하는 멤버에 대하여 public 또는 private 등으로 한정할 수 있다. public으로 선언된 메소드 또는 데이터는 외부에서 사용이 가능하며, private으로 선언된 경우는 외부에서 참조할 수 없고 내부에서만 사용된다. 이것은 클래스 외부에는 제한된 접근 권한을 제공하며 원하지 않는 외부의 접근에 대해 내부를 보호하는 작용을 한다. 


문제점 1 : 자바스크립트는 public 또는 private 등의 키워드를 제공하지 않는다.

var Person = function(arg) {
  var name = arg ? arg : ''; // ①

  this.getName = function() {
    return name;
  };

  this.setName = function(arg) {
    name = arg;
  };
}

var me = new Person('Lee');

var name = me.getName();

console.log(name);

me.setName('Kim');
name = me.getName();

console.log(name);

 

해결 방안 1 :

①의 name 변수는 private 변수가 된다. 자바스크립트는 function-level scope를 제공하므로 함수 내의 변수는 외부에서 참조할 수 없다. 


 

문제점 2:

만약에 var 대신 this를 사용하면 public 멤버가 된다.

new 키워드로 객체를 생성하지 않으면 this는 생성된 객체에 바인딩되지 않고 전역객체에 연결된다.

var person = function(arg) {
  var name = arg ? arg : '';

  return {
    getName: function() {
      return name;
    },
    setName: function(arg) {
      name = arg;
    }
  }
}

var me = person('Lee'); /* or var me = new person('Lee'); */

var name = me.getName();

console.log(name);

me.setName('Kim');
name = me.getName();

console.log(name);

 

해결 방안 2:

person 함수는 객체를 반환한다. 이 객체 내의 메소드 getName, setName은 클로저로서 private 변수 name에 접근할 수 있다. 이러한 방식을 모듈 패턴이라 하며 캡슐화와 정보 은닉를 제공한다.


문제점 3:

그러나 private 멤버가 객체나 배열일 경우, 반환된 해당 멤버의 변경이 가능하다.

var person = function (personInfo) {
  var o = personInfo;

  return {
    getPersonInfo: function() {
      return o;
    }
  };
};

var me = person({ name: 'Lee', gender: 'male' });

var myInfo = me.getPersonInfo();
console.log('myInfo: ', myInfo);
// myInfo:  { name: 'Lee', gender: 'male' }

myInfo.name = 'Kim';

myInfo = me.getPersonInfo();
console.log('myInfo: ', myInfo);
// myInfo:  { name: 'Kim', gender: 'male' }

 

해결 방안 3:

객체를 그대로 반환하지 않고 반환해야 할 객체의 정보를 새로운 객체에 담아 반환해야 한다.

객체 전체가 그대로 반환되어야 하는 경우에는 깊은 복사(deep copy)로 복사본을 만들어 반환한다.


 

문제점 4:

person 함수가 반환한 객체는 person 함수 객체의 프로토타입에 접근할 수 없다. 이는 상속을 구현할 수 없음을 의미한다.

var person = function(arg) {
  var name = arg ? arg : '';

  return {
    getName: function() {
      return name;
    },
    setName: function(arg) {
      name = arg;
    }
  }
}

var me = person('Lee');

console.log(person.prototype === me.__proto__); // false
console.log(me.__proto__ === Object.prototype); // true: 객체 리터럴 방식으로 생성된 객체와 동일하다

 

해결 방안 4:

객체를 반환하는 것이 아닌 함수를 반환해야 한다.

var Person = function() {
  var name;

  var F = function(arg) { name = arg ? arg : ''; };

  F.prototype = {
    getName: function() {
      return name;
    },
    setName: function(arg) {
      name = arg;
    }
  };

  return F;
}();

var me = new Person('Lee');

console.log(Person.prototype === me.__proto__);

console.log(me.getName());
me.setName('Kim')
console.log(me.getName());

 

 

 


후기

문제점과 해결방법의 흐름으로 이루어진 챕터였는데, 생각보다 어지러웠는데.. 마지막만 보면될꺼같다. 

 

자바스크립트에서 JAVA 와 같이 캡슐화, 모듈화를 구현하는 방법으로 

1. 자유변수를 만들고 (private 변수)

2. 이에 접근가능한 메소드를 클로저로 구현하며

3. 이때 상속 가능하도록 함수를 반환 (F) 

 

인데,.. 

ES6 의 class 를 쓰면 더 쉽지 않을까? 그냥 2번 클로저 정도로 끝내도 되지않을까 this 를 써야되나..? 흠..

 

gpt 예제 코드

function createPerson(name) {
  let _name = name; // private 변수

  return {
    getName: function() {
      return _name;
    },
    setName: function(newName) {
      _name = newName;
    }
  };
}

const person = createPerson('John');
console.log(person.getName()); // 'John'
person.setName('Jane');
console.log(person.getName()); // 'Jane'

 

 


 

객체지향 프로그래밍이란?

실제 세계에 존재하는 객체(Object)를 소프트웨어의 세계에서 표현하는 방법으로

객체의 핵심적인 개념 또는 기능만을 추출하는 추상화(abstraction)를 통해 모델링하려는 프로그래밍 방법

추상화, 캡슐화, 상속, 다형성 의 특징을 가진다. 

 

프로토타입을 쓰는 이유는?

프로토타입 객체에 메소드를 정의해 두면 새로 생성되는 인스턴스에서 중복으로 메소드를 정의할 필요없이 가져다 사용할 수 있어서 메모리 절약 가능 및 관리 효율성 증가 

 

인스턴스가 많아질 경우를 대비하여 메서드는 프로토타입 객체로 관리

 

js 에서 캡슐화, 모듈화 구현을 어떻게 할 수 있을까? 

 

 

 

 

 

 

 

 

 

https://chatgpt.com/

'JavaScript' 카테고리의 다른 글

21. Global Object , 전역 객체  (0) 2024.07.20
20. Built-in Object  (0) 2024.07.20
18. Closure 클로저  (0) 2024.07.19
17. this  (0) 2024.07.18
16. Strict mode  (0) 2024.07.18