본문 바로가기

공부/TIL

프로토타입

객체:상태데이터와 동작(프로퍼티)를 하나의 논리적인 묶은 복합적인 자료구조
프로토타입:어떠한 객체의 부모(상위)역할을 하는 객체

객체지향 프로그래밍:프로그램을 여러개의 독립적인 단위(객체)들의 집합으로
표현하려는 패러다임
객체의 상태를 나타내는 데이터와 상태 데이터를 조작할 수 있는 동작을 하나의
논리적인 단위로 묶어서 생각.
->사람은 속성으로 이해, 필요한 속성만을 간추려내는것을 '추상화'

EX)원 - 반지름(상태를 나타내는 데이터) 지름,둘레,넓이(동작)

상속은 객체지향의 핵심개념
자바스크립트는 프로토타입을 기반으로 상속을 구현한다.

프로토타입(객체)라고도함. 
모든 객체는 하나의 프로토타입을 갖는다(프로토 타입은 null이거나 객체이다)
null인것을 최상위 프로토타입 object.prototype이겠지.
그리고 모든 프로토타입은 생성자 함수와 연결되어있다.

모든 객체는 __proto__접근자 프로퍼티를 통해서 자신의 프로토타입 즉 [[prototype]]내부슬롯에 접근가능
단 __proto__접근자 프로퍼티를 코드내에서 직접사용하는것은 비추천
접근자 프로퍼티를 사용하는 이유는 상호참조,순환참조 방지

함수객체의 prototype프로퍼티
함수 객체는 __proto__접근자 이외에 prototype 프로퍼티도 소유, 함수 객체의
prototype프로퍼티는 생성자 함수가 생성할 인스턴스의 프로토 타입을 가리킴

모든 객체가 가지고있는(object.prototype로부터 상속받은) __proto__접근자 프로퍼티와
함수 객체만이 가지고 있는 prototype 프로퍼티는 동일한 프로토 타입을 가리킨다.
사용하는 주체가 다르다.

모든 프로토타입(부모)는 constructor프로퍼티를 갖는다. 자신을 참조하고 이쓴ㄴ
생성자 함수를 가리킨다. 객체가 생성될때 연결된다.

리터럴 표기법에 의해 생성된 객체의 생성자 함수와 프로토타입
리터럴 표기법에 의해 생성된 객체도 물론 프로토타입이 존재한다.
하지만 리터럴 표기법에 의해 생성된 객체의 경우,
프로토타입의 constructor 프로퍼티가 가리키는 생성자 함수가 반드시 객체를 생성한 생성자 함수라고 단정할 수는 없다.
->Object 생성자 함수는 new 연산자와 함께 호출하지 않아도 new 연산자와 함께 호출한 것과 동일하게 동작한다.


함수 객체의 경우, 더욱 차이가 명확하다.
 Function 생성자 함수 방식으로 생성한 함수는 렉시컬 스코프를 만들지 않고 전역 함수인 것처럼 스코프를 생성하며 클로저도 만들지 않는다.
 따라서 함수 선언문과 함수 표현식을 평가하여 함수 객체를 생성한 것은 Function 생성자 함수가 아니다.
 하지만 함수 foo의 의 생성자 함수는 Function 생성자 함수이다.

프로토타입과 생성자 함수는 단독으로 존재할 수 없고 언제나 쌍(pair)으로 존재하기 때문이다.

프로토타입 생성시점
생성자 함수로서 호출할 수 있는 함수, 즉 constructor는 함수 정의가 평가되어 함수 객체를 생성하는 시점에 프로토타입도 더불어 생성된다.
함수 선언문은 다른 코드가 실행되기 이전에 자바스크립트 엔진에 의해 먼저 실행된다.
따라서 함수 선언문으로 정의된 생성자 함수는 어떤 코드보다 먼저 평가되어 함수 객체가 된다.
이때 프로토타입도 더불어 생성된다. 생성된 프로토타입은 생성자 함수의 prototype 프로퍼티에 바인딩된다.
빌트인 생성자 함수가 아닌 사용자 정의 생성자 함수는 자신이 평가되어 함수 객체로 생성되는 시점에 프로토타입도 더불어 생성되며 생성된 프로토타입의 프로토타입은 언제나 Object.prototype이다.


