코드 스피츠 강의
코드스피츠-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
- 메모리에 적재하는 과정
- instruction: cpu가 해석할 수 있는 명령어
&- 주소값*- 실제값
- 한 번에 값을 찾는 게 아니라 하나의 주소값에 대한 값을 찾는 것(두 번에 걸려 찾는 것 - 참조의 참조)
- Control Charater(제어문자)
- White Space(공백문자)
- Line Terminators(개행문자)
- Comments(개행문자)
- Keyword(예약어)
- Literals(리터럴)- 더이상 나눌 수 없는 객체나 값(언어마다 다름)
- 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식별자(시본형, 참조형, 변수, 상수)
- 동기화 작동 또는 동기화 흐름
- 메모리에 적재되어 있는 동안에는 간섭하지 못한다.
- 제어할 수 있다면 Control Sync Flow(Flow Control) - 흐름을 바꿔줄 수 있는 명령어를 쓸 수 있다.(흐름 제어문)
- 필요할 걸 불러서 사용할 수 있다.(함수나 클래스 같은 것)
2강
Record, Completion record
- Flow Control Statement, Completion Record
- statement - record: 레코드를 만들고, 레코드를 실행하는 과정 -> 자바스크립트 엔진의 주 작동 원리
- 엔진 스텍이 매년 달라짐
Direct Flow Control
- 직접 플로우하는 컨트롤
- 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');
// 주석문 같음
- 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
- 인터페이스란 사영에 맞는 값과 연결된 속성키의 세트
- 어떤 object라도 인터페이스의 정의를 충족시킬 수 있다.
- 하나의 object는 여러 개의 인터페이스를 충족시킬 수 있다.
- test라는 키를 갖고
- 값으로 문자열인자를 1개 받아 boolean 경과를 반환하는 함수가 온다.
{
test(str){return true;}
}
Iterator Interface- next라는 키를 갖고
- 값으로 인자를 받지 않고 IteratorResultObject를 반환하는 함수가 온다.
- IteratorResultObject는 value와 done이라는 키를 갖고 있다.
- 이 중 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- Symbol.iterator라는 키를 갖고
- 값으로 인자를 받지 않고 Iterator Object를 반환하는 함수가 온다.
{
[Symbol.iterator](){
return {
next(){
return {value: 1, done: false};
};
}
}
}
Loop to Iterator
While문으로 살펴보는 Iteratorlet 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의 관계/기능
참고
Generators4강 (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 전환때문에 느려진다.
댓글
댓글 쓰기