2021-12-29

유니코드 정규표현식 (Regex unicode)

유니코드 정규표현식 (Regex unicode)

유니코드

문자열을 처리할 수 있는 코드의 집합 표준이다.
이것을 통해 문자로써 이모티콘(✨)과 수식(𝒳)의 처리가 가능해진다.

정규표현식에서의 유니코드

es6가 적용되는 모던 브라우저에서 사용이 가능한 정규표현식의 형태이다.
이로인해 기존 유니코드를 사용한 이모티콘, 수식에 대하여 정규표현식 처리가 가능하다.
사용법은 글로벌 옵션으로 u 를 추가한다.

	/𝌆{2}/u
	console.log(/𝌆{2}/.test('𝌆𝌆')); // false
	console.log(/𝌆{2}/u.test('𝌆𝌆')); // true

유니코드 - 표기 체계

언어에 따라 유니코드 그룹이 되어있어 그것을 사용하는 방법이 있다.
이것을 이용하면 기존의 한글 처리에서 일반적으로 아래와 같이 처리하는 것을.

	const ko = /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/;
	ko.test('한글인가요'); // true

아래처럼 처리할경우 처리가 가능하다.
언어별로 설정하게되면 유니코드의 범위는 언어마다 지정되어서
일일이 유니코드 범위를 지정하지 않아도 된다.

	const ko = new RegExp('[\\p{sc=Hangul}]', 'u');
	ko.test('한글인가요'); // true
	const jp = new RegExp('[\\p{sc=Hiragana}|\\p{sc=Katakana}]', 'u');
	jp.test('カタカナ'); // true
	const ch = new RegExp('[\\p{sc=Han}]', 'u');
	ch.test('我是意大利'); // true

표기 체계 목록
https://en.wikipedia.org/wiki/Script_(Unicode)

참조

Written with StackEdit.

2021-08-03

2021-06-29

YAML

YAML

YAML (데이터 직렬화)

XML, JSON 과 같은 데이터 직렬화 방식
최대한 간결하게 파이프라인을 구성하도록 되어있음

Tag

tag를 통해 데이터 구조를 명확히 지칭
일부 seq, map, object map, set 은 암시적인 tag로 적용됨

map:
  Block style: !!map
    Clark : Evans
    Oren  : Ben-Kiki

데이터 구조 (Collection Types)

seq, array (!!seq)

  Block style:
    - one
    - two
    - three
  Flow style: [one, two, three]

map (!!map)

map:
  # Unordered set of key: value pairs.
  Block style:
    Clark : Evans
    Ingy  : döt Net
    Oren  : Ben-Kiki
  Flow style: { Clark: Evans, Ingy: döt Net, Oren: Ben-Kiki }

object map (!!omap)

objectMap:
  Block style:
    - one: 1
    - two: 2
    - three : 3
  Flow style: [ one: 1, two: 2, three : 3 ]

set (!!set)

set:
  Block tasks:
    ? Mark McGwire
    ? Sammy Sosa
    ? Ken Griffey
  # Flow style
  Flow style: { Boston Red Sox, Detroit Tigers, New York Yankees }

pair (tag need / !!pairs)

pairs:
  Block tasks: !!pairs
    - meeting: with team.
    - meeting: with boss.
    - break: lunch.
    - meeting: with client.
  Flow tasks: !!pairs [ meeting: with team, meeting: with boss ]

데이터 타입 (Scalar Types)

#========================================== string
string: abcd
swap string every line: |
  a
  long
  string
swap string last line: >
  a
  long
  string
#========================================== bool
bool:
  - true
  - True
  - TRUE
  - false
  - False
  - FALSE
#========================================== float
float:
  canonical: 6.8523015e+5
  exponentioal: 685.230_15e+03
  fixed: 685_230.15
  negative infinity: -.inf
  not a number: .NaN
#========================================== int
int:
  canonical: 685230
  decimal: +685_230
  octal: 0o2472256
  hexadecimal: 0x_0A_74_AE
  binary: 0b1010_0111_0100_1010_1110
#========================================== null
null:
  # This mapping has four keys,
  # one has a value.
  empty:
  canonical: ~
  english: null
  ~: null key
  # This sequence has five
  # entries, two have values.
  sparse:
    - ~
    - 2nd entry
    -
    - 4th entry
    - Null
