코드 스피츠 강의

코드 스피츠 강의

코드스피츠-es6

es6와 관련된 강의는 5개가 있다. 프론트엔드 개발자로서 생소한 부분도, 몰랐던 부분도 많았던 강의내용이었다.

1강

철학(왜 그렇게 코드를 짰는가?) - 개발을 할 때 고려해야 할 도구(마음)
  • 가치(의사소통, 단순함, 유연함)
  • 원칙(지역화, 중복제거, 대칭성-get/set)
  • 패턴(=선배들의 경험)(계발론, 설계론, 각종 적용 패턴)
  • 동기(돈, 시간)
프로그램
  • language code(lint time) -> machine language(compile time) -> file(exe같은…) -> load -> run(run time) -> terminate
  • 메모리에 적재된 게 프로그램 (load부터)
  • run time error는 잡기도 힘들고, 많이 일어나면 프로그램을 뒤집어 엎어야…
  • context error는 기획자의 잘못된 정보도 있지만, 코딩 스타일 때문…
스크립트
  • language code(lint time) - file - load - machine language - run(run time) - terminate
Runtime
  • 메모리에 적재하는 과정
  • instruction: cpu가 해석할 수 있는 명령어
&와 * (c에서)
  • & - 주소값
  • * - 실제값
double dispatch - linked list의 구조
  • 한 번에 값을 찾는 게 아니라 하나의 주소값에 대한 값을 찾는 것(두 번에 걸려 찾는 것 - 참조의 참조)
Lexical Grammar(어휘 문법)
  • Control Charater(제어문자)
  • White Space(공백문자)
  • Line Terminators(개행문자)
  • Comments(개행문자)
  • Keyword(예약어)
  • Literals(리터럴)- 더이상 나눌 수 없는 객체나 값(언어마다 다름)
Language Element
  • Statements문(공문, 식문, 제어문, 선언문, 단문, 중문)
  • if나 for문같은 문장은 메모리에 남지 않고, 컴파일할 때 혹은 실행할 때 인지 및 처리만 하고 있는 것 따라서, 문은 실행기에게 주는 힌트다.(Control Statements라고 불리기도 한다.)
  • 공문: 아무것도 없는 문도 인정한다(for(var i=0; i<5; i++);;;; -> 에러 안남, 자바스크립트는 공문 인정)
  • if (true) a = 3; else if (a >2) b = 3; else b = 5; // 이 식은 if, else if, else로 이루어져있는 것 같아 보이지만, 실제로는 if문과 else문으로 이루어져 있다.(else아래부터가 모두 else문이다.)
    if (true) a = 3; else {if (a >2) b = 3; else b = 5;} // 같은 의미이다.
  • Expression식(값식, 연산식, 호출식) - 하나의 값 == 값이다.
  • Identifier식별자(시본형, 참조형, 변수, 상수)
Sync Flow
  • 동기화 작동 또는 동기화 흐름
  • 메모리에 적재되어 있는 동안에는 간섭하지 못한다.
  • 제어할 수 있다면 Control Sync Flow(Flow Control) - 흐름을 바꿔줄 수 있는 명령어를 쓸 수 있다.(흐름 제어문)
Sub Flow
  • 필요할 걸 불러서 사용할 수 있다.(함수나 클래스 같은 것)

2강

Record, Completion record

  • Flow Control Statement, Completion Record
  • statement - record: 레코드를 만들고, 레코드를 실행하는 과정 -> 자바스크립트 엔진의 주 작동 원리
  • 엔진 스텍이 매년 달라짐

Direct Flow Control

  • 직접 플로우하는 컨트롤
  1. LABEL
  • Identifier: $로 시작할 수 없는 것만 빼놓고, 언더바로 시작할 수 있고… 뭐 그런 변수 이름 규칙과 동일하게 하고, 콜론을 붙이면 그게 LABEL
<!-- example -->
<html>
  <script>
    test:;
  </script>
</html>
자체만으로 존재할 수는 없음 -> 공문은 가능(문이 있어야 한다.)
  • scope -> 함수로 결정
    레이블스코프
