6.27 월 ch.19 ~ 21
자바스크립트는 객체 기반의 프로그래밍 언어이며 자바스크립트를 이루고 있는 거의 "모든 것"이 객체다.
속성을 통해 여러 개의 값을 하나의 단위로 구성한 복합적인 자료구조를 객체라고 하며, 객체지향 프로그래밍은 독립적인 객체의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임이다.
객체지향 프로그래밍은 프로그램을 명령어 또는 함수의 목록으로 보는 전통적인 명령형 프로그래밍의 절차지향적 관점에서 벗어나 여러 개의 독립적 단위, 즉 객체의 집합으로 프로그램을 표현하는 프로그래밍 패러다임을 말한다.
객체 지향 프로그래밍은 실세계의 실체(사물이나 개념)을 인식하는 철학적 사고를 프로그래밍에 접목하려는 시도에서 시작한다. 실체는 특징이나 성질을 나타내는 속성(atribute/property)
을 가지고 있고 이를 통해 실체를 인식하고나 구별할 수 있다.
다양한 속성 중에 프로그램에 필요한 속성만 간추려 내어 표현하는 것 -> 추상화
const circle = {
radius: 5;
//원의 지름 2r
getDiameter() {
return 2 * this.radius;
},
//원의 둘레: 2ㅠr
getPerimeter() {
return 2 * Math.PI * this.radius;
},
//원의 넓이 : ㅠrr
getArea(){
retyrn Math.PI * this.radius ** 2;
}
};
객체지향 프로그래밍은 객체의 상태를 나타내는 데이터와 상태 데이터를 조작할 수 있는 동작을 하나의 논리적인 단위로 묶어 생각한다. 따라서 객체는 상태 데이터와 동작을 하나의 논리적인 단위로 묶은 복합적인 자료구조라고 할 수 있다. 이때 객체의 상태 테이터를 프로퍼티
, 동작을 메서드
라고 부른다.
상속은 객체지향 프로그래밍의 핵심 개념으로, 어떤 객체의 프로퍼티 또는 메서드를 다른 객체가 상속받아 그래도 사용할 수 있는 것을 말한다.
자바스크립트는 프로토타입을 기반으로 상속을 구현하여 불필요한 중복을 제거한다.
중복을 제거하는 방법? -> 기존의 코드를 재사용
//생성자 함수
function Circle(radius){
this.radius = radius;
this.getArea = function(){
//Math.PI는 원주율을 나타내는 상수다.
return Math.PI * this.radius ** 2;
};
}
//반지름이 1인 인스턴스 생성
const circle1 = new Circle(1);
//반지름이 2인 인스턴스 생성
const circle2 = new Circle(2);
-> this.getArea 함수가 불필요하게 중복된다, 이처럼 동일한 생성자 함수에 의해 생성된 모든 인스턴스가 동일한 메서드를 중복 소유하는 것은 메모리를 불필요하게 낭비한다. 또한 인스턴스를 생성할 때마다 메서드를 생성하므로 퍼포먼스에도 악영향을 준다. 만약 10개의 인스턴스를 생성한다면 동일한 메서드도 10개 생성된다.
상속을 통해 불필요한 중복을 없앨 수 있다. -> 자바스크립트는 프로토타빙르 기반으로 상속을 구현한다.
function Circle(radius){
this.radius = radius;
}
//Circle 생성자 함수가 생성한 모든 인스턴스가 getArea 메서드를 공유해서 사용할 수 있도록 프로토타입에 추가한다. 프로토타입은 Cicle 생성자 함수의 prototype 프로퍼티에 바인딩되어 있다.
Circle.prototype.getArea = function(){
return Math.PI * this.radius ** 2;
};
//인스턴스 생성
const circle1 = new Circle(1);
const circle2 = new Circle(2);
//Circle 생성자 함수가 생ㅅ어한 모든 인스턴스는 부모 객체의 역할을 하는 프로토타입 Circle.prototype으로부터 getArea 메서드를 상속받는다. 즉 Circle 생성자 함수가 생성하는 모든 인스턴스는 하나의 getArea 메서드를 공유한다.
console.log(circle.getArea === circle2.getArea); //true
Circle 생성자 함수가 생성한 모든 인스턴스는 자신의 프로토 타입, 즉 상위 객체 역할을 하는 Circle.prototype의 모든 프로퍼티와 메서드를 상속받는다.
프로토타입객체란 객체지향 프로그래밍의 근간을 이루는 객체 간 상속을 구현하기 위해 사용된다. 프로토타입은 어떤 객체의 상위 객체의 역할을 하는 개체로서 다른 객체에 공유 프로퍼티(메서드 포함)를 제공한다. 프로토타입을 상속받은 하위 객체는 상위 객체의 프로퍼티를 자산의 프로퍼티처럼 사용할 수 있다.
모든 객체는 [[prototype]]이라는 내부 슬롯을 가지며 이 내부 슬롯의 값을 프로토타입의 참조에 저장되는 객체 생성 방식에 의해 결정된다.
ex. 객체 리터럴에 의해 생성된 객체의 프로토타입은 Object.prototype이고 생성자 함수에 의해 생성된 객체의 프로토타입은 생성자 함수의 prototype 프로퍼티에 바인딩 되어 있는 객체다.
모든 객체는 하나의 프로토타이을 갖는다. 그리고 모든 프로토타입은 생성자 함수와 연결되어 있다.
모든 객체는 proto 접근자 프로퍼티를 통해 자신의 프로토타입, 즉 [[Prototype]] 내부 슬롯에 간접적으로 접근할 수 있다.
프로토타입은 생성자 함수가 생성되는 시점에 더불어 생성된다. 프로토타입과 생성자 함수는 단독으로 존재할 수 없고 언제나 쌍으로 존재하기 때문이다.
선언하지 않은 변수가 생성되는 암묵적 전역 상태를 해결하기 위해 ES5부터 strict mode가 지원되었다. 이는 자바스크립트 언어의 문법을 좀 더 엄격히 적용하여 오류를 발생시킬 가능성이 높거나 자바스크립트 엔진의 최적화 작업에 문제를 일으킬 수 있는 코드에 대해 명시적인 에러를 발생시킨다.
ESLint같은 린트 도구를 사용해도 유사한 효과르 얻을 수 있다. 린트 도구는 정ㅈ거 분석 기능을 통해 소스코드를 실행하기 전에 소스코드를 스캔하여 문법적 오류만이 아니라 잠재적 오류까지 찾아내고 오류의 원인을 리프팅해주는 유용한 도구다.
린트 도구는 strict mode가 제한하는 오류는 물론 코딩 컨벤션을 설정 파일 형태로 정의하고 강제할 수 있기 때문에 더 강력한 효과를 얻을 수있다. ES6에서 더입된 클래스와 모듈을 기봊겅르ㅗ strict mode가 적용된다.
1. 전역으로 strict mode를 적용하는 것은 피하자
2. 함수단위로 sirict mode를 적용하는 것도 피하자
표준 빌트인 객체
표준 빌트인 객체는 ECMAScript 사양에 정의된 객체를 말하며 애플리케이션 전역의 공통 기능을 제공한다. 표준 빌트인 객체는 자바스크립트 실행환경과 관계없이 언제나 사용할 수 있다. 전역 객체의 프로퍼티로서 제공된다.
호스트 객체
호스트 객체는 ECMAScript 사양에 정의되어 있지는 않지만 자바스크립트 실행환경에서 추가로 제공하는 객체를 말한다.
사용자 정의 객체
사용자 정의 객체는 표준 빌트인 객체와 호스트 객체처럼 기본 제공되는 객체가 아닌 사용자가 직접 정의한 객체를 말한다.
자바스크립트는 object, String, Number, boolean, Symbol. Date....등 40여개의 표준 빌트인 객체를 제공한다. Math, Reflect, JSON을 제외한 표준 빌트인 객체는 모두 인스턴스를 생성할 수 있는 생성자 함수 객체다. 생성자 함수 객체인 표준 빌트인 객체는 프로토타입 메서드와 정적 메서드를 제공하고 생성자 함수 객체가 아닌 표준 빌트인 객체는 정적 메서드만 제공한다.
문자열이나 숫자등의 원시값이 있는데도 문자열, 숫자 객체를 생성하는 String, Number 등의 표준 빌트인 생성자 함수가 존재하는 이유는 무엇일까?
const str ='hello'
// 원시 타입인 문자열이 프로퍼티와 메서드를 가지고 있는 객체처럼 동작한다.
// 이는 원시값에 대해 마치 객체처럼 마침표 표기법으로 접근하며 자바스크립트 엔진이 일시적으로 원시값을 연관된 객체로 반환해 주기 때문이다. 즉 원시값을 객체처럼 사용하면 자바스크립트 엔진은 암죽적으로 연관된객체를 생성하여 생성된 객체로 프로퍼티에 접근하거나 메서드를 호출하고 다시 원시값으로 되돌린다.
console.log(str.length) //5
console.log(str.toUpperCase()); // HELLO
-> 이처럼 문자열, 숫자 불리언 값에 대해 객체처럼 접근하면 생성된느 임시 객체를 래퍼 객체
라 한다.
전역 객체는 코드가 실행되기 이전 단계에 자바스크립트 엔진에 의해 어떤 객체보다도 먼저 생성되는 특수한 객체이며 어떤 객체에도 속하지 않는 최상위 객체이다.
브라우저 환경에서는 window(self, this, frames) Node.js 환경에서는 global이 전역 객체를 가리킨다.
전역객체는 표준 빌트인 객체와 환경에 따른 호스트 객체(클라이언트 WebAPI 또는 Node.js의 호스트 API) 그리고 var 키워드로 선언한 전역 변수와 전역 함수를 프로퍼티로 갖는다.
즉 전역 객체는 계층적 구조상 어떤 객체에도 속하지 않는 모든 빌트인 객체의 최상위 객체다. 전역 객체가 최상우이 객체라는 것은 프로토타입 상속 관계상에서 최상위 객체라는 의미가 아니다. 전역 객체 자신은 어떤 객체의 프로퍼티도 아니며 객체의 계층적 구조상 표준 빌트인 객체와 호스트 객체를 프로퍼티로 소유한다는 것을 말한다.