class요? css class?

c0ng·2023년 2월 7일
0

아니요. 그거 말고요 다른 class가 있다고 합니다 두둥
내가 아는 classid랑 같이 쓰던 그 클래스 밖에 없는데.......🤔


class 이전에 prototype이 있었다

그렇다고 한다.
ES6에서 OPP의 class를 제물삼아 javascript만의 class를 만들었다고 하는데,
그 전엔 prototype이 있었다고 한다.

📌 개념은 egoing님의 youtube 댓글에 달린 쌈빡한 summry

  1. 프로토타입의 의미란?
    : 객체들이 공통으로 사용하는 속성값이다.

  2. 프로토타입이 없을 떄의 비효율적인 점은 무엇인가?
    객체를 생성할 떄마다 같은 동작을 하는 중복적인 메소드가 메모리에 계속 생긴다. => 성능 저하, 메모리 낭비 생김.

  3. 프로토타입을 사용하면 좋은 점은 무엇인가?
    객체들이 공통으로 사용하는 속성값을 정의해서 객체가 생성할때 마다 같은 속성 값을 만드는 과정을 생략해, 성능 향상과 메모리를 효율적으로 이용할 수 있게 해준다.

👻 문법
: 생성자 함수명.prototype.함수명 = function(){ } 로 한번만 정의.

보충 설명
: 프로토타입은 객체를 정의하는 시점이 아닌, 자신이 필요한 시점에서 정의 할 수 있기 때문에
메모리의 이점이 있다. 또한 프로토타입은 생성된 모든 객체가 공통으로 사용할 수 있고
재정의가 가능하기 떄문에 커스터마이징이 가능하다.


자 나와랏 class

construct function의 대체제.
ES6 version 이상에서만 작동함. ❌그 이전 버전에서는 작동 안해여❌
https://caniuse.com 을 통해 작동하는 브라우저 체크하고 사용하자.
또한 https://babeljs.io 은 javascript 트랜스파일러(컴파일러)가 있당!

Class는 객체를 만드는 공장이다

👻 class 안에 초기값을 설정할때는 function을 쓰지 않는다. (필요없다 느꼈나?)

우리가 어떠한 객체를 생성할때, 객체의 초기 상태를 지정하기 위한,
객체가 만들어지기 직전!에 실행되도록 약속되어 있는 함수가 있음. 얘가 바로 constructor(){}

construct는 약속된 거임. 마음대로 하면 안됨

javascript는 객체를 생성할때 construct 함수를 자동으로 실행함


상속

extends

  1. 상속이란 무엇인가?
    상속이란, 하나의 class(constructor)를 정의하고 그 class에서 기능(property)을 추가하려고 할때,
    또다른(자식) class(constructor)를 만들고 기존(부모) class를 상속시켜 기능(property)를 추가 시킨다.

  2. 상속이 없으면 생기는 비효율은?
    부모 class가 내가 작성하는 코드가 아닐 때 혹은 다른 라이브러리를 가져다 썼을 때,
    수정이 불가능하거나 혹여 가능하다고 해도 여러 가지 오류를 범하는 등의 비효율이 생겨날 수 있다.

  1. 상속을 하는 이유
    1. 같은 코드를 중복해서 사용하지 않기 위해서 상속을 사용한다.
    2. 처음에 만든 클래스를 사용하는 코드가 많을 수도 있고 해당 클래스에 기능을 새로추가하면
    사용하고 있는 코드에서 에러가 날 수 있고, 유지보수하기에 용이 하지 않다.
    그래서 새로운 클래스를 생성해서 기존 클래스를 확장시켜 상속해주는 것이 코드 유지보수에 용이하다.
    3. 추가되는 기능을 기존 클래스를 사용하는 곳에서 모두 사용하는 것이 아니기 때문
    따로 클래스를 추가하여 상속한 후 추가된 기능을 사용하는 곳에서만 객체를 생성하여 유지보수 편의성을 증진시킨다.

자바스크립트의 상속은 크게
1. 객체와 객체가 직접 상속
2. 객체를 찍어내는 공장인 class 또는 construct function 을 통해 상속을 할 수 있음

proto (비권장)

__proto__

전통적인 주류 객체지향 언어(JAVA)에서는 클래스가 상속을 받는데,
javaScript에서는 객체가 직접 다른 객체에서 상속을 받을 수 있고, 얼마든지 상속 관계를 바꿀 수 있다.
필요에 의해 다른 객체에 의해 상속을 받고 싶을 때에는 그냥 prototype link를 바궈주면 된다
상속받는 object의 prototype link가 가리키고 있는 객체를 prototype object라고 부른다

class가 아닌 인스턴스 즉, 객체를 직접 다른 객체의 자식으로 만들수 있당(굉장히 쉽게)
A(인스턴스).__proto__ = B(인스턴스)
그러니까 prototype link를 쓰는 방법은 __proto__ 을 통해 A가 B의 자식이다라고 링크를 걸어주는거

