• 웹 개발에서 WAS는 클라이언트의 요청을 처리하고 동적인 웹 콘텐츠를 생성하는 핵심 컴포넌트이다.
  • 프론트엔드와 백엔드 간의 원활한 통신을 가능하게 하며, 웹 애플리케이션의 성능, 보안, 확장성을 좌우하는 중요한 요소이다.

WAS

  • 웹 애플리케이션을 실행하고 관리하는 서버 소프트웨어
  • 클라이언트로부터 HTTP 요청을 받아 처리하고, 동적인 웹 페이지나 데이터를 생성하여 응답을 반환한다.
  • WAS는 주로 백엔드 로직을 처리하며, 데이터베이스와의 상호작용, 인증 및 권한 관리, 비즈니스 로직 실행 등을 담당한다.

WAS와 Web Server의 차이

  • 웹 서버 : 주로 정적인 콘텐츠들을 제공하며, HTTP 요청을 처리한다.
    • 대표적으로 Apache, Nginx 등이 존재한다.
  • 웹 애플리케이션 서버 : 동적인 콘텐츠를 생성하고, 복잡한 비즈니스 로직을 처리한다.
    • 대표적으로 Tomcat, Jetty, WildFly 등이 있다.

⇒ WAS는 웹 서버와 함께 사용되는 경우가 많으며 웹 서버가 정적인 콘텐츠를 제공하고 WAS가 동적인 처리를 담당하여 효율적인 자원 관리를 가능하게 한다.

WAS의 주요 역할

  1. 동적 콘텐츠 역할
    • 사용자 요청에 따라 동적으로 웹 페이지나 데이터를 생성하여 응답한다.
  2. 비즈니스 로직 처리
    • 애플리케이션의 핵심 기능을 구현하는 로직을 실행한다.
  3. 데이터베이스 연동
    • 데이터베이스와의 상호 작용을 관리하여 데이터를 조회, 삽입, 수정, 삭제한다.
  4. 인증 및 권한 관리
    • 사용자 인증 및 권한 부여를 통해 보안을 유지
  5. 세션 관리
    • 사용자 세션을 관리하여 상태 정보를 유지
  6. 트랜잭션 관리
    • 데이터의 일관성을 유지하기 위해 트랜잭션 관리

WAS의 주요 기능

  1. 로드 밸런싱
    • 여러 대의 서버에 요청을 분산시켜 서버 부하를 줄이고, 가용성을 높임
  2. 클러스터링
    • 여러 대의 WAS 인스턴스를 클러스터로 구성하여 고가용성과 확장성을 제공
  3. 캐싱
    • 자주 요청되는 데이터를 캐시에 저장하여 응답 속도 향상
  4. 보안
    • SSL/TLS 지원, 인증 및 권한 관리, 데이터 암호화 등을 통해 보안을 강화
  5. 모니터링 및 로깅
    • 애플리케이션의 성능을 모니터링하고, 로그를 기록하여 문제를 진단하고 해결
  6. API 관리
    • RESTful API나 GraphQL API를 제공하여 프론트엔드와의 원활한 통신을 지원

프론트엔드와 WAS의 연동

  • 프론트엔드 애플리케이션은 WAS와 API를 통해 데이터를 주고받으며, 사용자 인터페이스를 동적으로 업데이트한다.
  1. API 설계
    • RESTful API 또는 GraphQL을 설계하여 프론트엔드와 백엔드 간의 통신 규약을 정의합니다.
  2. HTTP 요청 처리
    • 프론트엔드에서 fetch 또는 axios 같은 라이브러리를 사용하여 WAS의 엔드포인트에 HTTP 요청을 보냅니다.
  3. 데이터 포맷
    • 일반적으로 JSON 형식을 사용하여 데이터를 주고 받습니다.
  4. 인증 및 권한
    • JWT나 OAuth를 사용하여 인증 및 권한을 관리합니다
  5. 에러 핸들링
    • 프론트엔드에서 백엔드로부터의 에러 응답을 적절히 처리하여 사용자에게 알립니다.
  6. CORS 설정
    • WAS에서 CORS를 설정하여 프론트엔드와의 교차 요청을 허용합니다.

결론

  • WAS는 현대 웹 애플리케이션의 핵심 구성 요소로 프론트엔드와 백엔드 간의 원활한 통신을 지원하고, 애플리케이션의 성능과 보안을 책임집니다. 다양한 WAS가 존재하며, 프로젝트의 요구사항에 맞는 적절한 WAS를 선택하는 것이 중요합니다.
  • WAS의 존재에 대해 잘 몰랐기 때문에 그 동안 서버라고 말하면 모두 웹 서버를 말하는 줄 알았는데 오히려 프론트와의 긴밀한 연결은 WAS와 이어지고 있다는 것을 깨달았습니다. 두 서버가 왜 다른 지 이해했고, WAS를 어떤 시각으로 바라보고 프론트에서 적절하게 사용해야 하는 지 알았습니다.

'TIL' 카테고리의 다른 글

AMP (Accelerated Mobile PAges)  (0) 2024.08.26
React (Redux , Context API, 클래스형과 함수형)  (0) 2024.08.22
자바스크립트의 ES6  (0) 2024.08.21
자바스크립트의 this  (0) 2024.08.20
자바스크립트의 타입  (0) 2024.08.19

AMP

  • Accelerated Mobile Pages
  • AMP는 구글이 주도하는 오픈 소스 프로젝트이다.
  • 웹 페이지가 모바일 장치에서 더 빠르고 효율적으로 로드되도록 설계되었다.
  • AMP는 특히 모바일 환경에서 페이지 로딩 속도를 높여 사용자 경험을 개선하고 검색 엔진 순위를 향상시키는 데 중점을 둔다.

AMP의 주요 요소

AMP HTML

  • AMP HTML은 기존 HTML을 기반으로 하지만, 성능을 향상시키기 위해 제한된 HTML 태그와 기능을 사용한다.
  • 예를 들어, 일부 JS 기능을 사용할 수 없으며, 대신 AMP 프로젝트에서 제공하는 맞춤 태그를 사용한다.