#========================================== timestamp
timestamp:
  canonical:        2001-12-15T02:59:43.1Z
  valid iso8601:    2001-12-14t21:59:43.10-05:00
  space separated:  2001-12-14 21:59:43.10 -5
  no time zone (Z): 2001-12-15 2:59:43.10
  date (00:00:00Z): 2002-12-14

데이터 구조 병합 (Merge)

override 시, 먼저 참조한 데이터의 값을 먼저 사용

#============================================== object
object:
  foo: &foo
    a: 1
    b: 2
  bar:
    <<: *foo
    c: 3
  marge object a: &moa
    a: 1
    b: 2
  marge object b: &mob
    a: 3
    c: 4
  marge all:
    <<: [*moa, *mob]
  marge all with data:
    <<: [*moa, *mob]
    new data: new
#============================================== list
list:
  - &CENTER { x: 1, y: 2 }
  - &LEFT { x: 0, y: 2 }
  - &BIG { r: 10 }
  - &SMALL { r: 1 }

  - # Explicit keys
    x: 1
    y: 2
    r: 10
    label: nothing

  - << : *CENTER
    r: 10
    label: center

  - << : [ *CENTER, *BIG ]
    label: center/big

  - # Override
    << : [ *BIG, *LEFT, *SMALL ]
    x: 1
    label: big/left/small

2021-05-13

JavaScript 안티 패턴

JavaScript 안티 패턴

참조 문서

목차

  1. <script><body>최하단에 배치할 것 +
  2. 외부소스를 로컬로 관리할 것
  3. 전역변수 사용을 하지말 것 +
  4. import는 최상단에 배치할 것 +
  5. 선언없이 변수사용하지 말 것
  6. 생성자(Array/Object/Function)를 사용하지 말것 배열/객체 함수
  7. == 비교연산자를 쓰지 말 것
  8. 중괄호({…})를 생략하지 말것
  9. parseInt()에 진법을 붙일것
  10. switch에서 연속되고 기능이 있는 case사이에 break를 생략하지 말것
  11. 배열 순회시, for-in를 사용하지 말 것
  12. 배열 내에서 delete로 항목을 제거하지 말 것
  13. 반복문에서 절차에 따라 필요한 처리만 진행할 것
  14. 반복문에서 continue처리를 피할 것(불확실)
  15. 반복문안에서 try-catch 를 처리하지 말 것
  16. 돔 객체는 한번만 조회 할 것
  17. 돔 조작을 최소화 할 것
  18. 돔 레이아웃 불필요하게 초기화 하지 말 것
  19. 인라인 메소드 안에서 이벤트 처리를 하지 말 것
  20. eval()를 사용하지 말 것
  21. with()를 사용하지 말 것
  22. setTimeout/setInterval 사용시 문자열로된 callback 사용하지 말 것
  23. 기본 객체를 수정하지 말 것
  24. 증감연산자(++/--)를 사용하지 말 것
  25. this 를 따로 할당해서 쓰지 말 것
  26. 코드끝에 ;을 생략하지 말 것
  27. (ES5)정의하기전에 사용하지 말 것
  28. (Legacy)배열 순회시, array.length값을 정의해서 쓸 것

상세

<script><body>최하단에 배치할 것

script 에 정의된 소스들을 다운받는 과정에서 렌더링이 지연됨 참조

script async
스크립트 다운로드가 완료된 경우, 스크립트 파싱 후 HTML 파싱 재개

script defer
스크립트 다운로드가 완료되더라도 HTML 파싱후, 스크립트 파싱

1. 외부소스를 로컬로 관리할 것

CDN 기능 오류 나 네트워크 문제등의 외부 문제로 오류가 발생하는 것을 방지

2. 전역변수 사용을 하지말 것

다른 위치에서 접근하거나 기능이 덮어써질 가능성이 있음

Namespacing

// Bad - 중복될 가능성이 있음
const name = 'Nicholas'; // window.name === 'Nicholas'
function sayName() {
  alert(name);
}

// Good - Defined a global object MyApp and defined name variable and sayName function inside the MyApp
const MyApp = {
  name: 'Nicholas',
  sayName() {
    alert(this.name);
  }
};

