functionUser(name) {// this = {}; (빈객체가 암시적으로 만들어짐)// 새로운 프로퍼티를 this에 추가함this.name = name;this.isAdmin =false;// return this; (this가 암시적으로 반환)}let user =newUser('보라'); // 인스턴스 객체console.log(user.name); // 보라console.log(user.isAdmin); // false
프로토타입(prototype)
생성자 함수를 만들게 되면 1:1로 매칭되는 함수 멤버로 prototype 속성이 있다.
prototype 객체의 멤버인 constructor 속성은 함수를 참조하는 내부구조를 가진다.
Wrapper Object
래퍼 객체란 이름처럼 원시 타입의 값을 감싸는 형태의 객체이다. number, string, boolean, symbol 데이터 타입에 각각 대응하는 Number, String, Boolean, Symbol이 제공된다.
conststr='apple';console.log(str.length); // 5
🤔 해당 코드가 실행되는 원리는?
해당 코드를 실행하면 결과값은 5가 나온다. 여기서 이상한 점이 발견된다. str은 문자열인 원시타입이다. 객체의 프로퍼티를 접근가능하는 .length를 어떻게 사용할 수 있는 것일까?
자바스크립트의 문자열은 원시타입으로 존재한다. 우리가 문자열의 프로퍼티에 접근하려고 할 때, 자바스크립트는 new String을 호출한 것처럼 문자열 값을 객체로 변환한다. 이 객체를 래퍼객체 라고 한다. 래퍼 객체는 프로퍼티를 참조할 때 생성되며 프로퍼티 참조가 끝나면 사라진다.
conststr='apple';// 👇🏻 해당 코드를 실행하기 위해console.log(str.length); // const str = new String('apple') → 일시적으로 객체로 변환
Class
📖 Class
객체 지향 프로그래밍에서 특정 객체를 생성하기 위해 변수와 메소드를 정의하는 일종의 틀로, 객체를 정의 하기 위한 상태(멤버변수)와 메서드(함수)로 구성된다.
자바스크립트는 class 에 대한 개념이 있지 않았다. 따라서 생성자 함수를 사용해서 정의하곤 했다. ES6에서 class문법이 도입되면서 객체 지향 프로그맹에서 사용되는 다양한 기능을 자바스크립트에서도 사용할 수 있다.
기본문법
class 키워드를 사용
constructor() : 기본 상태를 설정해주는 생성자 메서드 new에 의해 자동으로 호출 된다.
classUser {// 꼭 해당 메서드가 존재해야 한다.constructor(name) {this.name = name; }sayHi() {return`Hello! ${this.name}`; }}constuser=newUser('홍길동');user.sayHi();
상속
extends 키워드를 사용해서 상속 받을 수 있다.
상속을 받는다면 constructor() 내부에 super() 함수가 존재해야 한다.
classShape {// 상속을 하든, 상속을 하지 않든, 반드시 constructor를 가지고 있어야 한다.constructor(color) {this.color = color; }getColor() {returnthis.color; }}classRectangleextendsShape {constructor(color, width, height) {super(color); // 상속받는다면 무조건 super 함수 있어야함.this.width = width;this.height = height; }getArea() {returnthis.width *this.height; }getColor() {return`사각형의 색상은 ${this.color}`; // 👈🏻 오버라이딩 }}
📖 메서드 오버라이딩
상속한 상위 클래스의 메서드를 수정하고 싶거나 더 확장하기 위해 상속 받은 class 내에서 메서드를 재정의하는 행위
get & set
set : 값을 설정하는 키워드
get : 값을 가져오는 키워드
classCar {constructor(speed) {this.speed = speed; }getspeed() {returnthis._speed; }setspeed(value) {this._speed = value <0?0: value; }getSpeed() {returnthis.speed; }// 가정... 수많은 함수들이 구현되어 있다.// 가정... 그 수많은 함수에서 speed를 사용하고 있다.}constcar1=newCar(-100);console.log(car1.getSpeed());
private
2020년 최신 문법
순수 웹브라우저에서는 #private 속성은 get&set를 제어 할 수 없다. (컴파일러 사용 해야한다.)
외부에서 값의 변경을 막고자 할 때 private 속성을 사용한다.
classCar { #speed;constructor(speed) {this.#speed = speed; }getSpeed() {returnthis.#speed; }}constcar1=newCar(100);console.log(car1.getSpeed());// car1.#speed = 100; // 🚨 바꿀수 없다는 error 출력
static
static으로 정의된 것들은 인스턴스화 되지 않는다.
classMathUtils {static APP_NAME ='Math Utils';static PI =3.14;constructor(number) {this.number = number; }staticadd(a, b) {return a + b; }}constmathUtils=newMathUtils(10);console.dir(mathUtils);console.log(MathUtils.PI); // 👈🏻 static은 인스턴스화 되지 않아서 생성자 함수 식별자를 사용해서 접근한다.console.log(MathUtils.add(2,4));