JavaScript 객체지향

csct3456·2022년 4월 4일
0

객체

서로 연관된 변수와 함수를 그룹핑하고 이름을 붙인 것

생성자 함수

// 생성자 함수 예시
function Person(name,first,second,third){
    this.name = name;
    this.first = first;
    this.second = second;
    this.third = third;
}

// prototype을 이용해 Person의 메소드를 정의
Person.prototype.sum = function(){ 
    return this.first+this.second+this.third;
}

var kim = new Person('kim',10,20,30);
var lee = new Person('lee',10,10,10);
console.log("kim.sum()",kim.sum());
console.log("lee.sum()",lee.sum()); // 탐색 순서 : lee.sum() ->  Person.prototype.sum()	
  • 객체를 생성하는데 사용되는 함수
  • 재사용 할 수 있는 객체 생성 코드를 구현할 수 있다
  • 객체의 일괄 수정이 가능하다
  • prototype을 이용해 메소드를 따로 정의하면 객체가 생성될 때 마다 함수를 생성할 필요(x)
    -> 하나의 함수를 공유함으로써 메모리를 절약하고 관리가 용이함

클래스 및 메서드

// class를 이용한 객체 생성 예시
class Person{
    constructor(name,first,second){
        this.name = name;
        this.first = first;
        this.second = second;
    }
	
    sum(){  // class 내부에 method 정의하기
        return 'sum : ' + (this.first+this.second);
    }
} 

// prototype을 이용한 method 정의하기
Person.prototype.sub = function(){ 
    return 'prototype : ' + (this.first-this.second);
}
  • https://babeljs.io/ : 클래스 기반 코드를 prototype 기반 코드로 바꿔주는 사이트
  • class {...}
  • 클래스 내에서 함수를 선언할 때 function은 사용하지 않는다
  • 객체 생성 시 실행되는 초기화 함수는 constructor(...) {...} 이다.
  • 멤버 변수 저장은 생성자와 동일하게 this를 이용한다
  • 메소드 정의 방법으로 prototype도 사용 가능
  • class 내부에 동일한 이름의 함수가 존재하는 경우 바깥쪽에서 prototype으로 재정의 불가능

클래스 상속

// class 상속
// Person이 PersonPlus에 상속됨(PersonPlus가 Person을 이어받고 확장시킴)
class PersonPlus extends Person{
    constructor(name, first, second, third){
        super(name, first, second); // super() : 부모의 constructor를 호출
        this.third = third;
    }
    sum(){
        return super.sum()+this.third; // super.~ : 부모의 멤버에 접근
    }
    avg(){
        return (this.first+this.second+this.third)/3;
    }
}
  • 상속이란 기존 클래스에서 어떠한 것을 추가하고 싶을 때 쓸 수 있는 기능이다.
  • 상속이 없다면 본 클래스를 수정하거나, 중복된 요소가 담긴 클래스를 생성해야 한다.
  • super를 이용하면 부모클래스의 consturctor나 method를 이용할 수 있다
    -> 코드를 중복시키지 않고 부모의 기능을 활용하여 새로운 기능을 만드는 것이 가능하다.

객체 상속

// 객체 상속
var superObj = {superVal:'super'}

// 방법 1
subObj.__proto__ = superObj;  // subObj가 superObj를 상속

// 방법 2
var subObj2 = Object.create(superObj); // 내부적으로는 방법 2와 동일

call

// call 사용 예시
var kim = {name:'kim',first:10,second:20}
var lee = {name:'lee',first:10,second:10}

function sum(prefix){
    return prefix+(this.first + this.second);
}

sum.call(kim, "result: ");

console.log(kimSum()); // result: 30
  • 자바스크립트에서 함수는 객체이다
  • 모든 함수는 call 메서드를 가진다
  • call의 첫번째 인자는 this로 사용할 객체이다
  • call의 두번째 인자부터는 매개변수로 사용된다

bind

// bind 사용 예시
var kim = {name:'kim',first:10,second:20}

function sum(prefix){
    return prefix+(this.first + this.second);
}

kimSum = sum.bind(kim, "kim result: ");
console.log(kimSum()); // kim result: 30
  • 내부적으로 매개변수를 고정시킨 새로운 함수를 반환한다
  • bind를 호출한 원함수에는 영향을 미치지 않는다
  • call과 동일하게 첫번째 인자는 this를 받고 두번째부터 매개변수로 쓰인다

prototype vs __proto__

function Person(name, first,second){
    this.name = name;
    this.first = first;
    this.second = second;
}

Person.prototype.sum = function(){}

var kim = new Person('kim',10,20);
var lee = new Person('lee',10,10);
  1. 객체에서 상속을 정의하는 것을 prototype link 라고 한다.
  2. prototype link는 __proto__ 를 사용하여 정의한다.
  3. 함수를 new 키워드를 이용하여 객체로 만들 때 생성자 객체와 prototype 객체가 생성된다.
  4. prototype 객체는 동일한 함수를 이용하여 생성된 객체가 모두 공유하여 사용한다.
  5. 생성자의 prototype은 자신의 prototype을 가리키고, prototype 객체의 constructor는 생성자를 가리킨다. (+ prototype의 __proto__ 는 Object를 가리킨다)
  6. new를 통해 객체가 만들어지면 자신을 만든 생성자의 prototype을 __proto__ 로 가리킨다.
  7. 객체가 값이나 함수를 탐색할 때, 먼저 내부를 찾아보고 없으면 __proto__를 따라가서 찾는 것을 반복한다.
    ex) kim.sum() : kim.sum (x) -> kim.__proto__.sum (o)
  8. constructor 활용 예시
console.log(d.constructor); // 객체의 생성자를 알아냄
var e = d.constructor() // 객체의 생성자를 호출

결론

1번 코드는 내부적으로 2번 코드를 사용한다.

// 1번 코드 : class 기반

class Person{
    constructor(name,first,second){
        this.name = name;
        this.first = first;
        this.second = second;
    }
	
    getName (){
        return this.name;
    }
} 

class PersonPlus extends Person{
    constructor(name, first, second, third){
        super(name, first, second); // super() : 부모의 constructor를 호출
        this.third = third;
    }
 
    avg(){
        return (this.first+this.second+this.third)/3;
    }
}
// 2번 코드 : prototype 기반

function Person(name,first,second){
    this.name = name;
    this.first = first;
    this.second = second;
}

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

function PersonPlus(name, first, second, third){
    Person.call(this,name,first,second);
    this.third = third;
}

//PersonPlus.prototype.\__proto\__ = Person.prototype;  <- 아래 두 줄 대신 사용 가능
PersonPlus.prototype = Object.create(Person.prototype);
PersonPlus.prototype.constructor = PersonPlus;

PersonPlus.prototype.avg = function(){
    return (this.first+this.second+this.third)/3;
}

0개의 댓글