객체 지향 프로그래밍은 상태를 나타내는 데이터와 상태 데이터를 조작할수 있는 동작을 하나의 논리적 단위로 묶어 생각함. 객체는 상태 데이터와 동작을 하나의 논리적 단위로 묶은 복합적 자료구조라 할수 있다. 객체의 상태를 프로퍼티, 동작을 메서드라 부름.
자바스크립트는 prototype기반으로 상속을 구현함. 프로토 타입은 생성자 함수의 prototype프로퍼티에 바인딩 된다
Circle 생성자 함수가 생성한 모든 인스턴스는 자신의 프로토타입, 상위 개게 역할하는 Circle의 모든 프로퍼티, 메서드 상속
모든 객체는 proto ( IE 11이상 , ES6 표준)접근자 프로퍼티 통해 자신의 프로토타입 [[ prototype]] 내부 슬롯에 간접 적으로 접근 가능.
이때 proto 는 객체가 직접 소유하는 프로퍼티가 아니고 Object.prototype의 프로퍼티임. 상속을 통해 Object.prototype.proto 접근자 프로퍼티 사용가능
이때, 직접 상속을 통해 Object.prototype을 상속 받지 않은 객체 생성도 가능해 proto 사용 불가능 한 경우가 있어서 직접 사용하는것 권장안함
예) 프로토타입 체인의 종점이라던가 이럴때는 Object.getPrototypeOf 메서드를 사용하고 → es5으로 IE9이상
프로토 타입 교체 할때는 Object.setPrototypeOf 사용 → es6으로 IE11이상
모든 객체는 프로토타입 계층 구조인 프로토 타입 체인에 묶여있음
함수 객체 프로퍼티: 생성자 함수가 생성할 인스턴스의 프로토타입. 생성자 호출 불가능한 non-constructor 인 화살표 함수, ES6메서드 축약 표현으로 정의한 메서드는 프로퍼티 없고 프로토 타입 생성도 안함
즉,
proto : 모든 객체가 갖고 있고 프로토타입의 참조, 모든 객체가 자신의 프로토타입에 접근, 교체위해 사용
prototype: constructor 가 가지고 있고, 생성자함수가 자신이 생성할 객체의 프로토타입 할당위해 사용
프로토타입은 생성자함수가 생성되는 시점에 생성됨
Person 입력 전에는 undefuned뜸. 생성자 함수로 호출 불가능한 화살표 함수(non- constructor) 생성되지 않음 ..
객체 리터럴 : 객체 리터럴 내부에 프로퍼티 추가함
Object 생성자 함수: 빈객체 생성후 프로퍼티 추가
프로토타입 체인 : 자바스크립트가 객체 지향 프로그램 상속을 구현하는 메컨니즘. 프로퍼티(메서드포함)에 접근하려고할때 해당 객체에 접근하려는 프로퍼티 없으면 내부 슬롯 참조 따라 부모 역할하는 프로토타입 프로퍼티 순차적 검색.
스코프체인 : 식별자 검색을 위한 메커니즘 . 스코프의 계층적 구조에서 식별자 검색.
오버라이딩: 상위클래스가 가지고 있는 메서드하위 클래스에서 재정의해 삿용
오버로딩: 함수이름은 같으나 매개변수의 타입 개수가 다른 메섣 구현하고 매개변수에 의해 메서드 구분해 호출. 자바스크립트는 오버로딩 지원안하나 argument 객체통해 구현은 가능
프로퍼티 삭제하고 싶으면 하위 객체를 통하면안되고 직접 그객체로 가서 delete로 삭제해야함.
프로토타입은 생성자 함수/ 인스턴스로 교체 가능
프로토타입은 생성자 함수의 prototype 프로퍼티 뿐만아니라 인스턴스의 proto 접근자 프로퍼티를 통해 접근가능(getProtoTypeOf) 그래서 포로토타입 교체(setPrototypeOf) 가능.
생성자함수로 프포토타입 교체하면, 생성자함수의 prototype프로퍼티가 교체된프로토 타입 가르킴
인스턴스에 의해 프로토타입교체 - 생성자 함수의 protoType프로퍼티가 교체된 프로토타입 가리키지 않음 .
프로토타입 교체 상속관계 동적으로 변경하는ㄴ거 번거로워서 직접교체 비추
: 생성자 함수의 prototype에 바인딩된 객체가 프로토타입 체인상에 존재 여부 확인
객체 instanceOf 생성자함수
이때, 생성자함수의 prototype에 바인딩 객체가
프로로타입 체인상에 존재하면 t 아니면 f
Object.create메서드, 첫번쨰 매개변수에 전달한 객체의 프로토타입체인에 속하는 객체 생성. 즉 객체를 생성하면서 직접 상속으로 구현함
→ new 없이 객체 생성가능, 프로토타입 지정하면서 객체 생성가능, 객체리터럴에 의해 생성된 객체 상속가능
Object.create(proto, [propertiesObject])
Object.create(객체1, (객체2))
객체1 : 생성할객체의 프로토타입으로 지정할 객체
객체2 : 생성할객체의 프로퍼티 키,
디스크립터 객체로 이루어진 객체
그러나, ESLint에서는 비권장함. Object.create 메서드로 프로토타입 체인의 종점에 있는 객체 생성이 가능. 프로토타입 체인 종점에 있는 객체는 Object.prototype 빌트인 메서드 사용 할수 없음 => 간접적으로 호출해야함.
방법2 ) ES6
객체 리터럴 내부에서 proto 에 의한 직접상속
생성자 함수로 인스턴스 생성 안해도 참조 호출 가능한 프로퍼티/ 메서드
프로토타입 메서드 호출하려면 인스턴스 생성하나 정적 메서드는 인스턴스 생성 안해도 호출가능
인스턴스/프로토타입 메서드 내에 this 사용안하면 메서드는 정적 메서드로 변경 가능. 인스턴스가 호출한 인스턴스/프로토 타입 내에서 this 는 인스턴스 가리킴. 메서드내에서 인스턴스 참조 필요 없으면 정적 메서드로 변경해도 동작함.
Object.__ 정적메서드 Object.create 같은거 → 생성자함수가 생성한 객체로 호출 불가
Object.prototype.__ 프로토타입 메서드 Object.prototype.hasOwnProperty 같은거
이떄 prototype을 #이라 표기하기도함 Object.#.isPrototypeOf
key in Object
in은 확인 대상 객체의 프로퍼티 외에 확인 대상 객체가 상속 받는
모든 프로토 타입 프로퍼티 확인함..!
ES6에서는 Reflect.has( , )메서드 사용가능
Object.prototype.hasOwnProperty 메서드로 객체에 특정한 프로퍼티 존재 확인가능 → 상속 받은 프로토타입프로퍼티일때는 false 이게 위의 in, Reflect.has와 다른점
for (변수선언문 in 객체 ){... } 문
프로퍼티 개수만큼 객체 순회하여 열거함. 이때 상속받은 프로퍼티 열거하나 toString은 열거가 안됨 어트리뷰트가 [[ Enumerable]]이라서 열거불가능
즉, for in 문은 프로토타입 체인상에 존재하는 모든 프로토 타입프로퍼티중 프로퍼티 어트리뷰트 [[ Enumerable]]의 값이 t인것만 열거
상속받은 프로퍼티 제외하고 객체 잦신의 프로퍼티 열거하고 싶으면 Object.prototype.hasOwnproperty 메서드로 확인해야함
for in 문은 순서 보장하지 않음. 알아서 숫자, 문자열 프로퍼티 키에 정렬함.
배열할땐 for..in 문 말고 일반적인 for문이나 for..of 문 Array.prototype.forEach 메서드 사용 권장. 배열도 객체라 상속받은 프로퍼티 포함될수있음
자신의 고유한 프로퍼티 열거할땐 for..in 대신
Object.key 객체 자신의 열거가능한 프로퍼티 키를 배열로 반환
Object.values 객체 자신의 열가능한 프로퍼티 값 배열로 반환 (Es8도입 )
Object.entires: 객체 자신의 열거 가능한 프로퍼티 키와 값의 쌍의 배열을 배열에 담아 반환 (Es8도)입 사용 권장