근데 prototype__proto__ 가 헷갈리기 시작한다. 혼돈하다 혼돈해

아참 그리고 객체의 값을 바꾸는건 proto의 값을 바꾸는 것과는 틀리다.

let superObj = {superVal : "super"}
let subObj = {subVal : "sub"}
subObj.__proto__ = superObj;

console.log("subObj.subVal => ", subObj.subVal);
console.log("subObj.superVal => ", subObj.superVal);

subObj.superVal = "sub";
console.log("superObj.superVal => ", superObj.superVal);

//subObj.subVal =>  sub
//subObj.superVal =>  super
//superObj.superVal =>  super    -> 보이나, 결국 부모의 프로퍼티를 바꾸는거지 프로토를 바꾸는게 아님

근데 __proto__가 유연한 만큼 복잡하고 ❌사고가 많이 난다고❌ 한다. 주의 요망
아참 그리고 표준으로 인정하지는 않지만 거의 모든 브라우저에서는 제공해주고는 있당.. 사실상 표준상태

proto의 대체제 Object.create() method (권장)

let subObj = {subVal : "sub"}
subObj.__proto__ = superObj;
let subObj = Object.create(superObj);
subObj.subVal = 'sub';

이 둘은 완전 같다.

그러니 Object.create() 를 사용해서 객체와 객체와의 상속관계. 즉 protolink를 지정해주는것이 더 좋은 방법이다.

__proto__ 를 쓰지 않는 건가?
이유는 MDN 참조

IE 9-10부터 지원. 그 이하는 미지원

Super

super
부모 클래스에게 상속받아 자식 클래스를 만들었는데, 자식 클래스에 속성을 추가하려고 한다.
이때 필요한게 super 라는 개념이다.
1. super() : 부모 클래스의 생성자(construct)
2. super.method() : 부모 클래스의 메소드를 참조


👻 기괴한 javascript

여기서 사족 OOP의 입장에서 javascript의 유연함이 기괴함까지로도 느껴진다고 한다. 왜냐
class가 class를 상속하는 것이 아닌 객체가 다른 객체를 상속하는데 그걸 런타임에서 실행되고 있는 동안에 다른걸로 상속을 바꿀수 있어서. -> object.create를 사용해서
그걸로 끝이 아님.
함수도 기괴한 일부임.

함수가 어떤 객체의 종속될수도 있지만, 혼자서도 잘 지내고,
필요에 의해서 어떤 객체의 메소드도 될 수 있음


call

let kim = {name : "kim", first : 10, second : 20}
let lee = {name : "lee", first : 10, second : 10}

function sum(){
    // this = kim
    return this.first + this.second;
}

sum.call(kim); // sum이라는 객체를 실행시킨다 = sum()과 같음

그냥 sum()으로 쓰면 되지 왜 굳이 call 을 붙히냐?
모든 함수는call()이라는 메소드를 가지고 있다. 왜냐? js에서는 함수도 객체이기 때문

call()이라는 메소드에 인자로 넣은 값이 해당 함수의 this 값이 된다

  1. call()을 쓰기 전, sum이라는 함수는 kim이라는 객체의 함수가 아니였다
  2. 근데 call() 의 인자로 sum이 내부적으로 사용할 this 의 값을 지정했더니
  3. sum이라는 함수가 kim의 멤버인 메소드가 되버렸다

call()이라는 함수의 파라미터는 여러개가 올 수 있는데

  1. 첫번째 파라미터는 : 그 함수의 내부적으로 this를 뭘로 할것인가
  2. 두번째 파라미터부터 : 우리가 호출하려는 함수의 파라미터에 들어갈 인자값이 들어감
let kim = {name : "kim", first : 10, second : 20}
let lee = {name : "lee", first : 10, second : 10}

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

console.log("sum.call(kim)" + sum.call(kim, " => ")); 
console.log("sum.call(lee)" + sum.call(lee, " : "));

유사품 apply가 있음. 거의 똑같음. 형식만 다를뿐


bind

call 은 호출 될때마다 this 를 바꾸지만 아예 함수의 내부적으로 사용할 this 를 고정해버리는 방법이 bind

파라미터 설정은 call 과 같다.

bind 를 사용한다고 함수 자체가 바뀐걸까? 그건 아님ㄴㄴ
그냥 새로운 함수가 생성되서 리턴된 것 뿐이어서 기존 함수에는 영향을 미치지 않는다.

call 은 실행할때 함수의 this 을 바꾸고
bind 는 어떤 함수의 this 의 값을 영구적으로 바꾸는 새로운 함수를 만듬.

profile
농부 대장님 아래서 일하는 잡초

0개의 댓글