<html>
  <script>
  :{
    abc:3;
  }
  </script>
</html>
<html> // flow control
  <script>
  abc:{
    console.log('start');
      
    if (true) {
    // break; // error(syntax error)
      break abc;
    }
    console.log('end');
  }
  </script>
</html>
break, continue로 아래로 빠져나올 수 밖에 없다.
// Auto Label
temp38:
for(let i=0; i<10; i++) {
  if (i == 5) break temp38;
}
console.log('end');
우리가 이름을 생략하면 javascript가 자동으로 temp38같은 레이블 이름을 생성해줌(iteration, switch -> undefined named label)
앞주석을 쓰기 위해서 label을 사용
console.log('end') // a
console.log('000000') // b

a:console.log('end');
b:console.log('00000');

// 주석문 같음
  1. SWITCH - Special Label Block, Fall Through, Auto Label(break안하면 계속 떨어지는 거)
// Auto Label
// case label, default label만 사용 가능
switch(true) {
  default: console.log('c'); // 위에서 아래로(자바스크립트)
  // case true: console.log('a');
  case  1: console.log('a');
  case  false: console.log('b');
  // 브라우저별로 다름(case를 돌고 일치하는 게 없으면 default)
}
Runtime switch
// 값에 대한 라우팅 - switch
var  a = true
temp17:
switch(a) {
  default: console.log('c');
  case  f1(a): console.log('a'); break temp17;
  case  f2(a): console.log('b');
}
console.log('end');
switch(true) {
  case  network() === 'online':
  case  network() === 'wifi':
  case  network() === 'offline':
  case  localCache():
  default: // 안내문..
}
else if(){…}문은 없다.
if (c === 1) {

} else if (c ===2) {

} else {

}

if (c === 1) {

} else {
  if ( c === 2) {
  
  } else {
  
  }
}
https://www.youtube.com/watch?v=U6dmAT8KImY&feature=youtu.be
‘’, false, 0, undefined, null, NaN // falsy
falsy가 아닌 것등 // truthy
예외사항
for (; ; ;) { // 가운데(조건)를 넣지 않으면 원래는 falsy인데 예외사항으로 truthy가 된다. -> 무한루프
}
// 일반적
while(truthy) {

}

do {

} while (truthy)

// 맞는 문장
do  a++; while(a); // 세미콜론 뒤에는 공문이 온 거

for ( of );
for ( in );

3강 (Iteration & Generator)

Interface in JS

  1. 인터페이스란 사영에 맞는 값과 연결된 속성키의 세트
  2. 어떤 object라도 인터페이스의 정의를 충족시킬 수 있다.
  3. 하나의 object는 여러 개의 인터페이스를 충족시킬 수 있다.
Interface
  1. test라는 키를 갖고
  2. 값으로 문자열인자를 1개 받아 boolean 경과를 반환하는 함수가 온다.
{
  test(str){return true;}
}
Iterator Interface
  1. next라는 키를 갖고
  2. 값으로 인자를 받지 않고 IteratorResultObject를 반환하는 함수가 온다.
  3. IteratorResultObject는 value와 done이라는 키를 갖고 있다.
  4. 이 중 done은 계속 반복할 수 있을지 없을지에 따라 불린값을 반환한다.
{
  next() {
    return {value:  1, done:  false};
  }
}
{
  data: [1, 2, 3, 4],
  next(){
    return {
      done:  this.data.length == 0,
      value:  this.data.pop()
     };
  }
}
Iterable Interface
  1. Symbol.iterator라는 키를 갖고
  2. 값으로 인자를 받지 않고 Iterator Object를 반환하는 함수가 온다.
{
  [Symbol.iterator](){
    return {
      next(){
        return {value:  1, done:  false};
      };
    }
  }
}

Loop to Iterator

While문으로 살펴보는 Iterator
let arr = [1, 2, 3, 4];
while(arr.length > 0) {
  console.log(arr.pop());
}
while(계속 반복할지 판단) {
  반복시마다 처리할 것
}

