드림오구
article thumbnail

1. 🌊 프로토타입 체인

: 자바스크립트 엔진의 특성상 객체의 프로퍼티에 접근할 때 해당 객체에 프로퍼티가 없으면 부모 역할을 하는 프로퍼토타입을 순차적으로 탐색한다.

 

1.1. __proto__

: 모든 객체는 __proto__ 접근자 프로퍼티를 통해 자신의 프로토타입, 즉 [[Prototype]] 내부 슬롯에 간접적으로 접근할 수 있다.

  • __proto__ 접근자 프로퍼티는 상속을 통해 사용된다.
  • __proto__ 접근자 프로퍼티를 통해 프로토타입을 접근하는 이유는 상호 참조에 의해 프로토타입 체인이 생성되는 것을 방지하기 위해서다. (프로토타입 체인은 단방향으로 구현되어야한다)
  • 모든 객체가 __proto__접근자를 사용할 수 있는 것이 아니기 때문에 __proto__ 접근자 프로퍼티를 코드 내에서 직접 사용하는 것은 권장하지 않는다.
  • 사용 목적 : 객체가 자신의 프로토타입에 접근 또는 교체하기 위해 사용

1.2. prototype 프로퍼티

: 함수 객체만이 소유하는 prototype 프로퍼티는 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킨다.

  • Object.prototype으로부터 상속받은 __proto__ 접근자 프로퍼티와 함수 객체만이 가지고 있는 prototype 프로퍼티는 결국 동일한 프로퍼티를 가진다.
  • constructor이 소유한다.
  • 사용 목적 : 생성자 함수가 자신이 생성할 객체의 프로토타입을 할당하기 위해 사용

 

1.3. 프로토타입 상속 (ES5 클래스)

<javascript />
function Person(first, last, age, gender, interests){ this.name = { first, last } this.age = age; this.gender = gender; this.interests = interests; } // Person의 메소드 Person.prototype.greeting = function() { alert("Hi! I'm" + this.name.first + '.'); } // student 클래스 만들기 // 추가될 속성 학교 (초등학교, 중학교, 고등학교, 대학교) // greeting 인사 function Student(first, last, age, gender, interests, school){ Person.call(this, first, last, age, gender, interests); this.school = school; }

Student() 생성자 함수가 Person()을 상속 받기 위해 call() 함수를 사용한다.

call() 함수의 첫번째 매개변수 this는 다른 곳에서 정의된 함수를 현재 컨텍스트에서 실행할 수 있게 하고, 나머지 실제 함수 실행에 필요한 인자들을 전달한다.

마지막 줄에 새 속성인 school을 정의하여 Student만 갖는 속성을 만들어준다.

 

→ 단, 상속 받은 Person() 생성자의 prototype 속성은 상속 받지 못한다.

 

<javascript />
Object.getOwnPropertyNames(Student.prototype); // ['constructor'] Object.getOwnPropertyNames(Person.prototype); // ['constructor', 'greeting']
<javascript />
// person의 prototype을 상속받지 못했기 때문에 Person을 상속 받는 객체를 생성하여 Student.prototype으로 할당한다 Student.prototype = Object.create(Person.prototype); let student = Object.getOwnPropertyNames(Student.prototype); console.log(student) // [] Student.prototype.constructor; // Person을 상속받은 객체를 할당받아 아래를 반환한다. // Person(first, last, age, gender, interests){ // this.name = { // first, // last // } // this.age = age; // this.gender = gender; // this.interests = interests; // } Student.prototype.constructor = Student; //Student을 다시 할당해주면 Person도 상속받고 Student를 반환하는 것을 확인할 수 있다. // Student(first, last, age, gender, interests, school){ // Person.call(this, first, last, age, gender, interests); // this.school = school; // }

Person을 상속 받는 새 객체를 생성한 후 Student.prototype에 할당한다

Sudent.prototype.constructor에 Student를 다시 할당하면 Person도 상속받고 Student를 반환하는 것을 확인할 수 있다.

 

1.4. 프로토타입 상속 (ES6)

: ES6에는 클래스 문법이 새로 공개되어 조금 더 쉽고 명확하게 재활용할 수 있게 된다.

 

<javascript />
class Person { constructor(first, last, age, gender, interests){ this.name = { first, last }; this.age = age; this.gender = gender; this.interests = interests; } greeting(){ console.log(`Hi! I'm ${this.name.first}`) } } let oh = new Person('Oh', 'Gu', 30, 'female', ['coding']) oh.greeting() // Hi! I'm Oh

 

Person을 상속 받는 Student 클래스를 만들기

 

<javascript />
// extends로 Person을 상속받는 다는 것을 표기한다. class Student extends Person{ constructor(first, last, age, gender, interests, school){ this.name = { first, last }; this.age = age; this.gender = gender; this.interests = interests; // Student 클래스에 추가 됨 this.school = school; } } //constructor에서 첫 번째로 super 연산자를 정의하면 코드를 조금 더 읽기 쉬워진다. // super() → 상위 클래스의 생성자를 호출하여 super()의 매개변수를 통해 상위 클래스의 멤버를 상속 받을 수 있는 코드 class Student extends Person{ constructor(first, last, age, gender, interests, school){ super(first, last, age, gender, interests); // Student 클래스에 추가 됨 this.school = school; } }

 

1.4.1. Getter와 Setter

: 생성한 클래스 인스턴스의 속성 값을 변경하거나 최종 값을 예측할 수 없을 때 getter와 setter을 사용한다. 

  • Getter : 현재 값을 반환
  • Setter : 해당 값을 변경
<javascript />
class Student extends Person{ constructor(first, last, age, gender, interests, school){ super(first, last, age, gender, interests); // Student 클래스에 추가 됨 this.school = school; } get school(){ return this.school }; set school(newSchool){ this.school = newSchool; } }
profile

드림오구

@드림오구