
js는 함수형 프로그래밍.
js의 클래스는 자바에서의 클래스 아닌, 특별한 함수로 치환해서 동작.
클래스 키워드 썼지만 함수형태로 변환해 동작.
자바 최상위 오브젝트 클래스처럼 js도 오브젝트 Prototype 존재.
toString 사용 가능한 이유.
대부분 객체는 __proto__ (프로토 링크) 속성 갖고 있음.
함수도 객체! 실행 가능한 객체 (1급 객체)이기 때문에 프로토 링크 갖고있음.
상속 기능 구현 위해 상위 객체의 주소 정보 갖고 있는 속성.
객체 생성하면 자동으로 프로토 링크 통해 오브젝트 타입 객체 연결.
강제로 프로토링크에 매핑하는 것은 좋지 않다! 성능 문제.
상속은 Object.create() 사용하자.
현재는 클래스 키워드의 extends 사용해 상속 구현.
extends도 프로토타입으로 다시 변환되면서 만들어지는 것.
예전에는 프로토링크 이용해 상속 구현했음.
let human = {
name : ...,
run : function() {
...
}
}
let john = {
name : "john"
}
// 강제 매핑
john.__proto__ = human;
john.run();
__proto__와 바라보는 객체 동일. 둘 다 프로토타입이라고 부름.
함수에만 존재하는 속성.
prototype은 Human이라는 빈 객체와 연결됨.
서로 순환 참조하는 형태.
function Human() {
this.name = "human";
this.run = function() {
...
}
}
let john = new Human();
john.name = "john";

new 키워드는 함수에만 사용 가능.
객체에는 사용 X.
내부적으로 우측 객체의 constructor 함수 호출 -> 일반 객체는 constructor 함수 존재 X.
new 키위드로 만들어진 john은 객체.
new 사용하면 Human 내부 constructor 함수 실행해서 임의 객체 만들고 속성 모두 매핑.

john의 프로토링크는 Object 바라봐야 정상, but js 엔진에서 함수의 prototype 바라보도록 바꿈.
let david = new Human();
david.name = "david";
david.run();
// 함수에 넣은 것 아니고 프로토타입에 명시
Human.prototype.fight = function() {
...
}
프로토타입 객체는 constructor와 프로토링크만 갖고 있는 빈 객체.
프로토타입에 함수 명시하면 john.fight() 해도 정상 동작함.

john.fight() 하면 john 내부에서 fight 찾음.
없으니 프로토링크 찾아서 올라감 -> Human prototype에서 찾음.
메모리에는 john과 david 두개 만들어짐.
Human 내부 함수인 run()은 두개 메모리에 각각 만들어짐. -> 불필요!
proto에 정의된 fight()는 새로운 Human 객체에 들어가지 않고 proto에만 남아있음.
new 생성된 모든 객체는 동일 prototype 참조.
-> 추가, 생성에 용이하고 메모리 적게 사용.

새로 만든 객체와 proto 사이는 Implicit Link로 연결됨.
새로 생성된 객체 안에서 this.getNmae으로 proto 내부의 속성에 접근, 수정 가능.
BUT proto의 getName 수정되는 것 아닌, this가 가리키는 새로운 Person 객체에 새로운 속성이 부여됨.
// 함수를 임의 변수에 대입 (저장)
Human.prototype.$fight = Human.prototype.fight;
Human.prototype.fight = funtion(name) {
// 재정의 (override) 후
console.log(`age : ${this.age}`);
// 저장해둔 fight call
// 오버라이드 재정의하면 동작 안할 수 있으므로 임의 변수에 저장 후 call 해서 사용
Human.protype.$fight.call(this, name);
}
Polymer의 override.html에도 같은 동작 방식.

함수는 1급 객체!
변수에 대입 가능하고, 실행도 가능.
// 함수를 Human 함수 객체에 넣는 경우
Human.walk = function() {
...
}
let john = new Human();
// 에러
// Uncaught TypeError : john.walk is not a function
// Human.prototype.walk = function() {...} 이렇게 하면 정상 동작.
john.walk();
// 정상 동작
Human.walk.call(john);

john에서 walk 찾음.
-> 없으므로 프로토링크 찾아 올라가 Human prototype에서 찾음.
-> 없으므로 프로토링크 찾아 올라가 Object에서 찾음.
-> 없으므로 종료!
new로 만들어도 못찾음.
new 키워드 명시되면 함수의 constructor 실행.
함수 내에서 객체 생성.
해당 스코프 내에 있는 변수들 매핑.
walk는 스코프 내에 없으므로 매핑하지 않음.
Function.property/Function은 자바의 static과 비슷하게 동작.
Human.walk.call(john) 이런 식으로 사용 가능.
class Human {
// public
name = "human";
// private
#id = "123";
static BLOOD_TYPE = ["A", "B", "O", "AB"];
constructor(name) {
this.name = name;
}
walk() {
console.log("walk!");
}
}
let john = new Human("john");
john.walk();
js는 함수형 프로그래밍이기 때문에 클래스는 개발자 편의 위해 만들어진 것. (엔진이 클래스 -> 함수형태로)
자바의 클래스 객체와 다름.
내부적으로 함수 형태로 바꿈.

Human {name: 'john', #id" '123}
js는 자바의 new 키워드 문법을 채택해 사용한다.
Es6 이전에는 클래스 개념이 존재하지 않기 때문에 자바와 다른 방식을 채택해 사용했다.
자바는 객체 -> 클래스로 정의하지만 js는 함수로 정의.
js의 클래스는 자바 클래스의 생성자와 유사.
function을 사용하지 마라