Web

    Observer Pattern

    이 글은 Patterns.dev 사이트를 참고하여 작성한 시리즈 입니다. Observer Pattern 옵저버블을 사용해 이벤트가 발생할 때 구독자에게 알리기 옵저버 패턴을 사용하면 특정 객체(object)나 옵저버(observer)를 옵저버블(observable)이라 불리는 다른 객체를 구독(subscribe)할 수 있습니다. observable 객체는 일반적으로 3가지 중요한 요소를 포함합니다. observers: 특정 이벤트가 발생할 때마다 알림을 받는 observer 배열 subscribe(): observers에 observer를 추가하는 메소드 unsubscribe(): observers에서 observer를 삭제하는 메소드 notify(): 특정 이벤트가 발생할 때마다 모든 observer..

    Proxy Pattern (JavaScript)

    이 글은 Patterns.dev를 참고하여 작성한 시리즈 입니다. Proxy Pattern 대상 객체에 대한 상호작용 가로채기 및 제어 Proxy 객체를 사용하면 특정 객체와 상호작용을 보다 효과적으로 제어할 수 있습니다. 프록시 객체는 값을 얻거나 설정할 때 등 상호작용할 때의 동작을 설정할 수 있습니다. 일반적으로 프록시는 다른 사람의 대리인을 의미합니다. 상대방과 직접 대화하는 대신, 당신이 대화하려고 했던 사람을 대신할 대리인과 대화합니다. JavaScript에서도 마찬가지 입니다. 원본 객체와 대화하는 대신 Proxy 객체와 대화합니다. -> 원본 객체를 Immutable하게 사용할 수 있습니다. 먼저 yeon 객체를 생성합니다. 저를 나타내는 객체입니다. 이 객체와 직접 상호작용 하는 대신 프..

    Singleton Pattern (JavaScript)

    이 글은 Patterns.dev를 참고하여 작성한 시리즈 입니다. Singleton Pattern 애플리케이션 전체에서 단일 인스턴스 공유 싱글턴 패턴은 한 번의 인스턴스화가 가능한 클래스로 글로벌하게 엑세스할 수 있습니다. 이 단일 클래스는 애플리케이션 전체에 공유할 수 있기 때문에 애플리케이션의 글로벌 상태를 관리하는 데 적합합니다. 먼저 Counter 클래스를 작성해보겠습니다. Counter 클래스는 다음과 같은 메소드를 제공합니다. getInstance: 인스턴스를 반환합니다. getCount: 현재 counter 값을 반환합니다. increment: 카운터를 1 증가시킵니다. decrement: 카운터를 1 감소시킵니다. 위 클래스는 싱글턴의 기준을 충족시키지 못합니다. 싱글턴은 한 번만 인스턴..

    타입 좁히기 (Type Guard)

    타입 좁히기는 타입스크립트를 넓은 타입으로부터 좁은 타입으로 진행하는 과정을 말합니다. null 체크 존재하지 않을 때 null을 반환하는 메소드나 함수의 경우 if 문을 통한 null 체크를 통해 타입 좁히기를 할 수 있습니다. instanceof 생성자의 프로토타입 속성이 객체 프로토타입 체인 어딘가에 존재하는 여부를 확인할 수 있는 instanceof 연산자를 if문과 사용해서 타입을 좁힐 수 있습니다. 속성 체크 (in) 프로퍼티가 존재하는지 확인할 수 있는 in 연산자를 통해 타입을 좁힐 수 있습니다. 내장 함수 사용 Array.isArray 같이 타입을 판별할 수 있는 내장함수를 사용하여 타입을 좁힐 수 있습니다. tagged union 패턴 사용 명시적으로 태그를 붙여 타입을 좁힐 수 있습니..

    TypeScript Intersection & Union

    타입스크립트의 타입은 타입들의 집합을 표현해 타입의 범위를 명확하게 표현하는 것입니다. 아래 코드를 Intersection(교집합)을 사용한 코드를 살펴봅시다. Intersection 처음 코드를 보았을 때 Person은 name을 갖고 있고 Lifespan은 birth와 death 프로퍼티를 갖고 있기 때문에 교집합이 없어서 never(공집합)이라고 생각했습니다. 아래 Union(합집합) 코드도 살펴봅시다. Union 합집합이기 때문에 모든 property를 갖고 있어야하지 않나? 생각할 수 있지만 그렇지 않습니다. type의 집합이기 때문에 interface를 정의하면 아래와 같습니다.

    프로토타입

    자바스크립트는 프로토타입 기반의 객체지향 프로그래밍 언어다. 클래스 es6에서 클래스가 도입되었다. 클래스도 함수이며, 기존 프로토타입 기반 패턴의 문법적 설탕이라고 볼 수 있다. 클래스는 생성자 함수보다 엄격하며 생성자 함수에서는 제공하지 않는 기능도 제공한다. __proto__접근자 프로퍼티 모든 객체는 proto 접근자 프로퍼티를 통해 자신의 프로토타입, 즉 [[Prototype]] 내부 슬롯에 간접적으로 접근할 수 있다. 내부 슬롯은 프로퍼티가 아니며 일부 내부 슬롯과 내부 메서드에 한하여 간접적으로 접근할 수 있는 수단을 제공하기는 한다. proto 접근자 프로퍼티를 코드 내에서 직접 사용하는 것은 권장하지 않는다. Object.protytpe을 상속받지 않는 객체를 생성할 수또 있기 때문에 p..

    렉시컬 스코프

    var x = 1; function foo() { var x = 10; bar(); } function bar() { console.log(x); } foo(); // ? bar(); // ? 위 예제의 실행 결과는 bar 함수의 상위 스코프가 무엇인지에 따라 결정된다. 두 가지 패턴을 예측할 수 있다. 1. 함수를 어디서 호출했는지에 따라 함수의 상위 스코프를 결정한다. 2. 함수를 어디서 정의했는지에 따라 함수의 상위 스코프를 결정한다. 첫 번째 방식으로 함수의 상위 스코프를 결정한다면 bar 함수의 상위 스코프는 foo함수의 지역 스코프와 전역 스코프일 것이다. 이 방식을 동적 스코프라 한다. 함수가 호출되는 시점에 동적으로 상위 스코프를 결정해야 하기 때문에 동적 스코프라 부른다. 두 번째 방식으..

    라인 피드와 캐리지 리턴

    IDE(VSCode)로 협업하며 개발을 하다 보면 문제가 없는 코드에 lint error 밑줄이 그어져 있는 경우가 있다. 이는 서로 운영체제가 달라서 그런데 Windows의 경우는 CRLF macOS는 LF를 사용하기 때문에 그렇다. LF는 라인 피드, CR을 캐리지 리턴을 의미하는데, 캐리지 리턴(\r)은 종리를 움직이지 않고 커서를 맨 앞줄로 이동하는 것이다. 초창기 컴퓨터는 출력을 프린터로 수행했는데, 이때 개행을 위해 라인피드와 캐리지 리턴을 모두 사용했다. 즉, CRLF(\r\n)로 커서를 맨 앞으로 이동시키고 종이를 한 줄 올리는 방식으로 개행했다. 자바스크립트에서 라인 피드와 캐리지 리턴은 모두 개행을 의미한다. 하지만 캐리지 리턴(/r)으로 개행하는 경우는 거의 없고 일반적으로 라인피드(..

    Http Cache Control

    웹 사이트와 애플리케이션의 성능은 이전에 가져온 리소스들을 재사용함으써 현저하게 향상될 수 있습니다. 웹 캐시는 레이턴시와 네트워크 트래픽을 줄여줌으로써 리소스를 보여주는 데에 필요한 시간을 줄여줍니다. 캐싱은 주어진 리소스의 복사본을 저장하고 있다가 요청 시에 그것을 제공하는 기술입니다. 캐싱 동작의 대상 HTTP 캐싱 캐시들을 인반적으로 GET에 대한 응답만을 캐싱합니다. 기본 캐시 키는 요청 메서드 그리고 대상 URI로 구성됩니다. (GET 요청만을 대상으로 하므로 URI만 사용되는 경우가 많습니다.) 캐싱 제어 Cache-control 해더 Cache-Control HTTP/1.1 기본 해더 필드는 요청과 응답 양측 모두에 있어 캐싱 매커니즘을 위한 디렉티브를 지정하는데 사용됩니다. 캐시하지 않음..

    자주 사용하는 정규표현식 [ javascript ]

    자주사용하는 정규표현식 숫자를 포함하는 문자 const reg = /\d+/; console.log(reg.test("123")); // true console.log(reg.test("33asd")); // true console.log(reg.test("5asdasd")); // true console.log(reg.test("asdfasdf")); // true 숫자만 포함하는 문자 const reg = /^\d+$/; console.log(reg.test("123")); // true console.log(reg.test("33asd")); // false console.log(reg.test("5asdasd")); // false console.log(reg.test("asdfasdf")); /..