Immediately Invoked Function Expression

// Bad - today variable is global, so still remains after the code has been reset
const today = new Date();

alert(`Today is ${today.getDate()}`);

// Good - today variable is local to an anonymous function, so cannot be accessed from outside of the IIFE
(function() {
  const today = new Date();

  alert( `Today is ${today.getDate()}`);
})();

4. import는 최상단에 배치할 것

가독성 문제

5. 선언없이 변수사용하지 말 것

전역변수로 생성됨으로 추가적인 문제 발생
function 의 경우, eval()을 통해야 함으로 성능 저하 발생

6. 생성자(Array/Object/Function)를 사용하지 말것 배열/객체 함수

성능면이나 가독성 면에서 더 불리함

7. == 비교연산자를 쓰지 말 것

암시적 형변환을 거치게 됨으로 타입오류나 가독성 문제가 발생===

8. 중괄호({…})를 생략하지 말것

가독성 문제

9. parseInt()에 진법을 붙일것

문자열이 0x또는 0X로 시작하면 16 진수를 사용하고 0으로 시작하면 8 진수 또는 10 진수를 사용하여 문제가 발생할 수 있음

// Bad
const month = parseInt('08');
const day = parseInt('09');

// Good
const month = parseInt('08', 10);
const day = parseInt('09', 10);

// Tip : If converting to decimals, using Number() function or '+' operator is faster.
const month = Number('08')
const day = +'09';

10. switch에서 연속되고 기능이 있는 case사이에 break를 생략하지 말것

코드 누락인지 아니면 의도된 절차인지 가독성의 문제 발생

// Bad - case 사이에 다른 처리를 한상태에서 break 없이 다른 case로 넘어가지 않도록
switch (foo) {
  case 1:
    A()
  case 2:
    B();
    break;
  ...
}

11. 배열 순회시, for-in를 사용하지 말 것

for-in 배열 사용시, 배열내의 빈값이 있을때 생략하는 문제가 발생하며. 배열순회 성능면에서도 for-in을 지양하는 것이 좋음. 그러나 가독성 면에서 array.forEach()가 유리한점도 있음.

12. 배열 내에서 delete로 항목을 제거하지 말 것

배열내에 delete로 삭제된 항목이 undefined 로 남아 배열의 전체 길이는 동일하게 유지됨, 빈 배열 항목을 처리한다는 관점에서는 역으로 이용이 가능한 부분?

// Bad
const numbers = ['zero', 'one', 'two', 'three', 'four', 'five'];
delete numbers[2]; // ['zero', 'one', undefined, 'three', 'four', 'five'];

// Good
const numbers = ['zero', 'one', 'two', 'three', 'four', 'five'];
numbers.splice(2, 1); // ['zero', 'one', 'three', 'four', 'five'];

13. 반복문에서 절차에 따라 필요한 처리만 진행할 것

중복되는 변수나 조건에 부합하지 않는 처리를 반복문에서 제외하여 성능 저하를 막을것

14. 반복문에서 continue처리를 피할 것(불확실)

과도하게 사용될경우, 가독성의 문제와 함께 javascript 엔진이 별도의 컨텍스트로 관리하기에 성능문제가 발생할 수 있음

추가로 찾아봤을때, breakcontinue가 나쁜 프로그래밍 관행입니까?에서 처럼 무조건 안쓰는것이 옳다고는 할수 없는 것으로 보인다. What is the point of the no-continue rule?의 내용에서는 countinuego to 처럼 continue label로 처리되는것에 대해 금지한다는 의미인것으로 애기하고 있다.
차라리 filter()의 형태로 정제된 리스트만 처리하면 되지 않을까?

let loopCount = 0;
// Bad
for (let i = 1; i < 10; i += 1) {
  if (i > 5) {
    continue;
  }
  loopCount += 1;
}

// Good
for (let i = 1; i < 10; i += 1) {
  if (i <= 5) {
    loopCount += 1;
  }
}

15. 반복문안에서 try-catch 를 처리하지 말 것

루프가 반복될때마다 예외 개체가 현재 범위에서 저장되기 때문