AMP JS 라이브러리

  • AMP JS 라이브러리는 AMP HTML 페이지의 빠른 렌더링을 보장한다. 이 라이브러리는 모든 외부 리소스가 페이지 로딩을 방해하지 않도록 비동기적으로 로드되며, 사용자 정의 요소와 애니메이션의 성능을 최적하한다.

AMP 캐시

  • AMP 페이지는 자동으로 AMP 캐시라는 Google의 CDN에 캐시될 수 있다. 이 캐시는 AMP 페이지를 사전 렌더링하고 최적화 된 상태로 제공하여 로딩 속도를 더욱 향상시킨다.
  • Google 검색 결과에서 AMP 페이지는 번개 아이콘과 함께 표시되며, 즉시 로드된다.

AMP의 원리

  • 리소스 우선순위 지정
  • 광고 및 분석 최적화
  • 레이아웃 제

AMP의 장점

빠른 로딩 속도

  • 모바일 장치에서 웹 페이지의 로딩 속도가 빠르기 때문에 사용자 이탈률이 줄어든다.

SEO 개선

  • Google은 빠르게 로드되는 페이지를 선호하며 이는 검색 엔진 순위에 긍정적인 영향을 끼친다.

브랜딩과 사용자 경험

  • AMP 페이지는 기본 페이지와 스타일이 다를 수 있어, 브랜드 정체성을 유지하기 어려울 수 있다.

AMP의 대안

  • AMP 외의 다양한 웹 성능 최적화 방법 사용하기
    • PWA (Progressive Web App)
      • 오프라인 기능을 제공하면서 성능을 향상시키는 반면, 일반적인 성능 최적화 기법도 AMP의 대안으로 고려될 수 있다.

AMP 리소스

'TIL' 카테고리의 다른 글

WAS ; Web Application Server  (0) 2024.11.13
React (Redux , Context API, 클래스형과 함수형)  (0) 2024.08.22
자바스크립트의 ES6  (0) 2024.08.21
자바스크립트의 this  (0) 2024.08.20
자바스크립트의 타입  (0) 2024.08.19

리액트의 상태 관리

  • 애플리케이션이 커짐에 따라 상태가 어떻게 구성되고 구성 요소 간에 데이터가 어떻게 흐르는 지에 대해 더 의도적으로 생각하는 것은 도움이 된다.
  • 중복되거나 중복된 상태는 버그의 일반적인 원인이다.

Redux

  • 리덕스는 자바스크립트 애플리케이션에서 상태 관리를 간편하게 하기 위해 사용하는 대표적인 라이브러리 중 하나이다. 특히, 리액트와 함께 자주 사용되지만 리덕스는 리액트에 한정되지 않고 모든 자바스크립트 애플리케이션에서 사용할 수 있다.

리덕스의 핵심 개념

  • 스토어
    • 애플리케이션의 상태를 담고 있는 객체이다. 스토어는 단 하나만 존재하며, 이 곳에 애플리케이션의 모든 상태가 저장된다.
  • 액션
    • 상태를 변화시키기 위한 의도를 나타내는 객체이다. 액션은 ‘type’ 이라는 속성을 필수적으로 가져야 하며, 이 외에도 상태 변화를 위한 추가 데이터를 포함할 수 있다.
  • 리듀서
    • 액션을 받아 상태를 업데이트하는 함수이다. 이전 상태와 액션을 인자로 받아 새로운 상태를 반환하는 순수 함수이다.
  • 디스패치
    • 액션을 스토어에 전달하는 함수이다. 디스패치된 액션은 리듀서를 통해 상태를 업데이트되게 한다.
  • 구독
    • 상태가 변경될 때마다 특정 동작을 실행하도록하는 함수이다. 리덕스는 상태가 변경되면 자동으로 리액트 컴포넌트를 다시 렌더링하게 할 수 있다.

리덕스의 작동 원리

graph TD;
    A[사용자의 이벤트 발생] --> B[특정 액션 생성];
    B --> C[디스패치];
    C --> D[리듀서로 전달];
    D --> E[전달받은 액션 + 현재 상태];
    E --> F[새로운 상태가 스토어에 저장];
    F --> G[스토어 상태 업데이트, 해당 상태 구독 시 컴포넌트 재렌더링]

리덕스의 장점

  • 예측 가능하다
    • 상태 변화가 예측 가능하게 이루어지므로 애플리케이션의 동작을 쉽게 파악할 수 있다.
  • 중앙 집중식 관리
    • 모든 상태가 하나의 스토어에서 관리되기 때문에 상태를 추적하기 쉽다.
  • 디버깅 용이성
    • 리덕스 개발 도구를 통해 상태 변화 과정을 시각적으로 확인할 수 있어 디버깅이 용이하다.
  • 유연성
    • 미들웨어를 활용해 비동기 작업이나 로직, 에러 처리 등을 쉽게 추가할 수 있다.

Redux-saga

  • 리덕스 애플리케이션에서 비동기 작업을 관리하기 위한 미들웨어
  • 리덕스 자체는 동기적인 상태 관리에 초점을 맞추기 때문에 비동기 로직을 처리하는 데 추가적인 도구가 필요하기 때문에 만들어졌다.

리덕스 사가의 작동 원리

graph TD;
    A[특정 액션 디스패치] --> B[Watcher Saga가 감지];
    B --> C[액션에 따른 Worker Saga 실행];
    C --> D[비동기 작업 수행];
    D --> E[수행 결과에 따라 액션 재디스패치];
    E --> F[리듀서의 상태 업데이트];
   

Redux-saga를 사용하는 이유

  • 리덕스 애플리케이션에서 비동기 작업이 복잡해질수록 단순한 상태관리에는 한계가 있다.
  • 복잡한 API 호출 순서, 타이밍, 에러 처리 등의 작업이 필요한 경우 매우 유용하다.

