Coder Social home page Coder Social logo

til's Introduction

Hits

Hi,I'm Raegon. I'm working as a software engineer at Samsung.

My works

  • 2021.04 ~ : Samsung Podcasts / Server
  • 2020.06 ~ : TF / Server
  • 2019.11 ~ 2020.06 : Samsung Members / Server
  • 2019.04 ~ 2019.12 : Game Launcher / Server
  • 2016.07 ~ 2017.05 : Marshmallow / Server
  • 2015.02 ~ 2019.11 : Samsung Music / Server
  • 2014.03 ~ 2015.01 : Papergarden / Android Client / Magazine service for galaxy devices.
  • 2012.11 ~ 2014.03 : Samsung Hub / Android Client / First landing page for music, video, books, games and learning services.
  • 2011.03 ~ 2012.10 : Android Settings Application

Get in touch

til's People

Contributors

raycon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

til's Issues

Variables

변수

값에 지정된 상징적인 이름이다. 변수의 이름은 식별자(identifier)라고 불리며 특정 규칙을 따른다.

문자, 밑줄(_)이나 달러($) 기호로 시작해야 하고 문자, 숫자나 밑줄을 포함할 수 있습니다.

선언

var : 실행 문맥에 따라 지역, 전역 변수를 선언한다.

if (true) {
  var x = 5;
}
console.log(x);  // x is 5

const, let : 블록 스코프 지역 변수를 선언한다.

if (true) {
  let y = 5;
}
console.log(y);  // ReferenceError: y is not defined

변수를 선언할 때, 구조 분해 할당(Destructing assignment) 구문을 사용해서 객체 리터럴로부터 값을 가져올 수 있다.

var { bar } = foo; // where foo = { bar:10, baz:12 };
/* This creates a variable with the name 'bar', which has a value of 10 */

초기값

var, let으로 선언되고 값이 할당되지 않은 변수는 undefined 값을 갖는다.

undefinednull은 Number 문맥과 Boolean 문맥에서 다음과 같이 사용된다.

           | Number | Boolean |
undefined  | NaN    | false   |
null       | 0      | false   |

Hoisting

자바스크립트에서 변수는 함수(function)나 구문(statement)의 최상단으로 hoisted (or lifted) 된다. 호이스팅된 변수는 undefined 값을 갖는다.

console.log(x === undefined); // true
var x = 3;
var myvar = 'my value';

(function() {
  console.log(myvar); // undefined
  var myvar = 'local value';
})();

let, const로 선언된 변수는 호이스팅 되지만, 초기화 되지는 않는다. 이 변수를 사용하면 ReferenceError가 발생한다.

console.log(x); // ReferenceError
let x = 3;

함수 선언(declaration)은 호이스팅 되지만, 함수 표현식(expression)은 호이스팅 되지 않는다.

/* Function declaration */

foo(); // "bar"

function foo() {
  console.log('bar');
}

/* Function expression */

baz(); // TypeError: baz is not a function

var baz = function() {
  console.log('bar2');
};

전역 변수

전역 변수는 전역 객체의 속성(property)이다. 브라우저에서 전역 객체는 window이므로, window.variable 구문을 통해서 변수를 선언하거나 접근할 수 있다.

리터럴

Literal고정된 값을 의미한다. 자바스크립트 내부에서 문자 그대로(literally) 선언된다.

Array literals

let coffees = ['French Roast', 'Colombian', 'Kona']; // length of the array is 3
let myList = ['home', , 'school', , ]; // home, undefined, school, undefined

Boolean literals

Boolean 타입은 true, false 두가지 리터럴 값을 갖는다. Boolean 객체의 true, false 값과는 다르다.

Numeric literals

Number, BigInt는 10진수, 8진수(0, 0o, 0O), 16진수(0x, 0X), 2진수(0b, 0B) 값을 가질 수 있다.

0, 117, -345, 123456789123456789n             (decimal, base 10)
015, 0001, -0o77, 0o777777777777n             (octal, base 8)
0x1123, 0x00111, -0xF1A7, 0x123456789ABCDEFn  (hexadecimal, "hex" or base 16)
0b11, 0b0011, -0b11, 0b11101001010101010101n  (binary, base 2)

Floating-point literals

부동소수점 값을 의미한다.

3.1415926
-.123456789
-3.1E+12
.1e-23

Object literals

객체 리터럴은 중괄호({})로 둘러 싸인 속성(property)의 이름과 값의 목록이다.

var car = { manyCars: {a: 'Saab', b: 'Jeep'}, 7: 'Mazda' };

console.log(car.manyCars.b); // Jeep
console.log(car[7]); // Mazda

속성 이름이 유효한 식별자나 숫자가 아닐 경우, 따옴표("")로 묶어야 한다. 이러한 속성은 점(.)이 아니라 배열 같은 표기법([])으로 접근하고 값을 설정할 수 있다.

var unusualPropertyNames = {
  "": "An empty string",
  "!": "Bang!"
}
console.log(unusualPropertyNames."");   // SyntaxError: Unexpected string
console.log(unusualPropertyNames[""]);  // An empty string
console.log(unusualPropertyNames.!);    // SyntaxError: Unexpected token !
console.log(unusualPropertyNames["!"]); // Bang!

ES2015 부터 Enhanced Object literals을 사용할 수 있다.

var obj = {
    // __proto__
    __proto__: theProtoObj,
    // Shorthand for ‘handler: handler’
    handler,
    // Methods
    toString() {
     // Super calls
     return 'd ' + super.toString();
    },
    // Computed (dynamic) property names
    [ 'prop_' + (() => 42)() ]: 42
};

RegExp literals

var re = /ab+c/;

String literals

