
[면접을 위한 CS 전공지식 노트] 책을 사놓고 이제야 읽기 시작했다...!
시간 있을 때 미리미리 공부를 열심히 해두자 !!!
고럼 레쓰고
class Singleton {
constructor() {
if (!Singleton.instance) {
Singleton.instance = this
}
return Singleton.instance
}
getInstance() {
return this
}
}
const a = new Singleton();
const b = new Singleton();
console.log(a === b) // true
// 전달받은 값에 따라 다른 객체를 생성하며 인스턴스 타입 정함
const num = new Object(42);
const str = new Object('abc');
num.constructor.name; // Number
str.constructor.name; // String
class CoffeeFactory {
// 정적 메서드 => 클래스 기반으로 객체 만들지 않고 호출 가능
// 해당 메서드에 대한 메모리 할당을 한 번만 할 수 있음
static createCoffee(type) {
const factory = factoryList[type]
return factory.createCoffee()
}
}
class Latte {
constructor() {
this.name = "latte"
}
}
class Espresso {
constructor() {
this.name = "Espresso"
}
}
class LatteFactory extends CoffeeFactory{
static createCoffee() {
return new Latte()
}
}
class EspressoFactory extends CoffeeFactory{
static createCoffee() {
return new Espresso()
}
}
const factoryList = { LatteFactory, EspressoFactory }
const main = () => {
const coffee = CoffeeFactory.createCoffee("LatteFactory")
console.log(coffee.name) // latte
}
main()
특징
옵저버 패턴은 MVC 패턴에도 사용됨 (모델-주체 에 변경 사항이 생기면 update() 메서드로 옵저버인 뷰에 알려줌 → 컨트롤러 작동)JS의 옵저버 패턴
프록시 객체
// Proxy 객체 : 속성 접근, 할당 등등 작업을 가로채서 로직 강제
const handler = {
get: function(target, handler) {
return name === 'name' ? `${target.a} ${target.b}` : target[name]
}
}
const p = new Proxy({ a: 'YOOJIN', b: 'ZZANGZZANG' }, handler)
console.log(p.name) // YOOJIN ZZANGZZANG
프록시 객체를 이용한 옵저버 패턴
function createReactiveObject(target, callback) {
const proxy = new Proxy(target, {
// proxy 객체의 set()으로 속성에 대한 접근 가로채서 변화 감시
set(obj, prop, value) {
if (value !== obj[prop]) {
const prev = obj[prop];
obj[prop] = value;
callback(`${prop}이 [${prev}] >> [${value}]로 변경됨`);
}
return true;
}
})
return proxy;
};
const a = {
"윶": "직장인"
};
const b = createReactiveObject(a, console.log);
b.윶 = "직장인";
b.윶 = "백수";
// 윶이 [직장인]에서 [백수]로 변경됨
get()은 속성, 함수에 대한 접근을 가로챔has()는 in 연산자의 사용 가로챔set()은 속성에 대한 접근을 가로챔특징
프록시 서버
서버와 클라이언트 사이에서 클라이언트가 자신을 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 시스템 or 응용 프로그램
CDN을 프록시 서버로 캐싱 가능
nginx
CloudFlare
CORS와 프론트엔드의 프록시 서버
CORS : 서버가 웹 브라우저에서 리소스 로드시 다른 오리진을 통해 로드하지 못하게 하는 HTTP 헤더 기반 메커니즘
프론트에 프록시 서버를 둬서 프론트 서버에서 요청되는 오리진을 백엔드 서버 오리진으로 바꿔줌
const mp = new Map();
mp.set('a', 1);
mp.set('b', 2);
mp.set('c', 3);
const st = new Set();
st.add(1);
st.add(2);
st.add(3);
// 이터레이터 프로토콜 : for a of b
for (let a of mp) console.log(a);
for (let a of st) console.log(a);
/*
['a', 1]
['b', 2]
['c', 3]
1
2
3
*/
set, map 다른 자료구조인데도 똑같이 for a of b (이터레이터 프로토콜)로 순회const pukuba = (() => {
const a = 1;
const b = () => 2;
const public = {
c: 2,
d: () => 3
}
return public
})();
console.log(pukuba);
// { c: 3, d: [Fuction: d] }
console.log(pukuba.a, pukuba.b);
// undefined undefined
(() => {})(), 선언 동시에 실행)를 통해 private, public 같은 접근 제어자를 만드는 패턴ModelViewController커맨드(여러 요소를 한 액션으로 처리)와 데이터 바인딩(화면에 보이는 데이터와 웹 브라우저의 메모리 데이터 일치시키기)을 가짐특징
순수 함수
const pure = (a, b) => {
return a + b;
};
const list = [1, 2, 3, 4, 5, 11, 12];
const ret = list.reduce((max, num) => num > max ? num : max, 0)
console.log(ret) // 12
고차 함수
특징
추상화 | 복잡한 시스템에서 핵심적인 개념이나 기능 간추림캡슐화 | 객체의 속성과 메서드를 하나로 묶고 일부를 외부에 감춤상속성 | 상위 클래스 특성을 하위 클래스가 이어받아서 재사용, 추가, 확장다형성 | 하나의 메서드나 클래스가 다양한 방법으로 동작 (오버로딩, 오버라이딩)SOLID 설계 원칙
S(단일 책임 원칙) : 모든 클래스는 각각 하나의 책임만 가져야 하는 원칙O(개방-폐쇄 원칙) : 유지보수 사항 있을 땐 코드를 쉽게 확장해야 하고, 수정할 땐 닫혀있어야 함 (기존 코드는 잘 변경하지 X, 확장은 쉬워야 한다)L(리스코프 치환 원칙) : 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 함 (클래스의 부모 객체에 자식 객체를 넣어도 시스템에 문제없어야 함)I(인터페이스 분리 원칙) : 하나의 일반적인 인터페이스보다 구체적인 여러 인터페이스를 만들어야 함D(의존 역전 원칙) : 자신보다 변하기 쉬운 것에 의존하던 것을 추상화된 인터페이스나 상위 클래스를 두어 의존성을 없애는 원칙
진짜 열심히 작성하셨네요!
언제나 응원하고 있습니다!