옵저버블

  • 옵저버블은 비동기 데이터 스트림을 관리하는 개념이다.
  • 주로 리액티브 익스텐션 라이브러리를 통해 사용된다.
  • 함수형 프로그래밍과 반응형 프로그래밍의 개념을 결합하여 데이터 흐름을 효율적으로 처리하는 도구이다.

옵저버블의 장점

  • 조합성
    • 여러 데이터 스트림을 조합하거나 변환할 수 있어 복잡한 비동기 로직을 간결하게 표현할 수 있다.
  • 유연성
    • 옵저버블은 데이터를 처리하는 시점을 제어할 수 있어 실시간 데이터 흐름을 다루는 데 유리하다.
  • 함수형 프로그래밍
    • 순수 함수와 연산자를 사용하여 데이터를 처리하는 함수형 프로그래밍 스타일 지원한다.

옵저버블과 프로미스 비교

  • 프로미스
    • 단일 비동기 작업의 결과를 나타낸다. 작업이 완료되면 하나의 값을 반환한다.
  • 옵저버블
    • 여러 비동기 이벤트의 스트림을 나타낸다. 여러 개의 값을 발행할 수 있으며, 데이터 흐름을 제어할 수 있다.

Context-API

  • 전역적으로 데이터를 관리하고 여러 컴포넌트 간에 쉽게 데이터를 공유할 수 있도록 도와주는 기능
  • 일반적으로 리액트에서는 데이터가 부모에서 자식 컴포넌트로 props를 통해 전달하지만 깊게 중첩된 컴포넌트 구조에서는 이 방식이 비효율적이기 때문에 사용한다.

Context API의 주요 개념

  • Context
    • 전역적으로 관리하고 있는 데이터를 저장하는 컨테이너 역할.
    • React.createContext() 함수를 사용하여 생성된다.
    • 생성된 Context는 Provider과 Consumer을 통해 데이터를 주고 받습니다.
  • Provider
    • Context에서 제공하는 컴포넌트로 데이터를 전달하는 역할을 한다. Provider은 컴포넌트 트리에서 Context를 구독하는 하위 컴포넌트에게 값을 전달한다. 이 때 Value 속성을 통해 전달할 데이터를 정의한다.
  • Consumer
    • Context에서 제공하는 또 다른 컴포넌트로 데이터를 소비하는 역할을 한다. Consumer은 Context로부터 전달된 데이터를 받아 사용하는 컴포넌트이다. 함수형 컴포넌트는 useContext 훅을 사용하여 더 간단하게 Context 데이터를 소비할 수 있다.
  • useContext
    • 함수형 컴포넌트에서 Context를 쉽게 사용할 수 있게 도와주는 리액트 훅이다. Consumer를 사용하는 것보다 코드가 간결해지고 직관적으로 Context에 접근할 수 있다.

Context API의 장점

  • Prop Drilling 방지
    • 부모에서 자식으로 일일이 ‘Props’를 전달 해야하는 번거로움을 해결할 수 있다. 이를 통해 코드가 더 간결하고 관리하기 쉬워진다.
  • 전역 상태 관리
    • Context API를 사용하면 애플리케이션 전역에서 상태를 관리하고 필요한 곳에서 쉽게 접근할 수 있다. 간단한 상태 관리에서 리덕스 같은 라이브러리 없이도 Context API만으로 충분히 해결할 수 있다.
  • 재사용성
    • Context를 통해 전역적으로 데이터를 관리하면 특정 상태나 설정을 여러 컴포넌트에서 재사용할 수 있다

클래스형과 함수형의 차이

클래스형 컴포넌트

  • ES6을 사용하여 정의된다.
  • 상태와 라이프사이클 메서드를 사용하여 컴포넌트의 동작을 제어한다.
  • this 키워드를 사용해 상태 및 메서드에 접근한다.
  • 장점
    • 상태와 라이프사이클 관리
      • 클래스형 컴포넌트는 상태를 관리하고, 라이프사이클 메서드를 사용하여 컴포넌트의 생명주기를 제어할 수 있다.
    • 오래된 프로젝트에서 많이 사용
      • 리액트 초기에는 상태 관리와 라이프사이클 메서드를 사용해야 할 때 클래스형 컴포넌트가 필수적이다.

함수형 컴포넌트

  • 단순한 자바스크립트 함수로 정의
  • React Hooks를 사용하여 상태 및 라이프사이클을 관리할 수 있다.
  • useState, useEffect 등 다양한 훅을 사용하여 클래스형 컴포넌트에서 사용했던 기능들을 함수형 컴포넌트에서 쉽게 구현할 수 있다.
  • 장점
    • 간결한 코드
      • this 피워드가 필요하지 않아 코드 작성이 더 쉽다.
    • React Hooks의 도입
      • 훅을 사용해 상태 관리, 사이드 이펙트 처리 등을 할 수 있으며, 함수형 컴포넌트에서도 클래스형 컴포넌트의 기능을 모두 사용할 수 있다.
    • 재사용성 및 테스트 용이성
      • 함수형 컴포넌트는 일반 함수처럼 동작하므로, 재사용성과 테스트가 더 용이하다.

라이프사이클 메소드

라이프사이클의 단계

  1. 마운팅
    • 컴포넌트가 DOM에 처음 추가될 때 호출되는 메소드
  2. 업데이트
    • 컴포넌트가 업데이트될 때 호출되는 메소드
  3. 언마운팅
    • 컴포넌트가 DOM에서 제거될 때 호출되는 메소드

출처

https://react.dev/learn/managing-state

'TIL' 카테고리의 다른 글

WAS ; Web Application Server  (0) 2024.11.13
AMP (Accelerated Mobile PAges)  (0) 2024.08.26
자바스크립트의 ES6  (0) 2024.08.21
자바스크립트의 this  (0) 2024.08.20
자바스크립트의 타입  (0) 2024.08.19