{
  data: [1, 2, 3, 4],
  next(){
    return {
      done:  this.data.length == 0, // 계속 반복할지 판단
      value:  this.data.pop() // 반복시마다 처리할 것
    };
  }
}

ES6 + Loop

직접 Iterator 반복처리기를 구현
const  loop = (iter, f) => {
  // iterable이라면 iterator를 얻음
  if (typeof  iter[Symbol.iterator]== 'function') {
    iter = iter[Symbol.iterator]();
  } else return;

  // iteratorObject가 아니라면 건너뜀
  if (typeof  iter.next != 'function') return;
  
  do {
    const  v = iter.next();

    if (v.done) return; // 종료처리
    f(v.value); // 현재 값을 전달함
  } while(true);
};
내장반복처리기
  • Array destructuring (배열해체)
  • Spread (펼치기)
  • Reset Parameter (나머지인자)
  • For of
for (const v of iter) {
  console.log(v);
}
=> Iterator를 만들면 위의 문법들을 다 지원한다.
=> 반복을 위해 iterable을 만든다.
블로킹: cpu가 돌아가는데 그걸 소프트웨어나 다른 행동을 할 수 없는 것
루프를 분산해서 거는 스킬이 필요!
루프 조건을 걸 때, limit를 거는 것
함수가 만들어질 때, 함수 밖에 있는 변수들을 캡쳐해서 참조할 수 있는 기능이 있다. => free value

Generator

iterator를 좀 더 간단하게 구현
서스펜션 기능!
마무리: iterator, iteratale, generator의 관계/기능

참고

Generators

4강 (Abstract loop & Lazy execution)

Abstract Loop(루프 추상화)

Complex Recursion

단순한 배열을 루프인 경우는 간단히 이터레이션을 작성할 수 있다.
{
  [Symbol.iterator](){return  this;},
  data: [1, 2, 3, 4],
  next() {
    return {
      done: this.data.length === 0,
      value:  this.data.shift()
    };
  }
}
-> 목적이 있는 루프(목적을 바꾸면 다시 루프를 짜야 함)

Abstract Loop

다양한 구조의 루프와 무관하게 해당 값이나 상황의 개입만 하고 싶은 경우
결국 제어문을 직접 사용할 수 없고 구조객체를 이용해 루프실행기를 별도로 구현
팩토리 + 컴포지트 + Iteratable
(data, f) => {
  let  v;
  while (v = data.shift()) {
    if (!(v  instanceof  Object)) {
      f(v)
    } else {
      if (!Array.isArray(v)) v = Object.values(v);
      data.unshift(...v);
    }
  }
}

Lazy Execution

내장되어 있는 게 제일 빠르다. 직접 만드는 것보다 내장되어 있는 메서드등을 사용하자!
최적화 -> 돔 랜더링 최적화
알고리즘 ->표준 라이브러리를 사용하고 if 중첩을 줄이는 데 집중하자

Yield

필요한 만큼만 루프를 돌릴 수 있다.
const add = function*(data) {
  for (const v of data) {
    console.log("add", add.cnt++);
    if (v % 2) yield  v;
  }
};
odd.cnt = 0;
for(const v of add([1, 2, 3, 4])) console.log(v);

Yield란?

  • yield 키워드는 generator function을 중지하거나 재개하는 데 사용된다.
  • yield는 generator가 한 번 멈추게 하고 generator의 새로운 값을 반환한다. 다음 번의 next()가 호출된 후, yield 이후에 선언된 코드가 바로 실행된다.
function* test() {
  var index = 0;
  while (index <= 2) yield  index++;
}

var iterator = test();
console.log(iterator.next()); // { value: 0, done: false }
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
참고-MDN
=> 자바스크립트가 제일 어려운 언어. 매년 새로운 기능?이 나오고 있음.
현재 동영상은 2015년 기준인데… 자바스크립트의 기본임
근데… 기본은 아닌 듯… 내용이 어려움…

5강 (Block, NonBlock & Sync, Async)

