
아니요. 그거 말고요 다른 class가 있다고 합니다 두둥
내가 아는 class는 id랑 같이 쓰던 그 클래스 밖에 없는데.......🤔
그렇다고 한다.
ES6에서 OPP의 class를 제물삼아 javascript만의 class를 만들었다고 하는데,
그 전엔 prototype이 있었다고 한다.
📌 개념은 egoing님의 youtube 댓글에 달린 쌈빡한 summry
프로토타입의 의미란?
: 객체들이 공통으로 사용하는 속성값이다.
프로토타입이 없을 떄의 비효율적인 점은 무엇인가?
객체를 생성할 떄마다 같은 동작을 하는 중복적인 메소드가 메모리에 계속 생긴다. => 성능 저하, 메모리 낭비 생김.
프로토타입을 사용하면 좋은 점은 무엇인가?
객체들이 공통으로 사용하는 속성값을 정의해서 객체가 생성할때 마다 같은 속성 값을 만드는 과정을 생략해, 성능 향상과 메모리를 효율적으로 이용할 수 있게 해준다.
👻 문법
: 생성자 함수명.prototype.함수명 = function(){ } 로 한번만 정의.
보충 설명
: 프로토타입은 객체를 정의하는 시점이 아닌, 자신이 필요한 시점에서 정의 할 수 있기 때문에
메모리의 이점이 있다. 또한 프로토타입은 생성된 모든 객체가 공통으로 사용할 수 있고
재정의가 가능하기 떄문에 커스터마이징이 가능하다.
construct function의 대체제.
ES6 version 이상에서만 작동함. ❌그 이전 버전에서는 작동 안해여❌
https://caniuse.com 을 통해 작동하는 브라우저 체크하고 사용하자.
또한 https://babeljs.io 은 javascript 트랜스파일러(컴파일러)가 있당!
Class는 객체를 만드는 공장이다
👻 class 안에 초기값을 설정할때는
function을 쓰지 않는다. (필요없다 느꼈나?)
우리가 어떠한 객체를 생성할때, 객체의 초기 상태를 지정하기 위한,
객체가 만들어지기 직전!에 실행되도록 약속되어 있는 함수가 있음. 얘가 바로 constructor(){} 임
javascript는 객체를 생성할때 construct 함수를 자동으로 실행함
extends
상속이란 무엇인가?
상속이란, 하나의 class(constructor)를 정의하고 그 class에서 기능(property)을 추가하려고 할때,
또다른(자식) class(constructor)를 만들고 기존(부모) class를 상속시켜 기능(property)를 추가 시킨다.
상속이 없으면 생기는 비효율은?
부모 class가 내가 작성하는 코드가 아닐 때 혹은 다른 라이브러리를 가져다 썼을 때,
수정이 불가능하거나 혹여 가능하다고 해도 여러 가지 오류를 범하는 등의 비효율이 생겨날 수 있다.
자바스크립트의 상속은 크게
1. 객체와 객체가 직접 상속
2. 객체를 찍어내는 공장인 class 또는 construct function 을 통해 상속을 할 수 있음
__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__가 유연한 만큼 복잡하고 ❌사고가 많이 난다고❌ 한다. 주의 요망
아참 그리고 표준으로 인정하지는 않지만 거의 모든 브라우저에서는 제공해주고는 있당.. 사실상 표준상태
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 라는 개념이다.
1. super() : 부모 클래스의 생성자(construct)
2. super.method() : 부모 클래스의 메소드를 참조
여기서 사족 OOP의 입장에서 javascript의 유연함이 기괴함까지로도 느껴진다고 한다. 왜냐
class가 class를 상속하는 것이 아닌 객체가 다른 객체를 상속하는데 그걸 런타임에서 실행되고 있는 동안에 다른걸로 상속을 바꿀수 있어서. -> object.create를 사용해서
그걸로 끝이 아님.
함수도 기괴한 일부임.
함수가 어떤 객체의 종속될수도 있지만, 혼자서도 잘 지내고,
필요에 의해서 어떤 객체의 메소드도 될 수 있음
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 값이 된다
call()을 쓰기 전, sum이라는 함수는 kim이라는 객체의 함수가 아니였다call() 의 인자로 sum이 내부적으로 사용할 this 의 값을 지정했더니call()이라는 함수의 파라미터는 여러개가 올 수 있는데
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가 있음. 거의 똑같음. 형식만 다를뿐
call 은 호출 될때마다 this 를 바꾸지만 아예 함수의 내부적으로 사용할 this 를 고정해버리는 방법이 bind
파라미터 설정은 call 과 같다.
bind 를 사용한다고 함수 자체가 바뀐걸까? 그건 아님ㄴㄴ
그냥 새로운 함수가 생성되서 리턴된 것 뿐이어서 기존 함수에는 영향을 미치지 않는다.
call 은 실행할때 함수의 this 을 바꾸고
bind 는 어떤 함수의 this 의 값을 영구적으로 바꾸는 새로운 함수를 만듬.