Babel 이란?

  • 바벨은 자바스크립트의 트랜스파일러이다.
    • 컴파일 : 한 언어로 작성된 소스 코드를 다른 언어로 변환
    • 트랜스파일: 한 언어로 작성된 소스 코드를 비슷한 수준의 추상화를 가진 다른 언어로 변환
      • 공식 페이지에서는 컴파일러라고 명시하는데 의미상은 트랜스파일러라고 하는 곳도 많아 혼용하는 곳이 많은 것 같다.
  • 주로 ES6 버전을 오래된 브라우저나 환경에 맞추기 위해 이전 버전의 자바스크립트로 변환하는데 사용된다.
  • 바벨이 해줄 수 있는 일은
    • 문법 변환
    • 구형 브라우저에서도 최신 브라우저에서 제공하는 기능을 사용할 수 있도록 해준다.
    • 소스 코드 변환

ES6에서 추가된 스펙

var, let, const

  • var (ES6 이전에도 있던 기존 변수 정의 방식)
    • var로 선언된 변수는 함수 스코프를 가진다.
    • 변수가 선언된 함수 내에서만 유효하고, 블록 내에서 선언해도 해당 블록 외부에서 접근할 수 있다.
    • 호이스팅 문제 : var로 선언된 변수는 선언이 끌어올려지지만 선언과 동시에 할당된 값을 끌어올려지지 않는다.
    • console.log(a); // undefined var a = 10; console.log(a); // 10
  • let
    • let은 블록 스코프 안에서 변수를 정의할 수 있게 해준다.
    • let도 호이스팅이 발생하지만 var과 달리 초기화되지 않은 상태에서 접근하려고 하면 ReferenceError가 발생한다.
    • console.log(b); // ReferenceError let b = 20; console.log(b); // 20
  • const
    • const는 변하지 않는 변수를 지정할 때 사용한다.
    • const 역시 블록 스코프를 가진다.
    • const c = 30; c = 40; // TypeError: Assignment to constant variable. const obj = { name: "Alice" }; obj.name = "Bob"; // 객체의 프로퍼티는 변경 가능 console.log(obj.name); // "Bob"
  • var과의 차이점
    • let은 재선언될 수 없지만, 업데이트 될 수 있다.
    • var 변수는 재선언되고, 업데이트 될 수 있다.
    • const는 재선언도, 업데이트도 불가능하다.

화살표 함수

  • 기존의 함수 표현식에 비해 문법이 짧고 특히 this 키워드의 바인딩 방식에서 차이가 크다.
// 기존 함수 표현식
const add = function(a, b) {
    return a + b;
};

// 화살표 함수 표현식
const add = (a, b) => a + b;
  • function 키워드를 생략하고, 파라미터 목록 뒤에 ⇒ 기호를 사용한다.
  • 암시적 반환
    • 함수 본문이 하나의 표현식인 경우 중괄호를 생략할 수 있으며 해당 표현식의 결과가 자동으로 반환된다.
  • 화살표 함수는 기존 함수 표현식과 달리 this 키워드의 바인딩이 고정된다.
  • 화살표 함수는 자신이 정의된 위치에서 this를 상속받고 this가 호출시점에 변경되지 않는다.

객체 구조분해 할당

  • 객체의 속성을 쉽게 추출하여 변수에 할당하는 기능
  • const person = { name: "Alice", age: 25, job: "Engineer" }; // 객체 구조분해 할당 const { name, age, job } = person; console.log(name); // "Alice" console.log(age); // 25 console.log(job); // "Engineer"

배열 구조분해 할당

  • 배열의 요소들을 쉽게 변수에 할당한다.
  • 객체 구조분해 할당과 비슷하지만 배열의 인덱스를 기준으로 요소를 할당하는 점에서 차이가 있다.
  • const numbers = [1, 2, 3]; // 배열 구조분해 할당 const [a, b, c] = numbers; console.log(a); // 1 console.log(b); // 2 console.log(c); // 3

스프레드 연산자

  • 배열이나 객체의 요소를 개별 요소로 분해하거나 이를 다른 배열 또는 객체에 간단하게 복사하고 병합할 수 있는 방법을 제공한다.
    • 배열 복사
    • 배열 병합
    • 객체 복사
    • 객체 병합
    • 합수 인자 분해

for of 루프

  • 이터러블 객체의 요소들을 반복할 때 사용된다.
    • 이터러블 객체는 배열, 문자열, Map, Set 등과 같이 반복 가능한 값을 가진 객체를 말한다.
    const array = [1, 2, 3, 4];
    
    for (const element of array) {
        console.log(element);
    }
    // 출력: 1, 2, 3, 4
    
    • 배열과 다르게 객체에는 사용할 수 없다.
  • for…of 와 for…in의 차이점
    • of 는 배열, 문자열 등의 값을 반복한다.
    • in은 객체의 키를 반복한다.

템플릿 리터럴

  • 백틱을 사용하여 문자열을 정의하는 법
  • 문자열 내에서 변수를 삽입하고 여러 줄의 문자열도 처리할 수 있다.
  • const name = "Alice"; const greeting = `Hello, ${name}!`; console.log(greeting); // "Hello, Alice!"

클래스

  • 객체 지향 프로그래밍을 지원하는 클래스 문법을 도입
    • 프로토타입 기반 상속을 좀 더 직관적이고 깔끔하게 사용할 수 있도록 한다.
    • 생성자, 메서드, 상속 등을 지원
    class Person {
        // 생성자 메서드
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
    
        // 클래스 메서드
        greet() {
            console.log(`Hello, my name is ${this.name}`);
        }
    }
    
    // 클래스 인스턴스 생성
    const person1 = new Person('Alice', 25);
    person1.greet(); // "Hello, my name is Alice"
    

디폴트 매개변수

  • 함수의 매개변수에 기본값을 설정할 수 있다.
    • 함수 호출 시 인자 제공을 안 하면 기본값을 사용
    function greet(name = 'Guest') {
        console.log(`Hello, ${name}`);
    }
    greet(); // "Hello, Guest"
    

Promise

  • 비동기 작업의 결과를 처리하기 위한 객체
  • 비동기 작업의 성공과 실패를 처리할 수 있다.
    • 정리한 적 있다!
    https://asmallroom.tistory.com/14

출처

https://babeljs.io/docs/

https://www.w3schools.com/js/js_es6.asp