문자열 리터럴은 큰 따옴표(") 혹은 작은 따옴표(')로 묶인 0개 이상의 문자를 의미한다.

문자열 리터럴 값은 문자열 객체의 모든 메서드를 호출할 수 있다. JavaScript는 자동으로 문자열 리터럴을 임시 문자열 객체로 변환, 메서드를 호출하고 나서 임시 문자열 객체를 폐기한다. 또한 문자열 리터럴에서도 String.length 속성을 사용할 수 있다.

ES2015 부터 Template literals을 사용할 수 있다.

// Basic literal string creation
`In JavaScript '\n' is a line-feed.`

// Multiline strings
`In JavaScript, template strings can run
 over multiple lines, but double and single
 quoted strings cannot.`

// String interpolation
var name = 'Bob', time = 'today';
`Hello ${name}, how are you ${time}?`

// Construct an HTTP request prefix used to interpret the replacements and construction
POST`http://foo.org/bar?a=${a}&b=${b}
     Content-Type: application/json
     X-Credentials: ${credentials}
     { "foo": ${foo},
       "bar": ${bar}}`(myOnReadyStateChangeHandler);

tmux

tmux

설치

sudo apt install tmux

용어

  • Session: tmux의 실행 단위
  • Window: 세션을 구성하는 화면 단위
  • Pane: 윈도우를 구성하는 화면 단위
  • Prefix: tmux 명령을 실행하기 위해 입력하는 키, 기본값: Ctrl+B, <C-b> 로 표현.

명령

  • <C-b> 입력 후 명령 키를 누른다.
  • <C-b> 입력 후 : 를 눌러서 명령어 모드로 진입한다.

$가 붙은 명령은 쉘에서 실행하는 명령어를 의미한다.

Session

# 새 세션 생성
$ tmux
$ tmux new
$ tmux new -s <session-name>

# 세션 이름 변경
<C-b> $

# 세션 중단
<C-b> d

# 세션 목록
$ tmux ls

# 최근 세션 재개
$ tmux [ a | at | attach | attach-session ]

# 세션 재개
$ tmux a -t <session-number or session-name>

# 세션 종료
$ exit
$ tmux kill-ses -t <session-name>
$ tmux kill-sesion -t <session-name>

# 세션 이동
<C-b> (
<C-b> )

Window

# 새로운 세션을 시작하면서 윈도우 이름 지정
$ tmux new -n <window-name>

# 윈도우 생성
<C-b> c

# 윈도우 이름 변경
<C-b> ,

# 윈도우 종료
<C-b> &

# 이전, 다음 윈도우 이동
<C-b> n
<C-b> p

# 윈도우 번호로 이동
<C-b> <window-number>

# 윈도우 위치 변경
: swap-window -s 2 -t 1
: swap-window -t 1

Panes

# 세로 분할
<C-b> %

# 가로 분할
<C-b> "

# 좌, 우 이동
<C-b> {
<C-b> }

# 최근 활성화되었던 Pane으로 이동
<C-b> ;

# 방향키로 이동
<C-b> <arrow-key>

# 다음 Pane으로 이동
<C-b> o

# 사이즈 조절
<C-b-arrow-key>
<C-b> <C-arrow-key>

# Window로 변경
<C-b> !

# Pane 종료
<C-b> x

Alias 지정

alias tl='tmux ls'
alias ta='tmux a'
alias tas='tmux a -t'
alias tn='tmux new'
alias tns='tmux new -s'
alias tk='tmux kill-session -t'
alias tka='tmux kill-session -a'

환경 설정

~/.tmux.conf 를 다음과 같이 설정한다.

bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
bind -n C-d detach

플러그인

Tmux Plugin Manager를 사용해서 쉽게 관리할 수 있다.

installation 항목 참고해서 설치한다.

resurrect

시스템을 재시작 하면 tmux 세션이 없어지는데, resurrect를 사용하면 저장 후 복원 할 수 있다.

~/.tmux.conf 파일에 다음 내용을 추가한다.

set -g @plugin 'tmux-plugins/tmux-resurrect'

<C-b> I 를 눌러서 플러그인을 설치한다. (대문자 i). 설치 완료 후 <C-b> <C-s>를 누르면 저장되고, <C-b> <C-r>을 누르면 복원된다.

nvim 세션도 저장되도록 하려면 ~/.config/nvim/init.vim'tpope/vim-obsession 플러그인을 설치하고 ~/.tmux.conf에 다음 내용을 추가한다.

set -g @resurrect-strategy-nvim 'session'    # Save & Restore nvim session

continuum

resurrect를 사용해서 자동으로 저장하는 기능을 구현한 플러그인

set -g @plugin 'tmux-plugins/tmux-continuum' # Continuous saving
set -g @continuum-restore 'on'

Wine & Heidi

Heidi on Wine

Wine 설치

64bit Ubuntu 20.04 기준으로 다음과 같이 설치한다. 다른 버전은 공식문서를 참고.

# 64비트 시스템일 경우 실행
$ sudo dpkg --add-architecture i386 

# 키 다운로드
$ wget -nc https://dl.winehq.org/wine-builds/winehq.key
$ sudo apt-key add winehq.key

# Repository 추가
$ sudo add-apt-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main'
$ sudo apt update

# wine 설치
$ sudo apt install --install-recommends winehq-stable

Heidi 설치

설치 파일을 다운로드 한 뒤 다음 명령어로 실행한다.

$ wine HeidiSQL_11.1.0.6116_Setup.exe

Windows 10 으로 실행

$ winecfg

명령어로 Wine 설정을 띄운 다음 프로그램 > 프로그램 추가 에서 ~/.wine/drive_c/Program Files/heidisql.exe를 선택한다. heidisql.exe 설치 파일에 대한 Windows 버전을 Windows 10 으로 선택한다.

Redux

Redux

무슨 Re- 가 이렇게 많냐...

React: 각각의 Component 혹은, 공통된 부모가 state를 관리합니다.
Redux: Store를 하나 만들어서 state를 관리합니다.

Concepts

Action ---> Reducer ---> Store(state)

Store

Store는 state를 관리합니다. 특정 Action이 발생할 경우, Reducer로 이를 처리합니다. 이를 위해 Store를 생성할 때, Reducer를 전달해야 합니다. Reducer를 여러개 사용하기 위해서는 Redux가 제공하는 combineReducers를 사용합니다.

Store는 Redux를 사용하는 어플리케이션에서 하나만 사용할 수 있습니다.

Action

Action은 { type: "SOME_TYPE", someKey: "SOME_VALUE" } 형태의 JSON 객체를 의미합니다. 이런 객체를 생성하는 함수를 여러개 정의해서 사용합니다.

Dispatch

Store에 정의된 dispatch 함수는 특정 Action을 Store로 전달 합니다.

Reducer

Reducer는 현재 Store의 state와 전달 받은 action을 조합해서 새로운 state를 만들어 냅니다.

Store 생성

기본 생성

import { createStore } from 'redux'
import rootReducer from './reducer'
const store = createStore(rootReducer)
export default store

초기 상태 지정

import { createStore } from 'redux'
import rootReducer from './reducer'

let preloadedState
const persistedTodosString = localStorage.getItem('todos')

if (persistedTodosString) {
  preloadedState = {
    todos: JSON.parse(persistedTodosString)
  }
}

const store = createStore(rootReducer, preloadedState)

Enhancer 지정

Enhancer : Store를 감싸서 새로운 기능을 제공합니다. dispath, getState, subscribe 메소드를 재정의 할 수 있습니다.

import { createStore, compose } from 'redux'
import rootReducer from './reducer'
import {
  sayHiOnDispatch,
  includeMeaningOfLife
} from './exampleAddons/enhancers'

const composedEnhancer = compose(sayHiOnDispatch, includeMeaningOfLife)

const store = createStore(rootReducer, undefined, composedEnhancer)

export default store

react-redux

react-reduxProvider, useSelector, useDispatch 등의 기능을 제공해준다.

Middleware

Redux middleware provides a third-party extension point between dispatching an action, and the moment it reaches the reducer.

Middleware는 dispatch 동작을 맞춤화(customize) 하기 위해 사용합니다. Action이 Reducer에 전달되기 전에 사전에 지정된 작업을 수행합니다.

Action ---> Middleware ---> Reducer ---> Store(state)

Redux의 Middleware는 Store Enhancer의 구현체입니다. 따라서 다음과 같이 스토어를 생성할 때 middleware를 Enhancer로 전달할 수 있습니다.

import { createStore, applyMiddleware } from 'redux'
import rootReducer from './reducer'
import { print1, print2, print3 } from './exampleAddons/middleware'

const middlewareEnhancer = applyMiddleware(print1, print2, print3)

// Pass enhancer as the second arg, since there's no preloadedState
const store = createStore(rootReducer, middlewareEnhancer)

export default store

Middleware는 다음과 같이 정의할 수 있습니다.

const loggerMiddleware = storeAPI => next => action => {
  console.log('dispatching', action)
  let result = next(action)
  console.log('next state', storeAPI.getState())
  return result
}
  • storeAPI: {dispatch, getState} 함수를 갖는 객체입니다.
  • next: 미들웨어 파이프라인에 있는 다음 미들웨어를 의미합니다. 현재 미들웨어가 마지막 미들웨어라면, 실제 store.dispatch 함수를 의미합니다.
  • action: 전달 받은 action 객체를 의미합니다.

Redux Persist

Redux의 Store는 앱을 종료하면 사라집니다. Store를 저장하기 위해 Redux Persist를 사용합니다.

persistReducer, persistStore를 사용합니다 다음과 같이 사용합니다.

// configureStore.js

import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web

import rootReducer from './reducers'

const persistConfig = {
  key: 'root',
  storage,
}

// rootReducer를 감싸는 persistReducer 생성
const persistedReducer = persistReducer(persistConfig, rootReducer)

export default () => {
  let store = createStore(persistedReducer)
  // store를 감싸는 persistor 생성
  let persistor = persistStore(store)
  return { store, persistor }
}

이렇게 생성된 storepersistor를 각각 react-reduxProviderredux-persistPersistGate에 전달합니다.

import { PersistGate } from 'redux-persist/integration/react'

// ... normal setup, create store and persistor, import components etc.

const App = () => {
  return (
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <RootComponent />
      </PersistGate>
    </Provider>
  );
};

Redux i18n

다국어를 지원하기 위한 모듈입니다. 현재 언어 설정을 저장하기 위해 redux store를 사용합니다.

공식 문서 참고

Redux Saga

특정 Action이 발생했을 때 원하는 동작을 실행시켜주는 미들웨어 입니다. Generator문법을 사용합니다.

Loops

반복문

for

for ([초기문]; [조건문]; [증감문])
  문장

do ... while

do
  문장
while (조건문);

while

while (조건문)
  문장

label

label :
   statement

markLoop 는 while 루프를 식별한다.

markLoop:
while (theMark == true) {
   doSomething();
}

break

break [label]

레이블이 없는 경우: 가장 가까운 while, do-while, for, 또는 switch문을 종료하고 다음 명령어로 넘어간다.

for (i = 0; i < a.length; i++) {
  if (a[i] == theValue) {
    break; // for 루프 종료됨
  }
}

레이블이 있는 경우: 특정 레이블을 빠져나온다.

var x = 0;
var z = 0
labelCancelLoops: while (true) {
  console.log("Outer loops: " + x);
  x += 1;
  z = 1;
  while (true) {
    console.log("Inner loops: " + z);
    z += 1;
    if (z === 10 && x === 10) {
      break labelCancelLoops; // 전체 while 루프 종료됨
    } else if (z === 10) {
      break;
    }
  }
}

continue

continue [label]

레이블이 없는 경우: while, do-while, for 문을 둘러싼 현재 반복을 종료하고, 다음 반복으로 루프의 실행을 계속한다.

레이블이 있는 경우: continue는 그 레이블로 식별되는 루프 문에 적용된다.

for ... in

for (variable in object) {
  statements
}

for ... of

for (variable of object) {
  statement
}
let arr = [3, 5, 7];
arr.foo = "hello";

for (let i in arr) {
   console.log(i); // logs "0", "1", "2", "foo"
}

for (let i of arr) {
   console.log(i); // logs "3", "5", "7"
}

Expressions

Expression, Statement

Expression: 하나의 값으로 변환되는 코드 조각이다.

2 + 2 * 3 / 2
(Math.random() * (100 - 20)) + 20
functionCall() 
window.history ? useHistory() : noHistoryFallback()
1+1, 2+2, 3+3
declaredVariable
true && functionCall()
true && declaredVariable

Statement: 동작을 정의하는 코드 조각이다. State를 바꾼다. 표현식이 필요한 곳에 문장을 넣을 수 없다.

if
if-else
while
do-while
for
switch
for-in
with (deprecated)
debugger
variable declaration

Expression Statement: 표현식 뒤에 세미콜론 ; 을 붙이면 Expression Statement가 된다.

함수 호출은 Expression 이지만, 다음과 같이 함수 내부에서 상태를 변경하게 될 수 있다.

let value = 2
const foo = foo () => {
   value = 14
}

이 경우, 다음과 같이 작성하는 것이 좋다.

const foo = foo () => {
  return 14
}
const value = foo()

Expression과 Statement을 구분해서 사용하는 것은, 선언적(declarative)인 함수형(functional) 자바스크립트의 기본이 되는 사항이다.

Function declaration, Function expression

함수 선언은 Statement 다.

Function declaration statement:

function foo (func) {
  return func.name
}

값이 필요한 곳에 익명 함수나 네임드 함수가 사용되면 Expression이 된다.

Anonymous function expression:

console.log(foo(function () {} )) // ""

Named function expression:

console.log(foo(function myName () {} )) // "myName"

Semi-colon vs Comma operator

세미콜론으로 여러 Statement를 한 줄에 작성할 수 있다.

const a; function foo () {}; const b = 2

쉼표로 여러 Expression을 한 줄에 작성할 수 있다. 마지막 Expression이 반환된다.

console.log( (1+2,3,4) ) //4
console.log( (2, 9/3, function () {}) ) // function (){}
console.log( (3, true ? 2+2 : 1+1) ) // 4

function foo () {return 1, 2, 3, 4}
foo() //4

IIFEs (Immediately Invoked Function Expressions)

익명 함수를 괄호로 감싸면, 전달된 함수를 바로 리턴하는 Expression이 된다.

function (){}  // SyntaxError: function statement requires a name
(function () {}) // this returns function () {}

이때, 반환된 함수를 바로 실행할 수 있다.

(function () {
  //do something
})()

Block statements

중괄호를 사용해서 여러 Expression statement와 Statement를 묶을 수 있다. Block statement 는 Expression이 아니므로, 값이 필요한 곳에 사용할 수 없다.

console.log({a: 'b'}); // {a: 'b'} 오브젝트 리터럴
console.log({var a = "b", func(), 2+2}) // SyntaxError 블록 문장
const obj = {var a = "b", func(), 2+2} // SyntaxError 블록 문장

Block statement 에서 무엇이 반환되던지 그것은 암묵적으로 0로 강제 형변환되어 피연산자로 사용된다.

{} + 1 // 1
{2} + 2 // 2
{2+2} + 3 // 3
{2+2} - 3 // -3

Strict Mode

엄격 모드

엄격 모드는 구문과 런타임 동작을 변경한다.

실수를 에러로

실수로 글로벌 변수를 생성하는 것을 불가능하게 한다.

"use strict";
                       // 전역 변수 mistypedVariable 이 존재한다고 가정
mistypedVaraible = 17; // 변수의 오타때문에 이 라인에서 ReferenceError 를 발생시킴

예외를 발생시킨다.

"use strict";

// 쓸 수 없는 프로퍼티에 할당
var undefined = 5; // TypeError 발생
var Infinity = 5; // TypeError 발생

// 쓸 수 없는 프로퍼티에 할당
var obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // TypeError 발생

// getter-only 프로퍼티에 할당
var obj2 = { get x() { return 17; } };
obj2.x = 5; // TypeError 발생

// 확장 불가 객체에 새 프로퍼티 할당
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // TypeError 발생

삭제할 수 없는 프로퍼티를 삭제하려 할 때 예외를 발생시킨다.

"use strict";
delete Object.prototype; // TypeError 발생

중복된 파라미터 이름은 구문 에러를 발생시킨다.

function sum(a, a, c){ // !!! 구문 에러
  "use strict";
  return a + b + c; // 코드가 실행되면 잘못된 것임
}

0을 붙여서 사용하는 8진법 숫자 리터럴을 금지한다.

"use strict";
var sum = 015 + // !!! 구문 에러
          197 +
          142;

원시값에 프로퍼티를 설정하는것을 금지한다.

(function() {
"use strict";

false.true = "";         // TypeError
(14).sailing = "home";   // TypeError
"with".you = "far away"; // TypeError

})();

변수 사용 단순화

  • with를 사용하지 못하게 한다.
  • eval은 새로운 변수를 주위 스코프에 추가하지 않는다.
  • delete를 사용하지 못하게 한다.

eval, arguments 단순화

  • eval, arguments는 언어 문법에 바운드되거나 할당될 수 없다. (변수, 함수, 파라미터 이름 등으로 사용될 수 없다.)
  • arguments 객체가 생성한 프로퍼티를 alias 하지 않는다. (첫번째 파라미터에 값을 할당하면 arguments[0]이 변경되던 동작이 없어진다.)
  • arguments.callee를 지원하지 않는다.

JavaScript 보안

Javascript 보안 내용 참고

예약어

미래에 사용될 수 있는 몇가지 키워드들을 예약어로 지정한다.

implements, interface, let, package, private, protected, public, static, yield

ECMAScript 6, 2016, 2017

ECMAScript

ECMAScript 2015 = ES2015 = ES6

  • Ecma International: 정보와 통신 시스템을 위한 국제적 표준화 기구
  • ECMA-262: 넷스케이프가 자바스크립트 기술 규격 표준화를 위해 Ecma International에 제출한 규격의 이름.
  • ECMAScript: ECMA-262에 의해 표준화된 언어의 이름.
  • JavaScript: ECMAScript와의 호환을 목표로 하면서, 규격에 포함되지 않은 확장 기능을 제공한다.

Version

ECMA-262는 2020년 현재 11개의 버전이 출판되었으며, 11 버전은 2020년 6월에 확정되었다.

6 버전부터는 출판된 연도를 버전명으로 사용한다.

 6 : ECMAScript 2015 (ES2015)
 7 : ECMAScript 2016 (ES2016)
 8 : ECMAScript 2017 (ES2017)
 9 : ECMAScript 2018 (ES2018)
10 : ECMAScript 2019 (ES2019)
11 : ECMAScript 2020 (ES2020)

ES2015

  • import and export
  • Promises
  • Classes & Inheritance
  • Block-scoped variables (let and const)
  • Template Literals
  • Object destructing into variables
  • Generator functions
  • Map and Set data structures
  • Internationalisation for Strings, Numbers and Dates via Intl API

ES2016

  • Array.includes()
  • Numeric exponent (power of) operator **

ES2017

  • Async Functions
  • Object.entries
  • String padding functions

ES2018

  • Object Rest/Spread const obj = { ...props };
  • Asynchronous Iteration for await (...) {
  • Promise finally() function
  • Regular expression enhancements (lookbehind, named groups)

Flow.js

Flow

Flow is a static type checker for your JavaScript code

  • Flow는 자바스크립트 정적 타입 체커입니다.
  • Flow 문법으로 작성된 코드는 Babel이나 flow-remove-types로 표준 자바스크립트로 변환되어야 합니다.

create-react-app 으로 생성된 프로젝트는 flow를 기본으로 지원합니다. 다음과 같은 의존성을 갖습니다.

react-scripts
└ babel-preset-react-app
    └ @babel/plugin-transform-flow-strip-types
        └@babel/plugin-syntax-flow

flow-bin을 추가하고, flow init을 실행하면 사용할 준비가 완료됩니다.

$ yarn add --dev flow-bin
$ yarn run flow init

yarn run flow 명령어로 오류를 확인합니다.

$ yarn run flow
yarn run v1.22.10
No errors!
Done in 0.09s.

flow-typed

flow-typed is a repository of third-party library interface definitions for use with Flow.

flow-typed는 서드 파티 라이브러리의 타입 정보(Library Definitions)를 제공해주는 저장소 입니다. 다음과 같은 명령어로 사용합니다.

# yarn 설치
$ yarn global add flow-typed
# npm 설치
$ npm i -g flow-typed
# libdefs 검색
$ flow-typed search react-redux
# libdefs 설치
$ flow-typed install [email protected]
• Searching for 1 libdefs...
• rebasing flow-typed cache...
• Installing 1 libDefs...
  • react-redux_v7.x.x.js
    └> ./flow-typed/npm/react-redux_v7.x.x.js

.flowconfig 파일의 [libs] 섹션에 Library Definition이 정의된 경로를 지정할 수 있습니다. ./flow-typed는 지정하지 않아도 기본으로 포함됩니다.

Async and Await

async, await

async

함수 앞에 async가 붙으면 항상 프라미스를 반환한다. 다음 두 함수는 동일하다.

async function f() {
  return 1;
}

async function f() {
  return Promise.resolve(1);
}

에러가 발생하는 경우는 다음과 같다.

async function f() {
  await Promise.reject(new Error("에러 발생!"));
}

async function f() {
  throw new Error("에러 발생!");
}

await

await는 프라미스가 처리되기를 기다린다. async 함수에서만 사용할 수 있다.

// await는 async 함수 안에서만 동작한다.
let value = await promise;

에러 처리

await가 던진 에러는 try ... catch 로 처리할 수 있다.

async function f() {

  try {
    let response = await fetch('http://유효하지-않은-주소');
  } catch(err) {
    alert(err); // TypeError: failed to fetch
  }
}

f();

Functions

Function

자바스크립트에서 모든 함수는 Function 객체다. 다른 객체들 처럼 속성 및 메소드를 가질 수 있는 일급 객체다.

함수 선언

Function declarations

함수 정의(definition), 함수 선언(function declaration), 함수 구문(function statement)은 function 키워드를 상요한다.

function name([param[, param[, ... param]]]) {
   statements
}

이렇게 선언된 함수는 호이스팅된다.

console.log(square(5));
/* ... */
function square(n) { return n * n }

함수는 그 함수가 선언된 함수를 스코프로 갖는다. 만약 중첩 없이 코드의 탑 레벨에 함수가 정의된 경우, 전체 프로그램을 스코프로 갖는다.

Function expressions

함수 표현식으로 함수를 선언할 수 있다. 표현식으로 정의된 함수는 호이스팅 되지 않는다.

// 익명 함수 표현식
const square = function(number) { return number * number }
var x = square(4) // x gets the value 16

// 네임드 함수 표현식 (재귀 가능)
const factorial = function fac(n) { return n < 2 ? 1 : n * fac(n - 1) }
console.log(factorial(3))

파라미터 전달

함수의 파라미터는 으로 전달된다. 파라미터의 값을 변경해도 원래 값은 변하지 않는다. 하지만 객체가 전달된 경우 객체의 속성은 변경될 수 있다.

Method

함수가 객체 안에 속성으로 있을 경우, 이를 메소드라고 부른다.

Scope

함수 안에 선언된 변수는 함수의 외부에서 접근할 수 없다. 함수는 함수 외부의 변수에 접근할 수 있다.

arguments 객체

함수에 전달된 인수를 arguments를 사용해서 배열과 비슷한 방식으로 사용할 수 있다.

  • arguments: 현재 실행 중인 함수에 전달된 인수를 포함하는 배열 같은 객체.
  • arguments.callee : 현재 실행 중인 함수.
  • arguments.caller : 현재 실행 중인 함수를 호출한 함수.
  • arguments.length: 함수에 전달된 인수의 수.
arguments[i]

arguments는 배열이 아니다.

Function parameters

Default parameters

ECMA2015 이후로 파라미터에 기본 값을 지정할 수 있다. 지정하지 않을 경우 undefined 값을 갖는다.

function multiply(a, b = 1) {
  return a * b;
}

multiply(5); // 5

Rest parameters

함수의 마지막 파라미터의 앞에 ...를 붙여서 나머지 모든 인수를 자바스크립트 배열로 대체한다.

arguments와 달리 Rest 파라미터는 Array 인스턴스다.

function multiply(multiplier, ...theArgs) {
  return theArgs.map(function(element) {
    return multiplier * element;
  });
}

var arr = multiply(2, 1, 2, 3);
console.log(arr); // [2, 4, 6]

Arrow functions

함수 표현식과 비교해서 짧은 문법으로 함수를 선언할 수 있다. 화살표 함수는 자체적인 this, arguments, super, new.target을 갖지 않는다. 화살표 함수는 항상 익명이다.

Ruby SSL Error

사내 인증서 때문에 gem install bundler 가 실패할 경우, SSL_CERT_FILE 환경변수로 인증서.crt 파일을 지정해준다.

Ghost

Ghost 블로그 입력기 문제가 3.38.3 에서 해결됨
2020-11-26 현재 Lightsail 에서 사용 가능한 Ghost Certified by Bitnami 이미지는 3.32.1 버전이다.
업데이트 된다면 인스턴스 하나 만들어보는것도 좋을듯.

Sync, Async and Blocking, Non-Blocking

Sync, Async and Blocking, Non-Blocking

아 헷갈린다. 나의 언어로 정리하기.

A, B 모듈이 있고, A가 B를 호출한다고 가정한다.

Synchronous / Asynchronous

두 모듈 사이의 관계를 의미한다.

  • A and B are Synchronous:
    • A는 B를 호출하고 응답을 기다린다.
  • A and B are Asynchronous:
    • A는 B를 호출하고 다른 일을 한다.
    • 작업이 완료되면 B가 A를 부른다.
    • A와 B는 서로 다른 스레드다.

Blocking, Non-Blocking

한 모듈 안에서 발생하는 상황을 의미한다.

  • A is Blocking:
    • A는 B를 호출하고 응답을 기다린다.
  • A is Non-Blocking:
    • A는 B를 호출하고 다른 일을 한다.
    • B가 작업을 완료했는지 확인하는지, B가 A를 부르는지 여부는 중요하지 않다.
    • A와 B는 서로 다른 스레드다.

익숙한 시나리오

Sync, Blocking

자바에서 파일을 읽거나 쓰는 방법

Async, Non-Blocking

노드에서 콜백을 전달해서 함수를 실행하는 방법

어색한 시나리오

Sync, Non-Blocking

  • 푸드코트에서 주문을 하고 번호표를 받는다. (Sync)
  • 카톡을 하면서 번호판을 확인한다. (Non-Blocking)
  • 번호표를 주고 음식을 받는다. (Sync)

Async, Blocking

여러 작업을 동시에 실행하려고 하지만, 제어권을 넘겨받을 수 없어서 순차적으로 실행된다.

Types

자바스크립트의 자료형

동적 타이핑

자바스크립트는 느슨한 타입 (loosely typed) 언어, 혹은 동적 (dynamic) 언어다. 변수의 타입을 미리 선언 할 필요가 없다.

var foo = 42;    // foo 는 이제 Number 임
var foo = "bar"; // foo 는 이제 String 임
var foo = true;  // foo 는 이제 Boolean 임

최근 ECMAScript 표준은 9가지 타입을 정의한다.

Data Types

원시값: 객체가 아니면서 메서드도 가지지 않는 데이터를 의미한다.

undefined : typeof instance === "undefined"
Boolean : typeof instance === "boolean"
Number : typeof instance === "number"
String : typeof instance === "string"
BigInt : typeof instance === "bigint"
Symbol (new in ECMAScript 2015) : typeof instance === "symbol"

Undefined

값이 할당되지 않은 변수를 의미한다.

var x; //create a variable but assign it no value
console.log("x's value is", x) //logs "x's value is undefined"

Symbol

Symbol 함수를 사용해서 만드는 유일한 값을 의미한다.

// Here are two symbols with the same description:
let Sym1 = Symbol("Sym")
let Sym2 = Symbol("Sym")

console.log(Sym1 === Sym2) // returns "false"
// Symbols are guaranteed to be unique.
// Even if we create many symbols with the same description,
// they are different values.

Structural Types

Object : typeof instance === "object"
Function : typeof instance === "function"

Structural Root Primitive

null : `typeof null === "object"

모든 객체는 null로부터 파생되기 때문에 typeof 연산자는 object를 반환한다.

MySQL character set

JPA Repository 를 사용해서 findByName과 같은 쿼리를 작성했는데, 실제 DB에는 존재하지만, 쿼리 결과는 빈 리스트로 조회되는 문제가 있었다.

해결책으로는 jdbc 주소 뒤에 characterEncoding=UTF-8 을 추가하는 것이었다.

기본적인 문제로는 SHOW VARIABLES LIKE 'char%' 으로 조회된 캐릭터셋이 latin1 인게 문제였다.

C:\ProgramData\MySQL\MySQL Server 5.7\myini 파일을 열어서 다음과 같이 수정한다.

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
skip-character-set-client-handshake

MySQL 을 재시작하고 다음 쿼리로 설정 변경을 확인한다.

show variables like 'c%';

https://medium.com/oldbeedev/mysql-utf8mb4-character-set-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0-da7624958624

Arrays

배열

  • 인덱스로 정수만 사용한다.
  • .을 사용해서 배열 객체의 속성 변수를 설정할 수 있다.
  • 배열 객체의 속성과, 배열 리스트는 서로 다른 별개 항목으로, 순회 및 변형 작업은 객체 속성에 적용되지 않는다.
  • 인덱스는 0부터 시작한다.
  • 잘못된 인덱서를 사용하면 undefined를 리턴한다.
  • 마지막 요소의 인덱스는 length 속성에서 1을 뺀 것과 같다.

자주 사용하는 연산

let fruits = ['사과', '바나나']

console.log(fruits.length)
// 2

let first = fruits[0]
// 사과

let last = fruits[fruits.length - 1]
// 바나나

fruits.forEach(function (item, index, array) {
  console.log(item, index)
})
// 사과 0
// 바나나 1

let newLength = fruits.push('오렌지')
// ["사과", "바나나", "오렌지"]

let last = fruits.pop() // 끝에있던 '오렌지'를 제거
// ["사과", "바나나"]

let first = fruits.shift() // 제일 앞의 '사과'를 제거
// ["바나나"]

let newLength = fruits.unshift('딸기') // 앞에 추가
// ["딸기", "바나나"]

fruits.push('망고')
// ["딸기", "바나나", "망고"]

let pos = fruits.indexOf("바나나")
// 1

let removedItem = fruits.splice(pos, 1) // 항목을 제거하는 방법
// ["딸기", "망고"]

let vegetables = ['양배추', '순무', '무', '당근']
console.log(vegetables)
// ["양배추", "순무", "무", "당근"]

let pos = 1
let n = 2

let removedItems = vegetables.splice(pos, n)
// 배열에서 항목을 제거하는 방법
// pos 인덱스부터 n개의 항목을 제거함

console.log(vegetables)
// ["양배추", "당근"] (원 배열 vegetables의 값이 변함)

console.log(removedItems)
// ["순무", "무"]

let shallowCopy = fruits.slice() // 사본을 만드는 방법
// ["딸기", "망고"]

## length

새로운 인덱스가 배열의 경계를 넘어가면, `length` 속성이 업데이트 된다.

```js
fruits[5] = 'mango'
console.log(fruits[5])           // 'mango'
console.log(Object.keys(fruits)) // ['0', '1', '2', '5']
console.log(fruits.length)       // 6

length를 직접 늘릴 수 있다.

fruits.length = 10;
console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
console.log(fruits.length); // 10

length를 줄이면 요소가 지워진다.

fruits.length = 2
console.log(Object.keys(fruits)) // ['0', '1']
console.log(fruits.length)       // 2

H2 INIT

https://stackoverflow.com/questions/5225700/can-i-have-h2-autocreate-a-schema-in-an-in-memory-database

H2 데이터베이스를 메모리상에서 쓰지 않고, 파일로 쓸 경우 스프링이 스키마를 생성하거나 데이터를 입력해주지 않는다.

다음 설정을 사용한다.

spring:
  config:
    activate:
      on-profile: local
  datasource:
    url: jdbc:h2:file:./h2db;AUTO_SERVER=true
    username: sa
    platform: h2
    initialization-mode: always
  jpa:
    hibernate:
      ddl-auto: create-drop
    properties:
      show_sql: true
      format_sql: true
      use_sql_comments: true

A 10 minute primer to JavaScript modules, module formats, module loaders and module bundlers

https://www.jvandemo.com/a-10-minute-primer-to-javascript-modules-module-formats-module-loaders-and-module-bundlers/

Module

모듈은 재사용 가능한 코드 조각이다. 모듈은 상세한 구현을 캡슐화하고, 접근 가능한 API를 제공함으로써 다른 코드에서 쉽게 읽고 사용할 수 있다.

Module format

모듈 포맷은 모듈을 정의하기 위해 사용하는 문법이다. ES6 이전에는 모듈을 정의하는 공식적인 문법이 없었기 때문에, 똑똑한 개발자들이 여러가지 포맷을 고안해서 사용했다.

  • Asynchronous Module Definition (AMD) : 브라우저에서 사용된다.
  • CommonJS : Node.js 에서 사용되었다.
  • Universal Module Definition (UMD): 브라우저와 Node.js 에서 사용되었다.
  • System.register : ES6 모듈 문법을 ES5 에서 사용할 수 있게 하기 위해 설계되었다.
  • ES6 module format : 자바스크립트는 ES6부터 모듈을 정의하는 공식적인 문법을 갖게 되었다.

Transpiler

ES6 모듈 포맷을 사용할 수 있지만, 이를 지원하지 않는 브라우저를 위해서 Babel과 같은 트랜스파일러가 필요하다. 트랜스파일러는 모던 자바스크립트 코드를 구 표준을 준수하는 코드로 바꿔준다.

Polyfill

폴리필은 기존의 브라우저에서 새롭게 추가된 기능을 사용하기 위해 필요한 코드다. 트랜스파일러가 코드를 변환할 때 옛날 규격에 존재하지 않는 새로운 기능을 메꿔주는(fillin) 역할을 한다. 잘 알려진 예로 core-jspolyfill.io가 있다.

모던 자바스크립트를 이용해 스크립트를 작성하려면 트랜스파일러와 폴리필은 필수다.

Module loaders

모듈 로더는 브라우저에서 런타임에 특정 모듈 포맷으로 작성된 모듈을 해석(interpret)하고 로드한다. 잘 알려진 예로 RequireJSSystemJS가 있다.

Module bundlers

모듈 번들러는 모듈 로더를 대체하며, 빌드 시점에 모든 코드를 합친 bundle을 생성한다. 잘 알려진 예로 BrowserifyWebpack이 있다.

Closures

Closure

클로저는 외부 변수를 기억하고 이 외부 변수에 접근할 수 있는 함수를 의미한다.

클로저는 함수와 함수가 선언된 어휘적 환경(Lexical Environment)의 조합이다. 이 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성된다.

Lexical Environment

렉시컬 환경은 명세서에 존재하는 개념으로, 자바스크립트 엔진은 이를 고유의 방법으로 구현한다.
실행 중인 함수, 코드 블록 {...}, 스크립트 전체는 렉시컬 환경(Lexical Environment) 이라 불리는 내부 숨김 연관 객체(internal hidden associated object)를 갖는다.

Lexical Environment = Environment Record + Outer Lexical Environment
  • 변수는 Environment Record 의 프로퍼티다.
  • 코드가 실행되면서 레코드가 변경된다.
  • 변수에 접근할 때는 내부 렉시컬 환경 -> 외부 렉시컬 환경 -> 전역 렉시컬 환경으로 확장된다.

함수

모든 함수는 함수가 생성된 곳의 렉시컬 환경을 기억한다. 함수는 [[Environment]] 라는 숨김 프로퍼티를 갖는데, 여기에 렉시컬 환경에 대한 참조가 저장된다. 함수 내부의 코드는 [[Environment]]를 사용해서 외부 변수에 접근할 수 있다.

Node

Node

비동기 이벤트 주도 JavaScript 런타임

  • Highly-scalable, data-intensive and real-time apps
  • Node is a runtime environment for executing JavaScript code
    • 자바스크립트로 파일 시스템, OS, 네트워크를 사용할 수 있는 환경을 제공해준다.
  • Non-blocking (Asynchronous)
  • Single Thread 로 여러 Request를 처리한다.
    • 기존(ASP.NET)에는 요청 하나당 스레드 하나가 생성되어서, 모든 스레드가 사용중이면 대기를 해야 했다.
  • Node is ideal for I/O-intensive apps.
    • 쿼리를 실행하고 다른 요청을 처리할 수 있음
  • Do not use Node for CPU-intensive apps. (Video encoding, Image population)
    • 요청을 처리하는 동안 다른 요청이 기다려야함

Global Objects

console, setTimeout(), clearTimeout(), setInterval(), clearInterval() 등의 객체가 있다. 브라우저에서는 모든 Global Object를 window Object를 통해서 접근할 수 있다.

window.console.log(...)
var message = '';
window.message

node 는 window 대신 global 객체가 있다.

var message = '';
console.log(global.message) // undefined!
global.setTimeout(...)

window와는 다르게 변수나 함수가 global 객체에 추가되지 않는다.

Modules

  • 같은 이름의 함수를 다른 파일에서 선언하면, 나중에 불러온 함수가 window에 추가되어서 기존의 함수를 Overload 한다.
  • 각각의 파일이 각각의 모듈이 된다.
  • 파일 안에서 module 객체를 사용할 수 있다.
// logger.js
var url = "http://mylogger.io/log";

function log(message) {
  // Send an HTTP request
  console.log(message);
}

module.exports.log = log;
// module.exports.endPoint = url;
// app.js
// module.exports 객체가 logger로 할당된다.
const logger = require('./logger');
console.log(logger);
// output: { log: [Function: log] }

logger.log('message');
// output: message

module.exports에 변수나 함수를 직접 할당할 수 있다.

// logger.js
function log(message) {
  console.log(message);
}
module.exports = log;
// app.js
const log = require('./logger');
log('message')

Module Wrapper Function

모듈은 exports, require, module, __filename, __dirname이 파라미터로 전달되는 Module Wrapper Function에 의해 감싸진다.

// 간략한 버전
(function (exports, require, module, __filename, __dirname) {

  function log(message) {
    console.log(message);
  }

  module.exports = log;
  // 같은 의미로 사용할 수 있다.
  // module.exports.log = log;
  // exports.log = log;

  // export는 module.exports에 대한 참조라서 아래와 같이 선언할 수 없다.
  // exports = log;
}

Built-in Modules

OS

const os = require('os');
var totalMemory = os.totalmem();
var freeMemory = os.freemem();

console.log('Total Memory: '+ totalMemory);
console.log(`Free Memory: ${freeMemory}`);  // ES6 / ECMA2015 문법

File System

const fs = require('fs');

// 동기
// 성능 저하의 원인
const files = fs.readdirSync('./');
console.log(files);

// 비동기. 콜백으로 결과를 받는다.
fs.readdir('./', function(err, files) {
  if(err) console.log('Error', err);
  else console.log('Result', files);
});

Events

Event Emitter 클래스를 사용한다. 노드가 제공하는 기본 모듈들은 Event Emitter를 구현하는 것이 많다.

const EventEmitter = require('events');
const emitter = new EventEmitter();

// Register a listener
// emitter.on('messageLogged', function(arg) {
//    console.log('Listener called', arg);
// });

emitter.on('messageLogged', (arg) => {
    console.log('Listener called', arg);
});

// Raise an event
// emit: Making anoise, produce - signalling
emitter.emit('messageLogged', { id: 1, url: 'http://' });

HTTP

http.Servernet.Server를 상속받는다. net.ServerEventEmitter를 상속 받는다.

Class: net.Server#
Added in: v0.1.90
Extends: <EventEmitter>
const http = require('http');

const server = http.createServer((req, res) => {
  if (req.url === '/') {
    res.write('Hello World');
    res.end();
  }

  if (req.url === '/api/courses') {
    res.write(JSON.stringify([1, 2, 3]));
    res.end();
  }
});

server.listen(3000);

console.log('Listening on port 3000...');

next-material-starter

앱 생성

npx create-next-app

폴더 구조를 변경한다.

public
src
  pages
    api
  styles

절대 경로 import 설정

jsconfig.js

import 구문에서 src/ 밑의 경로로 import 할 수 있게 설정한다.

{
  "compilerOptions": {
    "baseUrl": "src",
  }
}

ESLint

  • npx install-peerdeps --dev eslint-config-airbnb
  • npm install --save-dev eslint-config-prettier
  "devDependencies": {
    "eslint": "^7.2.0",
    "eslint-config-airbnb": "^18.2.0",
    "eslint-config-prettier": "^6.15.0",
    "eslint-plugin-import": "^2.21.2",
    "eslint-plugin-jsx-a11y": "^6.3.0",
    "eslint-plugin-react": "^7.20.0",
    "eslint-plugin-react-hooks": "^4.0.0
  }

VIM Configuration

vim-javascript 플러그인은 vim의 js 기본 Syntax Highlighting과 Indentation을 향상시켜준다.

# Javascript
Plugin 'pangloss/vim-javascript'
# JSX
Plugin 'mxw/vim-jsx''
# Syntax
Plugin 'scrooloose/syntastic'
```

```
# js 파일을 jsx 로
let g:jsx_ext_required = 0
```

neovim

neovim

Ubuntu 20.04 환경에서 neovim으로 개발 환경을 구축하는 방법

Installation

다음 명령어로 설치한다.

$ sudo apt install neovim

nvim 명령어로 실행한다. 손에 익은 vim 명령어로 실행할 수 있도록 ~/.bashrc~/.zshrc에 다음 내용을 추가한다.

alias vim='nvim'
alias vi='nvim'

설정 파일을 다시 읽어들인다.

$ source ~/.zshrc
$ vim

Configuration

neovim의 설정 파일은 ~/.config/nvim/init.vim 이다. 없다면 생성하고, 다음 내용을 입력한다.

" init.vim
nmap <silent> ,ev :e  $MYVIMRC<CR>
autocmd! bufwritepost $MYVIMRC source $MYVIMRC

,ev 매핑으로 ~/.config/nvim/init.vim 을 수정할 수 있도록 지정하고, 파일이 수정될 경우 다시 읽어들여서 수정 사항이 반영 되도록 설정한다.

Configurations

vim-plug

플러그인을 관리하는 플러그인 vim-plug를 사용한다. 다음 명령어로 설치한다.

sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \
       https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'

init.vim

~/.config/nvim/init.vim 파일을 다음과 같이 작성한다.

파일 내용 추가

fzf

fzf.vim의 기능을 전부 사용하기 위해서 bat, ripgrep, delta를 설치해준다.

  • bat: syntax-highlighted preview
  • delta: git diff format
  • ripgrep: Rg command

bat, ripgrep 은 설치시 충돌이 나는 이슈가 있어서 다음 명령으로 설치한다.

sudo apt install -o Dpkg::Options::="--force-overwrite" bat ripgrep

delta 는 패키지 파일을 다운로드 받아서 다음 명령으로 설치한다.

sudo dpkg -i git-delta_0.5.0_amd64.deb

CoC

~/.config/nvim/coc-settings.json 파일을 다음과 같이 작성한다.

{
  // "http.proxyStrictSSL": false,
  "eslint.autoFixOnSave": true,
  "coc.preferences.formatOnSaveFiletypes": [
    "json",
    "jsonc",
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ],
  "tsserver.formatOnType": true,
  "coc.preferences.formatOnType": true
}

Lexical Structure

자바스크립트의 어휘구조

Unicode

자바스크립트는 유니코드로 작성되어서, 어떤 언어든지 변수 이름으로 사용할 수 있다.

Optional Semicolon ;

자바스크립트는 ;으로 문장의 끝을 구별한다. 세미콜론을 붙이는게 기본이다. 세미콜론이 없을 경우 인터프리터가 세미콜론 자동 삽입(Automatic Semicolon Insertion) 기능으로 세이콜론을 넣는다.

하지만, 강제되는 사항이 아니라서 생략이 가능하고, 요즘은 세미콜론을 붙이지 않는것이 유행하는 것으로 보인다. JavaScript Standard Style세미콜론이 없어야 합니다.라는 규칙이 있다.

White space

자바스크립트는 공백을 무시한다.

Case sensitive

자바스크립트는 대소문자를 구별한다. somethingSomething은 서로 다른 identifier다.

Comments

다음 두가지 스타일의 주석을 사용할 수 있다.

// 인라인 주석
/*
여러 줄을
주석으로 사용
*/

Literals and Identifier

Literal은 숫자, 문자열, 객체, 배열 등의 값을 의미한다.

5
'Test'
true
['a', 'b']
{color: 'red', shape: 'Rectangle'}

Identifier는 변수, 함수, 객체를 구별하기 위해 사용하는 문자열을 의미한다. 문자, $, _로 시작하며, 숫자를 포함할 수 있다.

Test
test
TEST
_test
Test1
$test

Reserved words

예약어는 identifier로 사용할 수 없다.

break
do
instanceof
typeof
case
else
new
var
catch
finally
return
void
continue
for
switch
while
debugger
function
this
with
default
if
throw
delete
in
try
class
enum
extends
super
const
export
import
implements
let
private
public
interface
package
protected
static
yield

Template Literals

Template Literals

템플릿 리터럴은 내장된 표현식을 허용하는 문자열 리터럴을 의미한다.

문법:

`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tag`string text ${expression} string text`

여러줄:

console.log(`string text line 1
string text line 2`);
// "string text line 1
// string text line 2"

표현식 삽입:

var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and
not ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."

중첩:

const classes = `header ${ isLargeScreen() ? '' :
 `icon-${item.isCollapsed ? 'expander' : 'collapser'}` }`;

Tagged Tamplages 참고

Hibernate 쿼리 로그

# logs the SQL statements
logging.level.org.hibernate.SQL=DEBUG
# Logs the JDBC parameters passed to a query
logging.level.org.hibernate.type=TRACE

Arrow Functions

화살표 함수 표현식

  • Does not have its own bindings to this or super, and should not be used as methods.
  • Does not have arguments, or new.target keywords.
  • Not suitable for call, apply and bind methods, which generally rely on establishing a scope.
  • Can not be used as constructors.
  • Can not use yield, within its body.

기본 문법

(param1, param2, , paramN) => { statements }
(param1, param2, , paramN) => expression
// 다음과 동일함:  => { return expression; }

// 매개변수가 하나뿐인 경우 괄호는 선택사항:
(singleParam) => { statements }
singleParam => { statements }

// 매개변수가 없는 함수는 괄호가 필요:
() => { statements }

고급 문법

// 객체 리터럴 반환시 () 사용
params => ({foo: "a"})

// Rest 파라미터
(a, b, ...r) => expression

// 파라미터 기본값
(a=400, b=20, c) => expression

// 파라미터 구조 분해 및 기본값
([a, b] = [10, 20]) => a + b;  // result is 30
({ a, b } = { a: 10, b: 20 }) => a + b; // result is 30

The Event Loop

Concepts

Event Loop

Stack

함수 호출은 프레임을 생성하고, 스택에 프레임을 집어넣는다. 프레임은 인수와 로컬 변수를 포함한다.

프레임이라고 표현한 개념은 ECMA-262 명세서상에 정의된 Lexical Environment를 의미하는 것 같다.
렉시컬 환경 참고

Heap

객체들은 힙 안에 할당 된다. 힙은 구조화되지 않은 넓은 메모리 영역을 가리킨다.

Queue

처리해야되는 메시지를 큐에 저장한다. 메시지메시지를 처리하기 위한 함수와 연관되어 있다. 런타임은 이벤트 루프의 특정 시점에 큐에 오랫동안 저장된 순서대로 메시지를 처리한다. 메시지가 큐에서 제거되고, 연관되어 있는 함수의 파라미터로 메시지가 전달된다. 함수가 호출되면 새로운 스택 프레임이 생성되고, 함수가 사용한다.

함수 실행은 스택이 비워질 때 까지 지속되며, 스택이 비워지면 이벤트 루프는 큐에 있는 다음 메시지를 처리한다.

Event Loop

  • 각각의 메시지는 다른 메시지가 처리되기 전에 완전히 종료된다.
  • 브라우저의 이벤트나 setTimeout()을 통해서 메시지를 추가할 수 있다.
  • setTimeout()은 대기열에 추가 할 메시지와 시간값을 인수로 갖는다.
  • setTimeout은 타이머 만료 직후에 실행되지 않고, 메시지가 큐에 추가된 후 처리된다.

Semicolons

세미콜론

  • 있는게 기본
  • 생략 가능
  • 생략할 경우 몇가지 문제가 발생할 수 있어서 주의를 기울여야 한다.

Semicolons in JavaScript 참고

Java SSLPeerUnverifiedException

JAVA 에서 다음과 같은 오류가 발생하는 경우

java.lang.IllegalStateException: javax.net.ssl.SSLPeerUnverifiedException:
   Certificate for <a.host.com> doesn't match any of the subject
   alternative names: [b.host.com]

https://a.host.com 으로 접속하려고 하는데 인증서가 https://b.host.com으로 발급되어 있는 경우다. 개발시에 접속이 필요할 경우 다음과 같이 설정할 수 있다.

HttpClientBuilder builder = HttpClientBuilder.create();
SSLConnectionSocketFactory scsf = new SSLConnectionSocketFactory(
    SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(),
    NoopHostnameVerifier.INSTANCE);
builder.setSSLSocketFactory(scsf);
builder.build();

Asynchronous programming and callbacks

비동기 프로그래밍과 콜백

이벤트 루프(#49) 에 의해서

  • 함수가 실행된다.
  • 스택에 추가된다.
  • 비동기 함수를 실행한다.
  • 런타임이 비동기 함수를 처리한 뒤, 완료되는 시점에 콜백 함수를 메시지 큐에 추가한다.
  • 스택이 비어있을 경우 메시지 큐에 있는 메시지를 처리한다.
  • 콜백 함수가 실행된다.

무언가를 비동기적으로 수행하는 함수는 반드시 콜백(함수 내 동작이 모두 처리된 후 실행되어야 하는 함수)을 인수로 제공해야 한다.

Error-first callback

콜백이 errorresult를 다음과 같은 방식으로 받는 패턴을 의미한다. 단일 콜백으로 에러와 성공 처리를 수행할 수 있다.

loadScript('/my/script.js', function(error, script) {
  if (error) {
    // 에러 처리
  } else {
    // 스크립트 로딩이 성공적으로 끝남
  }
});

Callback hell

콜백을 중첩해서 여러번 사용하면 콜백 지옥 패턴이 발생한다.

멸망의 피라미드(pyramid of doom) 이라고도 불리운다.

이를 해결하기 위해 #46 Promises 를 사용한다.

this

this

Global Context

this는 엄격 모드 여부에 관계 없이 전역 객체를 참조한다.

// 웹 브라우저에서는 window 객체가 전역 객체
console.log(this === window); // true

a = 37;
console.log(window.a); // 37

this.b = "MDN";
console.log(window.b)  // "MDN"
console.log(b)         // "MDN"

Function Context

함수 안에서 this의 값은 함수가 호출된 방식에 의해 결정된다. 비엄격모드에서 함수만 호출할 경우 전역 객체를 가리키며, 엄격모드에서는 undefined 값을 갖는다.

// An object can be passed as the first argument to call or apply and this will be bound to it.
var obj = {a: 'Custom'};

// We declare a variable and the variable is assigned to the global window as its property.
var a = 'Global';

function whatsThis() {
  return this.a;  // The value of this is dependent on how the function is called
}

whatsThis();          // 'Global' as this in the function isn't set, so it defaults to the global/window object
whatsThis.call(obj);  // 'Custom' as this in the function is set to obj
whatsThis.apply(obj); // 'Custom' as this in the function is set to obj

Class Context

클래스 생성자 안에서 this는 일반적인 객체다. 클래스의 static이 아닌 메소드들은 this의 프로토타입에 추가된다.

예제

자세한 사용법은 예제 문서 참고

Books

Real MySQL, Real MariaDB, DBA를 위한 MySQL 운영기술

Promises

Promise

new Promise(executor)   | resolve(value)      | reject(error)
state: "pending"        | state: "fulfilled"  | state: "rejected"
result: undefined       | result: value       | result: error

resolve

let promise = new Promise(function(resolve, reject) {
  // 프라미스가 만들어지면 executor 함수는 자동으로 실행됩니다.
  // 1초 뒤에 일이 성공적으로 끝났다는 신호가 전달되면서 result가 'done'이 됩니다.
  setTimeout(() => resolve("done"), 1000);
});

reject

let promise = new Promise(function(resolve, reject) {
  // 프라미스가 만들어지면 executor 함수는 자동으로 실행됩니다.
  // 1초 뒤에 에러와 함께 실행이 종료되었다는 신호를 보냅니다.
  setTimeout(() => reject(new Error("에러 발생!")), 1000);
});

then, catch, finally

then

promise.then(
  function(result) { /* 결과(result)를 다룹니다 */ },
  function(error) { /* 에러(error)를 다룹니다 */ }
);

성공만 다루고 싶은 경우

let promise = new Promise(resolve => {
  setTimeout(() => resolve("done!"), 1000);
});

promise.then(alert); // 1초 뒤 "done!" 출력

catch

에러만 다루고 싶은 경우

let promise = new Promise((resolve, reject) => {
  setTimeout(() => reject(new Error("에러 발생!")), 1000);
});

// .catch(f)는 promise.then(null, f)과 동일하게 작동합니다
promise.catch(alert); // 1초 뒤 "Error: 에러 발생!" 출력

finally

프라미스가 이행(resolve)되거나 거부(reject)되면 항상 실행된다.

new Promise((resolve, reject) => {
  /* 시간이 걸리는 어떤 일을 수행하고, 그 후 resolve·reject를 호출함 */
})
  // 성공·실패 여부와 상관없이 프라미스가 처리되면 실행됨
  .finally(() => 로딩 인디케이터 중지)
  .then(result => result와 err 보여줌 => error 보여줌)

then, catch, finally 핸들러는 마이크로태스크 큐에 추가된다. 따라서 .then/catch/finally 핸들러는 항상 현재 코드가 종료되고 난 후에 호출된다.

Timers

Timers

자바스크립트 명세에는 없지만 대부분의 브라우저와 Node.js 에서는 지원한다. 브라우저는 HTML5 의 Timers 스펙을 준수한다.

setTimeout

setTimeout 으로 지정된 시간 이후에 함수를 실행한다.

// 일정 시간 이후 함수 실행
let timerId = setTimeout(func|code, [delay], [arg1], [arg2], ...)
// timerId 를 사용해서 함수 실행 취소
clearTimeout(timerId);

// 첫 인수가 문자열이면 이 문자열을 이용해 함수를 만든다.
setTimeout("alert('안녕하세요.')", 1000);
// 추천: 화살표 함수 사용
setTimeout(() => alert('안녕하세요.'), 1000);

setInterval

// 일정 시간 마다 함수 실행
let timerId = setInterval(func|code, [delay], [arg1], [arg2], ...)
// timerId 를 사용해서 함수 실행 취소
clearTimeout(timerId);

setInterval을 사용하면 함수 호출 사이의 지연 간격이 실제 명시한 간격보다 짧아진다.

대기시간 0

setTimeout(func, 0)이나 setTimeout(func)을 사용하면 setTimeout의 대기 시간을 0으로 설정할 수 있다. 현재 스크립트의 처리가 종료된 이후에 스케줄링한 함수가 처리된다.

Design Pattern

생성 패턴
Abstract Factory
Builder
Factory Method
Prototype
Singleton

구조 패턴
Adapter
Bridge
Composite
Decorator
Facade
Flyweight
Proxy

행위 패턴
Chain of Responsibility
Command
Interpreter
Iterator
Mediator
Memento
Observer
State
Strategy
Template Method
Visitor

Scopes

스코프

코드가 실행되고 있는 문맥을 의미한다. 값과 표현식(expression)들은 가시적이며 참조 가능하다. 하위 컨텍스트에서 상위 컨텍스트를 접근할 수 있지만, 상위에서 하위로는 접근하지 못한다.

함수는 클로저 역할을 해서 스코프를 생성한다. 함수 내에 정의된 변수를 함수 외부나 다른 함수에서 접근할 수 없다.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.