JS 객체지향 프로그래밍 2

Jungwon Lee(Jenny)·2021년 1월 20일
0
post-thumbnail

참고: 생활코딩 Javascript 객체 지향 프로그래밍

Class

객체를 찍어내는 공장, constructor function의 대체제
ECMA 6에 새로 도입된 문법

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

자바스크립트 객체를 실행할 때 constructor을 자동으로 실행시켜준다.
객체가 만들어지기 전에 constructor이 실행된다.

메소드 구현법

  1. 첫 번째 방법
Person.prototype.sum=function(){
	return 어쩌구;
    }
  1. 두 번째 방법
class Person {
	sum(){
    	return 어쩌구;
    }
}

둘다 의미는 똑같음.

이름은 같지만 개별적 기능은 다르게 동작하는 sum을 만들고싶다면,

kim.sum=function(){return something};

-> kim이라는 객체가 sum이라는 함수를 가지고 있는지 먼저 확인하고, 없다면 kim이라는 객체의 Person이라고 하는 class 안에 sum이라고 하는 메소드가 정의되어있나 보고, 있다면 그것을 실행시킨다.

Class 상속

상속:

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

class PersonPlus extends Person {
	avg(){
    	return (this.first+this.second)/2;
    }
}

만약 중복되는 속성이 있다면, 상속을 사용하여 중복을 최소화하면 좋다.
위의 코드처럼 extends 로 부모클래스를 상속받으면, 부모클래스의 프로퍼티들을 다 사용할수 있으므로, 유지보수↑

Super

class Person{
    constructor(name, first, second){
        this.name = name;
        this.first = first;
        this.second = second;
    }
    sum(){
        return this.first+this.second;
    }
}
class PersonPlus extends Person{
    constructor(name, first, second, third){
        super(name, first, second);
        this.third = third;
    }
    sum(){
        return super.sum()+this.third;
    }
    avg(){
        return (this.first+this.second+this.third)/3;
    }
}
 
var kim = new PersonPlus('kim', 10, 20, 30);
console.log("kim.sum()", kim.sum());
console.log("kim.avg()", kim.avg());
  • super() 와 super. 의 용법은 각각 무엇인가?
    - super(): 부모클래스의 constructor 즉 생성자로서의 역할을 수행한다.
    - super. : 부모클래스 자체를 의미하며 super.XXX에서 XXX에는 부모클래스의 키값이나 메서드가 올수있다.

  • super가 없다면 어떤점이 불편한가? 있다면 어떤점이 편리한가?
    - super가 없다면 값을 추가하고싶을때 부모클래스와 중복되는 코드를 모두 다시 한번 작성해야하기 때문에 효율성이 떨어진다. 하지만 super을 사용하게 되면 부모가 가지고있는 기능들을 모두 가져다 쓸 수 있어서 중복을 제거할 수 있고 유지보수에 좋다.

  • 상속의 기능으로 인해 생기는 단점을 어떻게 보완하는가?
    - 관계의 복잡성은 생기지만 반복을 줄여, 코드의 재사용성을 높여 관계만 잘 파악한다면 유지보수가 용이하다.


객체 간의 상속

__proto__를 이용한 상속 구현

javascript에서는 객체를 직접 다른객체의 자식으로 만들어버릴수있다.
=> subObj의 원형이 무엇인가? 를 가리키는 prototype링크를 정해주면 됨.

let superObj = { superVal: 'super' };
let subObj = { subVal: 'sub' };
subObj.__proto__=superObj; //subObj가 superObj의 자식이다
console.log(subObj.superVal); //super
subObj.superVal='sub'
console.log(superObj.superVal);//super
  • subObj.superVal
    subObj에 superVal프로퍼티가 있는지 찾아본다. 없으니 __ proto__속성이 담고있는 객체에서 superVal을 찾아본다.

  • subObj.superVal='sub'
    객체를 바꾸는거지 객체의 __proto__를 바꾸는게아니다.
    즉 superObj.superVal은 그대로 super이다

__proto__의 좋은점도 있지만, 유연성으로 인한 오류가 잘 발생할 가능성이 있다. 상속받는 방법의 정석은 아니다.. 정석은 따로 있다.

Object.create

__proto__의 대체제로 쓸수있다.

let superObj = { superVal: 'super' };

// let subObj = { subVal: 'sub' };
// subObj.__proto__=superObj; 

// 위 두 줄을 이렇게 쓸 수 있다.

let subObj=Object.create(superObj);
subObj.subVal:'sub';

객체와 함수

call, bind, this의 중요성

  • call
    - call(첫 번째 인자, 두 번째 인자)
    • 첫 번째 인자: 그 함수의 this에 뭐가 올지
    • 두 번째 인자: 호출하려고 하는 함수의 parameter에 들어갈 인자값들이 들어간다.
let kim = { name: 'kim', first: 10, second: 20 };
let lee = { name: 'lee', first: 10, second: 10 };
function sum(){
	return this.first + this.second;
}

//sum();
sum.call(); //sum();이랑 같은 뜻

모든 함수는 call이라는 메소드를 가지고 있다. Javascript 에서는 함수도 객체다.

sum.call(kim);

this = kim 이 된다.

console.log(sum.call(kim)); //30
console.log(sum.call(lee)); //20

sum이 매개변수를 받는다면,

function sum (prefix) {
	return prefix + (this.first+this.second);
    }
sum.call(kim,"hello");

이런식으로 넣어주면 된다.

  • bind
    - sum.bind(kim);
    • sum이라는 함수의 내부적으로 this를 kim으로 하는 새로운 함수가 만들어짐
let kimSum = sum.bind(kim, 'hi');
console.log(kimSum()); // hi 30

sum() 자체에는 영향이 가지 않음.

call과 bind의 차이?

call은 실행되는 함수의 this 값을 원하는 객체로 바꿔서 실행할수있게 해준다.
bind는 실행되는 함수의 this값을 원하는 객체를 고정시키는 새로운 함수를 만들어낸다.

쉽게 말하자면, call은 누구든지 (this)키를 공유해주는 역할이고 bind는 지정(this)인만 사용할 수 있도록 키를 새로 파주는 느낌
call(그때그때 어느 객체나) bind(지정객체)


prototype vs __proto__

누누히 말하지만 함수는 statement 같지만 Javascript에서는 객체다.

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

이런 함수를 정의했다고 보자. 그럼 자동으로 이런 객체가 생성된다


두 객체는 서로 연관되어 있기에 서로의 존재를 알아야한다. 그래서 내부적으로 이런식으로 상호참조한다.


만약

Person.prototype.sum=function() { };
let kim = new Person('kim', 10, 20);

이렇게 코드가 추가된다면

만약 kim.sum()이 실행된다면,
1. kim객체에 해당하는 sum이라는 property가 있나 확인
2. 없으면 __proto__ property를 통해서 가리키고있는 Person's prototype에 sum이 있나 확인

profile
FE개발자가 되고싶은 말하는 감자

0개의 댓글