This

  • 대부분의 경우 this의 값은 함수를 호출한 방법에 의해 결정된다.
  • 실행 중에는 할당으로 설정할 수 없고 함수를 호풀할 때마다 다를 수 있다.

ES5의 경우

  • 함수를 어떻게 호출했는 지 상관하지 않고 this 값을 설정할 수 있는 bind 메서드를 도입

ES6의 경우

  • 스스로의 this 바인딩을 제공하지 않는 화살표 함수를 추가

단독으로 쓴 this

  • 냅다 this를 호출하는 경우에 this는 global object를 가리킨다.
    • [object Window]
    'use strict';
     
    var x = this;
    console.log(x); //Window
    
    

함수 안에서 쓴 this

  • 함수 안에서 this는 함수의 주인에게 바인딩된다.
    • 함수의 주인 ⇒ window 객체
    function f1() {
      return this;
    }
    
    // 브라우저
    f1() === window; // true
    
    // Node.js
    f1() === global; // true
    
  • 엄격 모드에서 this 값은 실행 문맥에 진입하며 설정되는 값을 유지한다.
  • function f2() { "use strict"; // 엄격 모드 참고 return this; } f2() === undefined; // true

메서드 안에서 쓴 this

  • 일반 함수가 아니고 메서드인 경우
  • 메서드 호출 시 내부 코드에서 사용된 this는 해당 메서드를 호출한 객체로 바인딩된다.
  • var num = 0; function showNum() { console.log(this.num); } showNum(); //0 var obj = { num: 200, func: showNum, }; obj.func(); //200

이벤트 핸들러 안에서 쓴 this

  • 이벤트 핸들러에서 this는 이벤트를 받는 HTML 요소를 말한다.
  • var btn = document.querySelector('#btn') btn.addEventListener('click', function () { console.log(this); //#btn });

생성자 안에서 쓴 this

  • 생성자 함수가 생성하는 객체로 this가 바인딩 된다.
  • function Person(name) { this.name = name; } var kim = new Person('kim'); var lee = new Person('lee'); console.log(kim.name); //kim console.log(lee.name); //lee // new 키워드를 빼면 일반 함수 호출과 같아져서 window가 바인딩된다.

명시적 바인딩을 한 this

  • 명시적 바인딩은 짝을 짓는다.
    • apply()
      • apply()에서 매개변수로 받은 첫번째 값은 함수 내부에서 사용되는 this에 바인딩된다.
      • 두번째 값인 배열은 자신을 호출한 함수의 인자로 사용한다.
      func.apply(thisArg, [argsArray]);
      
      //인수들의 단일 배열을 받는다.
      
      function Character(name, level) {
        this.name = name;
        this.level = level;
      }
       
      function Player(name, level, job) {
        Character.apply(this, [name, level]);
        this.job = job;
      }
       
      var me = new Player('Nana', 10, 'Magician');
      
    • call()
      function whoisThis() {
        console.log(this);
      }
       
      whoisThis(); //window
       
      var obj = {
        x: 123,
      };
       
      whoisThis.call(obj); //{x:123}
      
    • ⇒ 인자를 this로 만드는 기능
  • 두 메서드 모두 보통 유사배열 객체에게 배열 메서드를 쓰고자 할 때 사용한다.

화살표 함수로 쓴 this

  • 화살표 함수에서 this는 자신을 감싼 정적 범위이다.
  • 전역 코드에서는 전역 객체를 가리킨다.
  • 화살표 함수는 전역 컨텍스트에서 실행되더라도 this를 새로 정의하지 않고, 바로 바깥 함수나 클래스의 this를 쓴다.
  • var Person = function (name, age) { this.name = name; this.age = age; this.say = function () { console.log(this); // Person {name: "Nana", age: 28} setTimeout(() => { console.log(this); // Person {name: "Nana", age: 28} console.log(this.name + ' is ' + this.age + ' years old'); }, 100); }; }; var me = new Person('Nana', 28); //Nana is 28 years old

Call / Apply / Bind

  • Call
    • this를 바인딩하면서 함수를 호출하는 것
    • 두번째 인자를 apply와 다르게 하나씩 넘기는 것
  • Apply
    • this를 바인딩하면서 함수를 호추라는 것
    • 두번째 인자가 배열
  • Bind
    • 함수를 호출하는 것이 아닌 this가 바인딩 된 새로운 함수를 리턴

출처

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this

https://nykim.work/71

'TIL' 카테고리의 다른 글

React (Redux , Context API, 클래스형과 함수형)  (0) 2024.08.22
자바스크립트의 ES6  (0) 2024.08.21
자바스크립트의 타입  (0) 2024.08.19
비동기 프로그래밍 (Callback, Promise, Async/Await)  (0) 2024.08.16
웹 프로토콜  (0) 2024.08.15

 

Number Type

  • 자바스크립트는 일부 다른 언어들과 다르게 숫자를 Number로만 표현한다.
  • 모든 숫자를 포함해야 하기 때문에 모든 수를 실수로 처리한다.
  • Number 타입은 64비트의 고정된 크기의 공간을 확보하므로, 정확하게 표현할 수 있는 숫자의 범위가 제한된다.
  • 만약 이보다 큰 수가 있다면?
    • BigInt()
      • Number가 안정적으로 나타낼 수 있는 최대치인 2^53 - 1보다 큰 정수를 표현할 수 있는 내장 객체이다.
      • BigInt를 사용했다면 BigInt 연산을 유지해야 한다!

원시 타입

  • 자바스크립트에서 원시 값이란 객체가 아니면서 메서드 또는 속성도 가지지 않는 데이터이다.
  • 원시 값에는 7 종류가 있다.
    • string
    • number
    • bigint
    • boolean
    • undefined
    • symbol
    • null
  • 모든 원시 값은 ‘불변’하여 변형할 수 없다.
  • 원시 값 자체와, 원시 값을 할당한 변수를 혼동하지 않는 것이 중요하다.
  • 이미 생성한 원시 값은 객체, 배열, 함수와 달리 변형할 수 없다.

실행 컨텍스트(Execution Context)

  • 실행 가능한 코드에 제공할 환경 정보를 모아놓은 객체
    • 변수 객체, 스코프 체인, this 정보가 담겨있다.
  • 자동으로 전역 컨텍스트가 생성된 후 함수 호출 시 함수 컨텍스트가 생성된 후에 함수 실행
  • 함수 실행이 마무리 될 경우 해당 컨텍스트는 사라지고 페이지가 종료되면 전역 컨텍스트도 사라진다.

실행 컨텍스트의 역할

  1. 전체 코드의 환경과 순서를 보장한다.
    • 환경 정보 객체를 콜 스택에 쌓아올리고 → 가장 위에 쌓여있는 컨텍스트와 관련 있는 코드 실행
  2. 실행 컨텍스트가 활성화되는 시점에 선언된 변수 hoisting
  3. 외부 환경 정보 구성
  4. this 값 설정

호이스팅(Hoisting)

  • 인터프리터가 코드를 실행하기 전 함수, 변수, 클래스 또는 임포트의 선언문을 해당 범위의 맨 위로 끌어올리는 것처럼 보이는 현상
  • 예시
    • 변수가 선언된 줄 이전에 해당 범위에서 변수 값을 사용할 수 있는 값 호이스팅
    • 변수가 선언된 줄 이전 해당 범위의 변수를 참조할 수 있지만 ReferenceError을 던지지 않고 값이 항상 정의되지 않음인 선언 호이스팅
    • 변수 선언 시 변수 선언된 줄 앞의 범위에서 동작이 변경
    • 선언의 부작용은 선언이 포함된 나머지 코드를 평가하기 전 발생

클로저(Closure)

  • 주변 상태에 대한 참조와 함께 묶인 함수의 조합
  • 내부 함수에서 외부 함수의 범위에 대한 접근을 제공
  • 함수 생성 시 함수가 생성될 때마다 생성된다.

→ 중첩된 함수는 외부 범위에서 선언한 변수에도 접근할 수 있다.

실용적인 클로저

  • 어떤 데이터와 그 데이터를 조작하는 함수를 연관시키기 때문에 유용하다.
  • 객체지향 프로그래밍과 같은 맥락

⇒ 오직 하나의 메소드를 가지고 있는 객체를 일반적으로 사용하는 모든 곳에 클로저를 사용 가능

function outter() {
	var title = 'coding everybody';
	return function () {     //return이 나올 시 outter 함수의 생은 마감
		alert(title);          //하지만 그의 자식인 내부함수는 계속 생존해 외부 함수가 남긴 변수 사용
	}
}
inner = outter();
inner();
  • private variable 사용 시 유용하게 사용 가능하다.

클로저의 세 가지 범위

  • 지역 범위
  • 포함하고 있는 범위
  • 전역 범

가비지컬렉터의 역할

  • 개발 시 유효하지 않은 메모리를 가비지라고 일컫는다.
  • 메모리는 제한된 자원이기 때문에, 사용하지 않는 메모리 영역은 다시 사용할 수 있도록 회수되어야 한다. 이 과정을 자동으로 수행하는 것이 바로 가비지 컬렉션
    • 이런 자동 메모리 관리는 개발자가 메모리 관리에 대해 고민할 필요가 없다는 잘못된 인식을 심어줄 수 있다.
  • ⇒ 가비지 컬렉션
  • 참조 추적: 가비지 컬렉터는 메모리 내에서 현재 사용 중인(참조되고 있는) 데이터와 더 이상 사용되지 않는(참조되지 않는) 데이터를 추적한다.
  • 참조 해제: 변수나 데이터가 더 이상 참조되지 않거나 그 참조 값이 null로 설정되면, 가비지 컬렉터는 해당 메모리 영역이 필요하지 않다고 판단한다.
  • 메모리 회수: 필요하지 않은 메모리 영역이 발견되면, 가비지 컬렉터는 이 영역을 해제하여 메모리를 반환하고, 이후 프로그램이 다른 데이터를 저장하는 데 이 메모리를 사용할 수 있도록 한다.

메모리 생존주기

  1. 필요할 때 할당한다.
  2. 할당된 메모리를 사용한다.
  3. 더 이상 필요하지 않으면 해제한다.

값 초기화

  • 프로그래머가 메모리 할당을 신경 쓸 필요가 없도록 JS는 값을 선언할 때 자동으로 메모리를 할당한다.

함수 호출을 통한 할당

  • 함수 호출의 결과 메모리 할당이 일어나기도 한다.
  • 메소드가 새로운 값이나 오브젝트를 할당하기도 한다.

순환참조

  • import 시 발생할 수 있는 순환 참조 에러

메모리 관점에서의 순환 참조

  • 서로 다른 두 객체가 서로를 참조하여, 가비지 컬렉션 알고리즘의 대상에 포함되지 않아 해당 객체들이 불필요해져도 메모리 회수되지 않고 존속하게 되는 문제이다.
function f() {
  const x = {};
  const y = {};
  x.a = y; // x는 y를 참조합니다.
  y.a = x; // y는 x를 참조합니다.

  return "azerty";
}

f();

// 두 객체가 불필요해지는 순간 할당된 메모리가 회수되어야 하지만 두 객체가 서로를 참조하고
 있으므로 참조 - 세기 알고리즘은 둘 다 가비지 컬렉션의 대싱으로 표시하지 않는다. 

이벤트 루프 & 동시성 모델

  • 자바스크립트의 런타임 모델은 코드의 실행, 이벤트 수집과 처리, 큐에 대기 중인 하위 작업을 처리하는 이벤트 루프에 기반한다.
  • 이벤트 루프는 JS의 단일 스레드에서 비동기 코드를 처리할 수 있게 돕는다.
  • JS의 코드 순차적 실행⇒ 비동기 작업이 완료되면 해당 작업의 콜백을 이벤트 큐에 추가
    • 위의 반복적인 행동을 이라고 부른다.
  • ⇒ 이벤트 루프는 콜 스택이 비어있는 지 확인하고 비어있을 경우 이벤트 큐에서 콜백을 가져와 실행
  • ⇒ 비동기 작업 발생 시 작업을 백그라운드로 넘김

동시성?

  • JS는 이벤트 루프를 기반으로 한 동시성 모델이다.
  • 여러가지 작업을 동시에 호출하는 것을 의
  • 이벤트 루프는 코드 실행, 이벤트 수집과 처리, 큐에 존재하는 하위 작업들을 처리한다.

프로토 타입

  • 모든 객체들이 메소드와 속성들을 상속받기 위한 템플릿으로써 프로토타입 객체를 가진다는 의미.
  • 프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메소드와 속성을 상속 받을 수도 있고 그 상위 프로토타입 객체도 마찬가지.
    • 객체가 특정 속성이나 메서드에 접근할 때 해당 객체에 없으면 이 프로토타입 체인을 따라 상위 객체에서 찾는다.
    ⇒ 이를 프로토타입 체인이라 부른다.

출처

https://velog.io/@kados22/FE-기술-면접-실행-컨텍스트가-무엇인가요

https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures

https://developer.mozilla.org/ko/docs/Web/JavaScript/Memory_management

https://mangkyu.tistory.com/118

'TIL' 카테고리의 다른 글

자바스크립트의 ES6  (0) 2024.08.21
자바스크립트의 this  (0) 2024.08.20
비동기 프로그래밍 (Callback, Promise, Async/Await)  (0) 2024.08.16
웹 프로토콜  (0) 2024.08.15
함수형 프로그래밍 (Function Programming)  (0) 2024.08.14

비동기 프로그래밍이란

자바스크립트는 싱글 스레드 언어이기 때문에 한 번에 하나의 작업만을 수행한다.

이를 동기적이라고 한다. 동기 방식은 간단하고 직관적이지만 장기 실행 함수의 경우 응답이 늦어져 전체적인 성능이 저하 된다.

동기적인 프로그래밍의 문제점

: 실행한 동기적 프로그래밍의 결과값이 나오기 전까지는 아무 작업도 시작할 수 없다.

그러면 이를 해결하기 위한 비동기 프로그래밍은 무엇을 해줄 수 있을까

  1. 함수를 호춤함으로써 장기적으로 실행되는 작업을 시작한다.
  2. 이 함수로 작업을 시작하고 즉시 복귀하여 다른 이벤트에 계속 응답할 수 있게 한다.
  3. 작업이 완료되면 결과를 알려준다.

즉, 비동기 함수 실행 시 응답이 오는 것에 상관없이 다른 작업을 이어나가 병렬적으로 작업을 처리할 수 있게 된다. 이는 총 코드 실행 시간을 감소할 수 있게 한다.

비동기 처리의 처리 원리

호출 스택이벤트 루프

  • 비동기 함수의 콜백 함수가 이벤트 루프에 의해 callback queue에 담기고 다시 싱글 스레드인 call stack에 담겨서 콜백 함수가 실행되는 동작 원리

자바스크립트는 싱글 스레드 언어라고 했으면서 어떻게 병렬 처리가 가능한가요

  • 자바 스크립트를 실행하는 Call Stack : 싱글 스레드
  • 서버에게 리소스를 요청하거나 파일 입출력 혹은 타이머 대기 작업을 실행하는 Web APIs : 멀티 스레드

즉, 브라우저가 멀티 스레드이기 때문에 메인 자바스크립트의 싱글 스레드를 차단하지 않고 다른 스레드를 사용하여 Web API의 작업을 처리할 수 있기 때문에 비동기 처리가 가능한 것이다.

비동기 처리의 문제점

  • 만일 그 다음 실행할 작업이 이전에 요청한 작업의 결과가 반드시 필요할 경우 문제가 생긴다.
  • 서버로부터 데이터를 받을 때 비동기 함수의 결과가 동기적으로 실행되는 코드에 영향을 줄 때도 문제가 된다.

작업의 순서를 맞추는 것이 필수 불가결일 경우에 문제가 생긴다.

이를 해결하기 위한 몇 가지 기법 중 가장 대표적인 것은 콜백 함수 기법이다.

콜백 함수

  • 콜백 함수는 자바스크립트의 일급 객체 특성을 이용해 함수의 매개변수에 함수 자체를 넘겨 함수 내에서 매개변수 함수를 실행하는 기법을 말한다.
    • 콜백 함수를 이용함으로써 간접적으로 작업 순서를 끼워 맞출 수 있다.
  • 콜백 함수는 비동기 함수에서 작업 결과를 전달받아 처리하는데 사용되어 작업 순서를 맞출 수 있다.

⇒ 언뜻 문제가 해결되어 보이지만 콜백 함수는 비동기를 순차적으로 처리하기 위한 하나의 조치일 뿐 공식적인 해결 방식은 아니다.

Promise란 무엇인가

  • Promise 객체는 이러한 한계점 극복을 위해 비동기 처리를 위한 전용 객체로서 탄생했다.
  • Promise는 비동기 처리를 위한 전용 객체이다.
    • Promise는 비동기 작업의 성공과 실패를 나눠 그 결과에 따른 코드를 실행할 수 있게 한다.
    ⇒ Promise를 통해 비동기 작업을 쉽고 깔끔하게 연결할 수 있다.
  • const myPromise = new Promise((resolve, reject) => { setTimeout(() => { const success = true; if (success) { resolve("작업 성공!"); } else { reject("작업 실패."); } }, 2000); }); myPromise .then(result => { console.log(result); }) .catch(error => { console.error(error); });

Promise와 Callback

Promise와 Callback의 차이

  • 에러 처리
    • Callback은 단순히 비동기 작업의 결과를 처리하는 데 사용되지만
    • Promise는 비동기 작업의 결과를 완료 / 실패로 나타내어 각 결과에 맞는 코드를 실행할 수 있다.
  • 중첩 문제 해결
    • Callback은 구조가 단순해 중첩이 쉬워 이른바 ~~‘콜백 지옥’~~을 발생시킬 수 있다.
    • Promise는 중첩 문제에서 자유롭고 콜백보다 높은 가독성을 제공한다.
      • Promise 체이닝을 통해 여러 비동기 작업을 간단하게 연결할 수 있으나
      • 작업이 너무 복잡해질 경우 코드가 어려워질 수 있다.
      ⇒ 이 경우 async/await으로 보완이 가능하다.

Async, Await

  • ES8에 해당하는 문법 async / await
  • Callback처럼 Promise에도 Promise Hell이 존재한다. (주로 지나친 then 남용으로 일어난다.)
  • 이를 해결하기 위한 async / await은 프로미스를 기반으로 하지만 마치 동기 코드처럼 쉽게 작성할 수 있게 해준다.

개념

  • async 함수
    • 함수 선언 앞에 async 키워드를 붙이면 해당 함수는 자동으로 Promise를 반환한다.
    • async 함수 내부에서 reuturn 된 값은 자동으로 Promise.resolve()로 감싸져 반환된다.
  • await 키워드
    • await은 async 함수 내부에서만 사용 가능하며, Promise가 해결 될 때까지 함수 실행을 일시 정지한다.
    • await 뒤에 오는 Promise가 해결되면 그 결과값을 반환하고 await은 거부 이유를 throw하여 예외를 발생시킬 수 있다.

예시 코드

async function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = "데이터 로드 완료";
            resolve(data);
        }, 2000);
    });
}

