Javascript Prototype

승훈·2022년 11월 9일
0

OOP Object- Oriented Programming

  구조적 프로그래밍 방식이 개선된 형태
  작은 문제들을 해결하는 객체를 만들어 조합해 큰 문제를 해결해 나가는 Bottom - up 방식

   객체 지향 특정
   - 캡슐화
   - 정보은닉
   - 추상화
   - 상속성
   - 다형성

// javascript는 객체지향 언어
// 다만 다른 언어와는 달리 프로토타입 상속에 기반을 둔 OOP 언어. --> Class 문법 지원

// 상속의 필요성.. 프로토타입 체이닝을 통해
// 가장 큰 목적은 '재사용성'
// 이미 부모쪽에서 정의 된 속성과 메서드을 그대로 물려받아 재사용할 수 있다. 뿐 아니라 새로운 기능을 추가해서 기존 기능에서 더 확장 시킬 수도 있다.

// 프로토타입 체인
// proto --> 상속을 해준 부모(원형)를 가리킴(참조)
// 즉, 자식 객체가 proto가 가리키는 부모 객체의 멤버를 사용할 수 있다. === 즉 상속 받았다.

let obj1 = {
name: '부모',
age: 30,
sayHi: function() {console.log('hi' + this.name);}
};

let obj2 = {
name: '자식'
};
// obj2의 proto 속성이 참조하는 것은..? -> 최상위 prototype Object를 가리킴 // obj2객체는 new 연산자를 통해 만든것이 x

// proto 속성이 참조하는 것을 바꿀 수 있는가..? YES
obj2.proto = obj1;
console.log(obj2);
obj2.sayHi(); // hi자식

객체의 프로토타입 출력

[1] : proto vs Object.getPrototypeOf()

function A() {}

let obj = new A();

console.log(obj);
console.log(obj.proto); // 프로토 출력
console.log(Object.getPrototypeOf(obj)); // 프로토 출력

// obj.proto && Object.getPrototypeOf(obj) 동일 ... 단 proto는 지원하지 않는 브라우져가 있을 수 있음.

new 연산자의 내부 동작

[1]: 내부적으로는 빈 객체를 생성한 후에 -> 같은 이름의 '프로토타입 객체'를 새로운 객체의 원형으로 설정

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

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

// 새로운 객체 생성
const add = new Add(111, 222);
console.log(add.plus()); // 333


// 내부 동작
const newObj = {};
newObj.__proto__ = Add.prototype;
Add.apply(newObj, [111, 222]);
console.log(newObj.plus()); // 333

// cf. Function.prototype.apply()

func.apply(thisArg, [argsArray])

인수들의 단일 배열을 받는다

- 이미 존재하는 함수를 호출할 때 다른 this 객체를 할당 할 수 있음.
apply를 사용해, 새로운 객체마다 메소드를 재작성할 필요없이 한 번만 작성해 다른 객체에 상속 시킬 수 있음

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

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

// 새로운 객체 생성
const add = new Add(111, 222);
console.log('add', add);
console.log(add.plus()); // 333

// 내부 동작
const newObj = {};
newObj.proto = Add.prototype;
Add.apply(newObj, [111, 222]); // Add func 객체에 a, b 요소 값을 초기화 시켜줌
console.log(newObj.plus()); // 333

Object prototype 빌트인 메서드

* Function.prototype.bind()
** bind() 메소드가 호출되면 새로운 함수를 생성합니다. 받게되는 첫 인자의 value로는 this 키워드를 설정하고, 이어지는 인자들은 바인드된 함수의 인수에 제공됩니다
* Function.prototype.call()
** call() 메소드는 주어진 this 값 및 각각 전달된 인수와 함께 함수를 호출합니다.
* Function.prototype.apply()

생성자 함수와 내부에서 처리되는 동작들

[1]: 객체 리터럴
const animal = {
    name: 'tiger',
    age: 20
}

[2]: 생성자 함수
// 첫 글자는 관례적으로 대문자로 작성
   새롭게 생성되는 객체 자신을 가리키는 것 --> this를 사용
   new 연산자를 사용해서 새로운 객체 --> 생성 --> 만약 new를 안붙이면 undefined 처리 --> 객체 생성시에는 new 연산자를 꼭 사용
function Person(name, age) {
    this.name =name;
    this.age = age;
}

let p1 = new Person('a', 1);
let p2 = new Person('b', 2);


[3]: 생성자 함수의 내부 실행 과정
function Person(name, age) {
  // this = {} // this라는 빈 객체를 하나 생성한 후에 속성을 추가.
  this.name =name;
  this.age = age;
  // return this;
}
위외 같은 처리로 new 연산자 시에  새로운 객체를 생성

프로토타입 객체의 속성

  • [1]: constructor 속성

  • 이 속성은 함수를 가리킨다(참조), 즉 참조를 값으로 가지는 속성

  • [2]: 서로가 참조... 즉, 서로가 연결고리 역할
    ** 생성자 함수(Animal) (------------------------------------------) (Animal) 프로토타입 객체

    • prototype * constructor
  • [3]: new 연산자에 의해 새롭게 생성된 객체 --> 인스턴스
    생성자 함수(Animal) <--> new 객체(tiger, lion)
    이 둘의 관계는 딱히 없는데 중요한게 있다면, new 연산자가 생성자 함수를 이용해서 새로운 객체를 생성
    하지만 이렇게 생성된 객체들의 원형(부모)는 '(Animal) 프로토타입 객체'

  • [4]: 인스턴스(new 객체)가 어떤 생성자 함수로 생성된 것인지 알아내는 방법?
    '(Animal) 프로토타입 객체' 의 constructor <- 이게 생성자 함수를 가리키고 있으므로 이 값을 확인

    // new 연산자로 새롭게 만들어진 인스턴스(객체)는 자신의 부모격인 원형(프로토타입 객체)에서 특성(속성, 메서드)
    를 상속 받으므로, 당연히 프로토 타입 객체의 constructor 속성을 참조 가능

0개의 댓글