// Bad
const {length} = array;
for (let i = 0; i < length; i += 1) {
  try {
    ...
  } catch (error) {
    ...
  }
}

// Good
const {length} = array;
function doSomething() {
  try {
    ...
  } catch (error) {
    ...
  }
}
for (let i = 0; i < length; i += 1) {
  doSomething();
}

16. 돔 객체는 한번만 조회 할 것

성능저하 문제

17. 돔 조작을 최소화 할 것

innerHTML, appendChild() 호출시마다 DOM을 다시 그리게되어 성능문제 발생

18. 돔 레이아웃 불필요하게 초기화 하지 말 것

layout thrashing으로 인해 성능저하 문제

layout thrashing
layout thrashing을 강제하는 것
DOM 요소가 변경될 경우, 기존 layout은 무효화 되어 추가로 layout 호출시 새로 계산이 필요하여 성능지연이 발생

// Bad
elementA.className = "a-style";
var heightA = elementA.offsetHeight; // layout is needed
elementB.className = "b-style"; // invalidates the layout
var heightB = elementB.offsetHeight; // layout is needed again

// Good
elementA.className = "a-style";
elementB.className = "b-style";
var heightA = elementA.offsetHeight; // layout is needed and calculated
var heightB = elementB.offsetHeight; // layout is up-to-date (no work)
// Bad
function resizeWidth(paragraphs, boxElement) {
  const {length} = paragraphs;

  for (let i = 0; i < length; i += 1) {
    paragraphs[i].style.width = `${boxElement.offsetWidth}px`;
  }
}

// Good
function resizeWidth(paragraphs, box) {
  const {length} = paragraphs;
  const width = boxElement.offsetWidth;

  for (let i = 0; i < length; i += 1) {
    paragraphs[i].style.width = `${width}px`;
  }
}

19. 인라인 메소드 안에서 이벤트 처리를 하지 말 것

소스 관리나 이벤트 처리 관점에서 혼란을 일으킴

20. eval()를 사용하지 말 것

구문 분석을 처리하는 과정에서 성능 문제가 크게 발생하며 보안측면에서도 매우 문제가 많음

21. with()를 사용하지 말 것

처리되는 과정에 대해 가독성 문제가 있으며 별도의 영역을 생성하여 성능문제도 발생

// Bad
with(document.getElementById('myDiv').style) {
  background = 'yellow';
  color = 'red';
  border = '1px solid black';
}

// Good
const {style} = document.getElementById('myDiv');
style.background = 'yellow';
style.color = 'red';
style.border = '1px solid black';

22. setTimeout/setInterval 사용시 문자열로된 callback 사용하지 말 것

내부적으로 문자열 함수에 대해 eval()이 처리 됨으로 20. 과 같은 문제 발생

// Bad
function callback() {
  ...
}
setTimeout('callback()', 1000);

23. 기본 객체를 수정하지 말 것

예측할 수 없는 오류가 발생할 가능성이 큼, 하지만 polyfill 처럼 긍정적인 사용방향도 있음

Monkey Patch
몽키패치- 런타임 중에 코드를 수정하는 것
Polyfill 처럼 구형 브라우저를 지원하기 위해 구형 브라우저의 코드를 수정해야 하거나, 개발 후 테스트를 진행할때 임시로 데이터 요청을 다른곳으로 요청하던지 하는 방식으로 사용될 수 있다. 그러나 동적으로 수정한다는 점에서 문제의 소지가 될 수 있다는점

24. 증감연산자(++/–)를 사용하지 말 것

i++++i와 같이 처리와 할당의 관점이 혼란을 야기해서 편의에 비해 문제소지가 있음

// Increment
let a = 1;
console.log(a++);    // 1 
console.log(++a);    // 3
// Decrement
let b = 1;
console.log(b--);    // 1
console.log(--b);    // -1

25. this 를 따로 할당해서 쓰지 말 것

클로저로 사용할 수 있지만 가독성의 문제, 관련하여 다른 의견에서는 오히려 명시적인 구분이 된다는점에서 장점도 있다는 의견이 있음

// Bad
function() {
  const self = this;
  return function() {
    console.log(self);
  };
}
function() {
  const that = this;
  return function() {
    console.log(that);
  };
}
function() {
  const _this = this;
  return function() {
    console.log(_this);
  };
}