async function main() {
    try {
        const result = await fetchData();
        console.log(result);
    } catch (error) {
        console.error("에러 발생:", error);
    }
}

main();

  • 비동기 코드를 동기식 코드처럼 작성할 수 있어 가독성이 좋다.
  • try/catch 구문으로 오류를 직관적이고 일관되게 처리할 수 있다.
  • 여러 개의 Promise를 더 간단하게 작성할 수 있다.

+) 웹 워커

  • 웹 워커는 브라우저 환경에서 메인 스레드와 독립적으로 백그라운드에서 자바스크립트를 실행할 수 있게 하는 비동기 작업의 일환이다.
  • 무거운 작업을 처리하면서도 UI의 변동 사항이 없기 때문에 사용자 경험을 개선할 수 있다.

예시 코드

// main.js (메인 스레드)
const worker = new Worker('worker.js');
worker.postMessage(1000000000);

worker.onmessage = function(event) {
    console.log('결과:', event.data);
    worker.terminate();
};

// worker.js (웹 워커)
self.onmessage = function(event) {
    let result = 0;
    for (let i = 0; i < event.data; i++) {
        result += i;
    }
    self.postMessage(result);
};

장점

  • UI 반응성 유지
  • 성능 향상
  • 독립적인 환경
    • 웹 워커는 독립된 실행 환경에서 동작하므로 메인 스레드와 충돌 없이 작업을 수행할 수 있다.