Block, NonBlock

  • flow(명령이 흘러야 하는데 멈춰 있는 것) -> block -> blocking-> 풀릴 때까지 아무 것도 못함(컴퓨터가 죽은 것처럼 보임)
  • 길게 Blocking -> Blocking
  • 짧게 Blocking -> NonBlocking
  • Flow is Blocking: 프로그램이 실행되면 도중에 멈춰지지 않고 끝까지 실행된다.(cpu가 blocking)
for(const i of (function*(){
  let  i = 0;
  while(true) yield  i++;
})()) console.log(i);

// script timeout
// 플랫폼의 안정성을 위해 블록되는 시간이 길면 강제 종료시킴

blocing function

점유하는 시간만큼 블록을 일으키는 함수
const f = v->{
  let i = 0;
  while(i++ < v);
  return i;
};

f(10);
f(10000000000);
// 인수에 따라 블로킹인지 아닌지를 판별한다.
배열 순회, 정렬 - 배열 크기에 따라
DOM 순회 - DOM의 하위구조에 따라
이미지 프로세싱 - 이미지 크기에 따라

blocking evasion

  • 독점적인 cpu점유로 인해 모든 동작이 정지됨
  • 타임아웃체크에 의해 프로그램이 강제 중단됨
  • 따라서, 블로킹의 조합을 예측할 수 없음
  • 시분할 운영체제의 동시 실행 - 2개의 작업이 있을 때, 1개의 작업을 끝내고, 다른 1개를 끝내는 것이 더 빠름
  • 자바스크립트 스레드
  • Main ui thread I (프레임 - 명령큐)
  • Background thread N
  • Web worker thread

Main ui thread(time slicing)

const looper = (n, f)=>{
  for(let i = 0; i<n; i++) f(i);
};

looper(10, console.log);
looper(10000, console.log);

// time slice manual
const  looper = (n, f, slice = 3)=>{ // 아무리 큰 n이 와도 블로킹을 막을 수 있다.(slice = 3 덕분에)
  let limit = 0, i = 0;
  while(i<n) {
    if (limit++ < slice) f(i++);
  }
};

Sync, Async

  • sync: 서브루틴이 즉시 값을 반환함(함수가 값을 리턴하면 sync)
  • async: 서브루틴이 콜백을 통해 값을 반환함(함수가 값을 리턴이하는 게 아니라 콜백으로 리턴하면 async)
// sync
const double = v => v * 2;
console.log(double(2)); // 4

// async
const double = (v, f) => f(v * 2);
double(2, console.log) // 4

sync

block -> 즉시 플로우 제어권을 반환하지 않음(normalAPI, legacyAPI)
const sum = n => {
  let sum = 0;
  for(let i = 1; i <= n  i++) sum += i;
  return sum;
};
sum(100);
non block -> 즉시 플로우 제어권을 반환함(IOCP, Future, img.complete - 옛날 legacyAPI, oldAPI)
const sum = n => {
  const result = { isComplete: false }
  requestAnimationFrame(_ => {
    let sum = 0;
    for(let i = 1; i <= n; i++) sum += i;
    result.isComplete = sum;
  });
  return  result;
};

const result = sum(100);
const id = setInterval(() => {
  if(result.isComplete) {
  clearInterval(id);
  console.log(result.value);
  }
}, 10);

async

block -> 즉시 플로우 제어권을 반환하지 않음(TRAP! 이렇게는 짜면 안된다.)
const sum = (n, f) => {
  let sum = 0;
  for(let i = 1; i <= n; i++) sum += i;
  return  f(sum);
};
sum(10, console.log);
console.log(123);
// 55 -> 123
none block -> 즉시 플로우 제어권을 반환함(modernAPI)
const sum = (n, f) => {
  requestAninationFrame(_ => {
    let  sum = 0;
    for(let  i = 1; i <= n; i++) sum == i;
    f(sum);
  });
};
sum(10, console.log);
console.log(123);
// 123 -> 55
코드를 예시로 드는데… 딱히 내가 접해본 게 아닌 코드…
background trhead를 1000개를 잡아서 돌린다… 이런 걸 어디에 쓸까?ㅎㅎ
cpu core 수의 2배정도까지만 잡아야 한다. 시분할 os 전환때문에 느려진다.

댓글

가장 많이 본 글