// Good
function printContext() {
  return function() {
    console.log(this);
  }.bind(this);
}
function printContext() {
  return () => console.log(this);
}

26. 코드끝에 ;을 생략하지 말 것

구문의 분리가 명확하지 않고 내부적으로 누락된 ;을 처리하는 과정에서 성능 문제 발생

27. (ES5)정의하기전에 사용하지 말 것

가독성 문제와 함께 호이스팅으로 인해 혼란 발생

28. (Legacy)배열 순회시, array.length값을 정의해서 쓸 것

IE10 과 같은 브라우저에서는 큰 성능문제를 일으킴

2021-03-22

2021-03-22 GraphQL

2021-03-22 GraphQL

GraphQL

페이스북에 의해 REST 구조를 개선하기 위한 방식으로 개발된 시스템

구조

기존 REST는 우측과 같이 서버에서 데이터를 가져올때 연관된 요청을 모두 요청 해야한다. 하지만 그 과정에서 항상 모든 정보가 쓰이진 않으며 처리될때 어떤 정보를 받게될지 명확하지 않다.
이점을 개선하여 SQL 과 같이 필요한 정보만을 타입 과 데이터 구조를 요청하게 된다.

내부 구조는 간단히 키워드로만 구성된 계층구조로 조회하는 형태로 보인다.
상세한 구조는 document에 심층적으로 소개되어있으니 그걸 참조

{
  hero {
    name
  }
}
{
  "data": {
    "hero": {
      "name": "R2-D2"
    }
  }
}

장단점

REST의 일부 단점을 개선 하였지만 그렇다고 완벽한것은 아닌것
알아서 상황에 맞는 구조로 설계하기

  • 필요한 데이터만 요청
  • 어떤 데이터구조가 이용될지 명확
  • 한번의 요청으로 필요한 데이터 조회가능

  • 기존 http 캐싱 구조를 사용할 수 없음
  • 파일 업로드의 명확한 구현이 되어있지않음
  • 요청 필터링의 어려움

    사용될 데이터를 요청할때 구조가 정의되는 탓에 항상 최적의 데이터를 조회한다고 볼수없기때문

  • 구조가 복잡해지는 문제
  • 이미 REST 구조로도 처리가 가능한 경우가 존재

Written with StackEdit

참조
5 reasons you shouldn’t be using GraphQL
GraphQL의 단점과 대안

2021-03-22 Pub-Sub 구조

2021-03-22 Pub-Sub 구조

Publish - Subsclibe

구조

아래와 같이 publisher 가 topic 계층으로 전달한 메세지를 broker 에서 해당 topic 을 보고있는 subscriber에게 메세지를 전달하는 구조

subscriber
publisher
topic/location
topic/state
topic/state
topic/location
topic/state
topic/location
state
location
state,location
update
broker

Written with StackEdit.

2020-11-30

js Proxy & Reflect (like observer)

js Proxy & Reflect (like observer)

MDN Proxy / MDN Reflect

proxy 와 reflect는 동일하게 동작하지만
reflect로 정의된 객체를 proxy로 재정의하여
동작을 할당한다고 보면 될것으로 생각됨

아래와 같은 관계로 재정의 되지않은 기본동작 정의

new Proxy(obj, {
  get: Reflect.get,
});

정리

MDN handler

var 대상Object = {} ;
var hander = new handler(....참조);
var obj = new Proxy(대상Object,  handler);

handler props

get
prop 값 호출시

get: function (대상_object,대상_prop_명) {}

set
prop 값 설정시

set: function (대상_object, 대상_prop_명, 설정값) {}

deleteProperty
prop delete시

deleteProperty: function (대상_object, 대상_prop_명) {}

ownKeys
Object.keys(대상obj) 호출시

ownKeys: function (object_내부의_모든_props) {}

has
prop 조회시

has: function (대상_object, 찾을_prop_명) {}

defineProperty
prop 조회시

defineProperty: function (대상_object, 추가된_prop_명, 정의된_값의_속성) {}

getOwnPropertyDescriptor
설명 요청시

getOwnPropertyDescriptor: function (대상_object, 설명을_검색할_prop_명) {}

Written with StackEdit.