출처

https://developer.mozilla.org/ko/docs/Learn/JavaScript/Asynchronous/Introducing

https://developer.mozilla.org/ko/docs/Learn/JavaScript/Asynchronous

'TIL' 카테고리의 다른 글

자바스크립트의 this  (0) 2024.08.20
자바스크립트의 타입  (0) 2024.08.19
웹 프로토콜  (0) 2024.08.15
함수형 프로그래밍 (Function Programming)  (0) 2024.08.14
http와 https의 통신 방법 차이  (0) 2024.08.13

웹 프로토콜

: 웹에서 쓰이는 통신 규약. 웹에서 통신할 때 형식을 맞추자는 일종의 약속과 같다.

 

HTTP (Hyper Text Transfer Protocol)

: HTTP는 브라우저가 웹 서버와 통신하기 위해 사용하는 주요 프로토콜

 

- HTTP의 주요 5가지 요청 형식

: GET - 리소스 조회

: POST - 요청 데이터 처리, 주로 등록

: PUT - 리소스 대체, 해당 리로스가 없을 시 생성

: DELETE - 리소스 삭제

 

- HTTP의 특징

 

: 무상태성 - 상태를 유지하지 않는 Stateless 프로토콜. 즉, 서버는 각각의 요청을 별개의 것으로 처리하며 이전 요청의 정보를 저장하지 않음. => 서버의 부하를 줄이고, 클라이언트와 서버 간의 통신을 단순화하여 처리 속도를 향상.

 

