30 Jun 2021
|
퍼온자료
[펌] 실행 컨텍스트, 렉시컬 환경, 호이스팅
요약 :
-
자바스크립트 엔진은 함수 호출을 만나면 실행 컨텍스트(Execution Context)를 생성하여 콜 스택에 넣는다.
-
실행 컨텍스트의 베이스는 Global Execution Context
이다.
-
자바스크립트 로딩 시 제일 먼저 글로벌 실행 컨텍스트가 생성되고 이 안에 실행 컨텍스트들이 쌓인다.
-
글로벌 실행 컨텍스트의 내부에서 값을 메모리에 할당하고 코드를 구동시킨다.
-
렉시컬 환경(Lexical Environment)은 특정 코드가 작성, 선언된 환경이다.
-
함수 a 안에 변수 b가 선언되었다고 하면 b의 렉시컬 환경이 a가 된다.
-
사용하고자 하는 함수, 변수의 렉시컬 환경이 어디에 속해있는지 아는 것은 매우 중요하다.
-
특히, ‘어디에서 호출했는지’보다는 ‘어디에서 선언했는지’, 즉 렉시컬 환경이 어디인지를 알아야한다.
-
모든 실행 컨텍스트들은 생성 단계와 실행 단계의 작업으로 이루어진다.
-
생성 단계에서 호이스팅이 일어나며 변수, 함수를 각 스코프의 최상단으로 끌어올려 선언하게 된다.
-
변수는 메모리 저장 시 3 단계를 거친다.
-
선언 단계 : 변수를 실행 컨텍스트의 변수 객체에 등록
-
초기화 단계 : 실행 컨텍스트에 등록된 변수에 메모리 할당. undefined로 초기화.
-
할당 단계 : undefined로 초기화된 변수에 값을 할당
-
var는 선언과 초기화가 동시에 진행되어 호이스팅 시 undefined로 초기화된다. 선언 전에 사용이 가능하다.
-
let은 선언과 초기화가 분리되어 진행되기 때문에 호이스팅 시 초기화가 되어있지 않아 이 값에 접근 시 ReferenceError가 발생한다.
-
const는 반드시 선언, 초기화, 할당을 동시에 해주어야한다.
console.log(a);
var a; // undefined
console.log(b);
let b; // ReferenceError
console.log(c);
const c; // Uncaught SyntaxError: Missing initializer in const declaration
a = 1;
b = 2;
-
let은 선언 전에 사용하지 못한다고해서 호이스팅이 일어나지 않는다는 뜻이 아니다.
-
let과 const는 TDZ(Temporal Dead Zone)의 영향을 받아 할당하기 전에는 사용할 수 없다.
참고 자료
자바스크립트의 실행 컨텍스트와 호이스팅
자바스크립트 중급 강좌 #1 - 변수, 호이스팅, TDZ(Temporal Dead Zone)
30 Jun 2021
|
퍼온자료
[펌] 클로저(closure) 넌 대체…
요약 :
렉시컬 환경 (Lexical Environment) : 특정 코드가 작성, 선언된 환경
-
함수와 렉시컬 환경의 조합
-
함수가 생성될 당시의 외부 변수를 기억, 생성 이후에도 계속 접근 가능
function a(x) {
return function(y) {
return x + y;
}
}
const b = a(3);
console.log(b(2)); // 5
처음 전역 렉시컬 환경에 a는 function, b는 초기화가 안된 상태로 정의된다.
const b = a(3);
구문이 실행되면서 a의 렉시컬 환경에 x가 3인 상태로 저장된다.
console.log(b(2));
구문이 실행되면서 a의 return 함수에 대한 렉시컬 환경이 생성되고 y의 값이 2로 저장된다. 따라서, x + y의 값이 5로 찍힐 수 있다. a가 생성된 이후에도 하위 함수에서 상위 함수의 x에 접근이 가능한 것을 볼 수 있는데 이 것을 클로저라고 한다.
-
스코프는 함수를 호출할 때가 아니라 함수를 어디에 선언하였는지에 따라 결정된다. 이를 렉시컬 스코핑이라 한다.
-
클로저가 없다면 상태를 유지하기 위해 전역 변수의 사용이 잦아져 많은 부작용을 일으킬 수 있다.
-
클로저를 사용하면 불변성을 지키고 Side Effect를 최소화 할 수 있다.
-
하지만 클로저를 남발하면 메모리 문제로 오버 플로우가 발생하고 스코프 체인을 거슬러 올라가는 동작이 많아 성능 문제로 이어질 수 있다.
참고 자료
모던 자바스크립트 Deep Dive
[javascript] 클로저(closure)에 대해서 알아보자
zeroCho - 실행 컨텍스트
자바스크립트 중급 강좌 #11 클로저(Closure) 5분만에 이해하기
29 Jun 2021
|
React
Redux-saga (업데이트 예정)
1. redux-saga란?
redux-saga
는 리액트/리덕스 애플리케이션의 사이드 이펙트(fetching 등 비동기 동작들)를 더 쉽고 좋게 만드는 것이 목적이다. 즉, 사이드 이펙트만을 담당하는 별도의 쓰레드와 같은 것으로 ES6의 Generator를 사용하여 비동기 흐름을 동기식 자바스크립트 코드처럼 보이게 한다. redux-thunk와 다르게 액션을 모니터링하고 있다가, 액션 발생 시 특정 작업을 하는 방식으로 사용한다. redux-thunk로 하지 못하는 API 실패시 재요청, 특정 액션 발생 시 다른 액션을 디스패치하거나 자바스크립트 코드 실행, 비동기 작업시 기존 요청 취소 처리 등이 가능하다.
2. Generator
자바스크립트 ES6 문법으로 함수 작성 시 함수를 특정 구간에 멈춰놓거나, 원할 때 돌아가게 할 수 있다. return 값을 여러번 반환하는 것도 가능하다.
제너레이터 함수는 function*
키워드로 함수를 선언한다. 제너레이터 함수 호출 시 생성되는 객체가 제너레이터이다.
function* generatorFunc() {
console.log('Start!');
yield 1;
console.log('제너레이터 함수');
yield 2;
return 3;
}
const generator = generatorFunc();
generator.next(); // Start!, {value: 1, done: false}
generator.next(); // 제너레이터 함수, {value: 2, done: false}
generator.next(); // {value: 3, done: true}
제너레이터는 next 호출 시 인자를 전달하여 제너레이터 함수 내부에서 사용할 수도 있다.
function* generatorSum() {
console.log('Start!');
let a = yield;
console.log('a값 전달 성공!');
let b = yield;
console.log('b값 전달 성공!');
yield a + b;
}
generator.next(); // Start!, {value: undefined, done: false}
generator.next(1); // a값 전달 성공!, {value: undefined, done: false}
generator.next(2); // b값 전달 성공!, {value: 3, done: false}
###
참고 자료
벨로퍼트와 함께하는 모던 리액트 - redux-saga
redux-saga 튜토리얼
28 Jun 2021
|
Javascript
JS Day 18 Webpack
1. 웹팩이란
웹팩이란 React, Vue, Angular 등 최신 FE 프레임워크에서 가장 많이 사용되는 모듈 번들러
이다.
모듈 번들링은 웹 앱을 구성하는 자원들을 하나의 파일로 병합 및 압축해주는 동작이다.
웹팩은 자바스크립트만을 위한 도구가 아니다. HTML, CSS, Javascript, Image, Font 등 웹 애플리케이션과 관련된 모든 모듈을 위한 것이다.
2. 웹팩의 필요성
- 파일 단위의 자바스크립트 모듈 관리
- script로 자바스크립트를 불러와서 사용할 경우, 변수명이 중복되었을때 의도와 다르게 동작할 수 있다.
- 모듈 단위로 자원을 뜯어서 관리하면 필요할때마다 불러서 사용할 수 있다.
- 웹 개발 작업 자동화
HMR (Hot Module Replacement)
- 새로고침 없이 런타임 시점에 업데이트가 가능하다.
- 빠른 로딩 속도와 높은 성능
- 자원을 미리 로딩하는게 아니라 그때그때 요청하여 성능을 향상시킬 수 있다.
3. 웹팩으로 해결하려는 문제
- 자바스크립트 변수 유효범위
- 브라우저별 HTTP 요청 숫자의 제약
- 여러 파일을 병합하여 HTTP 요청 숫자를 줄여 성능을 향상시킬 수 있다.
- 사용하지 않는 코드의 관리
- Dynamic Loading & Lazy Loading 미지원
- 웹팩의
Code Splitting
기능을 이용하여 모듈을 원하는 타이밍에 로딩할 수 있다.
4. 주요 속성
-
entry : 웹팩에서 웹 자원을 번들링하기 위한 최초 진입점. 웹팩이 디펜던시 그래프를 생성하기 위해 사용.
// webpack.config.js
module.exports = {
entry: './src/index.js'
}
// 배열 형태로 전달하여 다중 엔트리 구문 사용 가능
module.exports = {
entry: ['./src/index.js', './src/index2.js', '...']
}
// 멀티 페이지 애플리케이션에 적합한 다중 엔트리 구문
module.exports = {
entry: {
main: './src/main.js',
login: './src/login.js'
}
}
-
output : 웹팩 번들링 후 결과물이 위치할 파일 경로. filename
속성과 path
속성 지정이 필요.
// path는 core Node.js의 모듈이다
var path = require('path');
module.exports = {
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist')
}
}
- 둘 이상의 엔트리 포인트, 코드 분할, 다양한 플로그인을 통해 여러 번들을 생성할 경우 고유이름 지정 방법
filename: '[name].bundle.js
: 결과 파일 이름에 entry 속성을 포함
filename: '[id].bundle.js'
: 결과 파일 이름에 웹팩 내부적으로 사용하는 모듈ID를 포함
filename: [contenthash].bundle.js
: 생성된 콘텐츠에서 생성된 해시 포함
filename: [chunkhash].bundle.js
: 청크의 모든 요소를 포함한 청크의 해시
-
loader : Javascript, Json 파일 이외의 자원을 유효한 모듈로 변환하여 애플리케이션에서 사용
module.exports = {
module: [{
test: /\.m?js$/, // 로더를 적용할 파일 유형 (정규표현식 사용)
exclude: /(node_modules|bower_components)/,
use: { // 해당 파일에 적용할 로더의 옵션
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}]
}
module: {
rules: [
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
}
-
plugin : 플러그인은 웹팩의 기본적인 동작에 추가적인 기능을 제공하는 속성이다.
- 플러그인에는 생성자 함수로 생성한 인스턴스만 추가할 수 있다
module.exports = {
plugins: [
new HtmlWebpackPlugin(), // 웹팩으로 빌드한 결과물로 HTML 파일 생성
new webpack.ProgressPlugin() // 웹팩의 빌드 진행율을 표시
]
}
5. Dev Server
웹팩 데브 서버에서 실행하면 코드 변경 후 새로고침 없이 브라우저에 새로운 코드가 적용된다.
매번 빌드할 필요가 없기 때문에 개발 환경에 필수적인 도구이다.
npm install --save-dev webpack-dev-server
패키지 필요
package.json의 scripts에 dev server로 실행할 'webpack serve'
명령어 기입이 필수
webpack.config.js에서 devServer의 설정이 가능하다.
module.exports = {
devServer: {
port: 9000,
}
}
dev server에서 작업한 내용은 build하기 전까지 실제 파일로 저장되지 않는다. (메모리에 올려 실행하기 때문)
따라서 작업 완료 후 build하여 결과물을 파일로 생성해야한다.
- HMR 설정 : devServer 옵션에서 Hot Module Replacement 설정이 가능하다.
module.exports = {
devServer: {
hot: true
}
}
참고 자료
Webpack
웹팩 핸드북
25 Jun 2021
|
퍼온자료
[펌] Promise.all과 Promise.allSettled 차이
요약 :
Promose.allSettled는 ES2020 / ES11에 새로 추가된 기능이다.
- Promise.all은 여러 Promise 중 하나라도 실패하면 전체가 실패
- Promise.allSettled는 하나가 실패해도 다른 성공한 Promise의 값을 받을 수 있다
- Promise.allSettled는 status에 따라 분기 처리가 필요.
fulfilled
, rejected
참고 자료
Promise.all 과 Promise.allSettled 의 차이
모던 자바스크립트