빌트인 생성자 함수와 프로토타입 생성 시점
빌트인 생성자 함수도 일반 함수와 마찬가지로 빌트인 생성자 함수가 생성되는 시점에 프로토타입이 생성된다.
 모든 빌트인 생성자 함수는 전역 객체가 생성되는 시점에 생성된다.
전역 객체는 누구보다도 먼저 생성된다.
 이때 빌트인 생성자 함수와 더불어 프로토타입이 생성된다.
 생성된 프로토타입은 빌트인 생성자 함수의 prototype 프로퍼티에 바인딩된다.


객체 생성 방식과 프로토타입의 결정

객체 리터럴
Object 생성자 함수
생성자 함수
Object.create 메소드
클래스 (ES6)

자바스크립트 엔진은 객체 리터럴을 평가하여 객체를 생성할 때,
 추상 연산 ObjectCreate를 호출한다.
이때 추상 연산 ObjectCreate에 전달되는 프로토타입은 Object.prototype이다.
 즉, 객체 리터럴에 의해 생성되는 객체의 프로토타입은 Object.prototype이다


Object 생성자 함수에 의해 생성된 객체의 프로토타입
Object 생성자 함수에 의해 생성되는 객체의 프로토타입은 Object.prototype이다.

생성자 함수에 의해 생성된 객체의 프로토타입
생성자 함수의 prototype 프로퍼티에 바인딩되어 있는 객체이다.
즉, 생성자 함수에 의해 생성되는 객체의 프로토타입은 생성자 함수의 prototype 프로퍼티에 바인딩되어 있는 객체이다.


프로토타입 체인.
객체의 프로퍼티에 접근할때 접근하려는 프로퍼티가 없다면 __proto__접근자 프로퍼티가
가리키는 링크를 따라 자신의 부모 역할을 딸라 프로퍼티를 순차적으로 검색
상속과 프로퍼티 검색을 위한 메커니즘

프로퍼티가 아닌 식별자는 스코프 체인에서 검색
스코프 체인은 식별자 검색을 위한 메커니즘
스코프 체인과 프로토타입 체인은 별도로 서로 연관없이 동작하는 것이 아니라 서로 협력하여 식별자와 프로퍼티를 찾아낸다.

캡슐화 즉시실행함수를 통해 생성자 함수와 프로토타입을 확장하는 코드를 하나의 함수내에 모음

오버라이딩 : 상위클래스가 가지고 있는 메소드를 하위 클래스가 재정의하여 사용

오버로딩: 함수 이름은 동일하지만 매개변수의 타입 또는 개수가 다른 메소드를 구현하고
매개 변수에 의해 메소드를 구별하여 호출하는 방식

프로토타입의 교체
프로토타입은 다른 임의의 객체로 변경할 수 있다.
이것은 부모 객체인 프로토타입을 동적으로 변경할 수 있다는 것을 의미한다.
이러한 특징을 활용하여 객체 간의 상속 관계를 동적으로 변경할 수 있다.
프로토타입은 생성자 함수 또는 인스턴스에 의해 교체할 수 있다.

교체한 프로토타입에는 constructor가없고, 체인이 파괴됨

Object.create 메소드는 첫번째 매개변수에 전달한 객체의 프로토타입 체인에 속하는 객체를 생성한다.
즉, 객체를 생성하면서 직접적으로 상속을 구현하는 것이다.
이 메소드의 장점은 아래와 같다.

1.new 연산자가 없이도 객체를 생성할 수 있다.
2.프로토타입을 지정하면서 객체를 생성할 수 있다.
이때 생성자 함수와 프로토타입 간의 링크가 파괴되지 않는다.
3.객체 리터럴에 의해 생성된 객체도 상속받을 수 있다.

정적(static) 프로퍼티/메소드는 생성자 함수로 인스턴스를 생성하지 않아도 참조/호출할 수 있는 프로퍼티/메소드를 말한다.


프로퍼티 존재 확인
in 연산자는 확인 대상 객체의 프로퍼티 뿐만 아니라 확인 대상 객체가 상속받은 모든 프로토타입의 프로퍼티를 확인하므로 주의하기 바란다

프로퍼티 열거
객체의 모든 프로퍼티를 순회하며 열거(enumeration)하려면 for…in 문을 사용한다.

반응형

'공부 > TIL' 카테고리의 다른 글

DOM  (0) 2019.05.23
배열의 고차함수  (0) 2019.05.20
number, math, string 객체  (0) 2019.05.17
0516  (0) 2019.05.16
0515  (0) 2019.05.15