: 비연결성 - Connectionless 프로토콜. 요청과 응답이 한 번 이루어지면 연결을 끊음. 서버 부하를 줄일 수 있지만, 새로운 연결을 맺을 시 시간이 추가로 발생할 수 있음.

 

- HTTP 통신 방식

: '요청'과 '응답'. 어떤 데이터를 '요청' 시 요청 받은 데이터로 '응답'.

즉, Request와 Response 구조로 통신한다. 

Request
Response

IP / MAC / ARP / TCP / UDP

- IP (Internet Protocol)

: 각각의 패킷을 IP 주소와 MAC 주소를 통해 상대방에게 전달하는 역할

: 각 노드에게 부여된 주소를 가르킴

 

*

비연결성

비신뢰성

프로그램 구분이 힘듬

 

- MAC (Media Access Control)

: 각 네트워크에 할당된 '고유의 주소'

 

- ARP (Address Resolution Protocol)

: 유동적인 IP 주소를 고유주소인 MAC 주소로 변환하여 목적지를 찾아감

 

- TCP (Transmission Control Protocol)

: 전송 제어 프로토콜

=> 데이터를 안정적으로, 순서대로, 에러없이 교환할 수 있게 전달한다.

 

- UDP (User Datagram Protocol)

: TCP와 대조되는 전송 프로토콜. 데이터 전달에 대한 안정성을 보장하진 않지만, TCP 보다 빠르다. 

 

- DNS (Domain Name Server)

: 숫자로 되어있는 IP 주소를 우리가 기업하기 쉽게 '문자'로 매핑.

 

인터넷 프로토콜 스택의 4계층

* 각 프로토콜이 완전히 별개의 것이 아니다. 

 

 

 


 출처

https://developer.mozilla.org/ko/docs/Web/HTTP/Overview

+ Recent posts