클래스
- ES6이후 등장한 개념
- 리액트 16.8 버젼 : 클래스형 컴포넌트(생명주기 함수) -> 함수형 컴포넌트
- 특정한 객체를 만들기 위한 일종의 템플릿

class Car {
	constructor(name) {
    	this.name = name
    }
    
    honk() {
    	console.log(`${this.name}이 경적을 울립니다.`);
    }
    
    static hello() {
    	console.log('저는 자동차입니다.')
    }
    
    set age(value) {
    	this.carAge = value
    }
    
    get age() {
    	return this.carAge
    }   
}

const myCar = new Car('자동차');

myCar.honk(); 
Car.hello();
myCar.hello; // Uncaught TypeError: myCar.hello is not a function

myCar.age = 32;
console.log(myCar.age, myCar.name); // 32 자동차

 
 
constructor
- 생성자
- 하나만 존재 가능, 생략도 가능
 
프로퍼티
- 클래스의 속성값
- JS에서 기본적으로 모든 프로퍼티 값은 public
- ES2019부터 #를 붙여서 private 선언 가능
 
✓ getter / setter
- 클래스에서 무언가 값을 가져올 때 사용
- 예약어 get / set 사용
 
✓ 인스턴스 메서드
- 클래스 내부에 선언한 메서드
- 자바스크립트의 prototype에 선언 : Object.getPrototypeOf(인스턴스) === 클래스.prototype cf)인스턴스.__proto__ 
-> 프로토타입의 메서드, 프로토타입에 선언되었기 때문에 프로토타입 체이닝을 통해 새로 생성한 인스턴스 메서드에서 부모 클래스의 메서드에 접근 가능(위 예제 honk()의 경우)
 
✓  정적 메서드 
- 예약어 static 사용
- 클래스의 인스턴스가 아닌 이름으로 호출
- 정적 메서드 내부의 this : 클래스로 생성된 인스턴스가 아닌, 클래스 자신을 가리킴 
- 인스턴스를 생성하지 않아도 사용 가능
- 재사용성
- ex) 애플리케이션 전역에서 사용하는 유틸 함수
 
✓ 상속
- 에약어 extends 사용
- 기존 클래스를 상속받아서 자식 클래스에서 이 상속받은 클래스를 기반으로 확장하는 개념
 
✓ 클래스와 함수의 관계
- ES6이전에는 자바스크립트 프로토타입을 활용해 클래스의 작동 방식을 동일하게 구현
- 객체지향 언어를 사용하던 다른 프로그래머가 좀 더 자바스크립트에 접근하기 쉽게 만들어주는 Syntactic sugar 역할
- 리액트에서 클래스형 컴포넌트 생성 시 React.Component, React.Purecomponent 상속

// 바벨로 변환
'use strict'

// 클래스가 함수처럼 호출되는 것을 방지
function _classCallCheck(instance, Constructor) {
	...
}

// 프로퍼티 할당
function _defineProperties(target, props) {
	...
}

// 프로토타입 메서드와 정적 메서드 선언
function _createClass(Constructor, protoProps, staticProps) {
	...
}

 
 
클로저
- 리액트 함수 컴포넌트는 대부분 클로저 방식에 의존 cf) 리액트 클래스 컴포넌트 : 클래스, 프로토타입, this
- 함수와 함수가 선언된 어휘적 환경(Lexical Scope)의 조합
- Lexical Scope : 변수가 코드 내부에서 어디서 선언되었는지
- 호출되는 방식에 따라 동적으로 결정되는 this와 다르게 코드가 작성된 순간에 정적으로 결정
- 클로저는 이러한 어휘적 환경을 조합하여 코딩하는 기법
 
✓ 스코프(Scope)
- 변수의 유효 범위 
 
✓  전역 스코프(Global scope)
- 전역 레벨에 선언
- ex) 브라우저 window, Node.js Global

var global = 'global scope';

console.log(global === window.global) // true

 
✓  함수 스코프
- 자바스크립트는 기본적으로 함수 레벨 스코프를 따름
- { } 블록이 스코프 범위를 결정하지 않음

if (true) {
	var global = 'global scope';
}

console.log(global); // global scope
console.log(global === window.global); // true

function hello() {
	var local = 'local variable';
    console.log(local); // local variable
}

hello();
console.log(local); // Uncaught ReferenceError: local is not defined

 
✓ 클로저의 활용
- 자바스크립트는 함수 레벨 스코프를 가지고 있으므로, 스코프는 동적으로 결정

function outerFunction() {
	var x = 'hello';
    function innerFunction() {
    	console.log(x);
    }
    return innerFunction;
}

const innerFunction = outerFunction();
innerFunction() // hello

- outerFunction이 innerFunction을 반환하였고, innerFunction에는 x라는 변수가 존재하지 않지만, 해당 함수가 선언된 어휘적 환경(outerFunction)에는 x가 존재하며 접근할 수 있으므로 정상적으로 'hello'출력 가능
- 전역 스코프는 어디에서든 접근할 수 있으므로 보안에 취약 -> 클로저 활용
- 리액트에서 클로저 : useState
- 클로저에서 var 보다 let, const 사용 권장
- 클로저는 생성될 때 마다 그 선언적 환경을 기억해야 하므로 비용 발생 -> 스크립트를 실행하는 시점부터 클로저를 메모리에 올려두고 시작
 

+ Recent posts