Jan 16, 2018 - codespitz73_part3_2

코드스피츠73 part3_2

ITERATION & GENERATOR

ES6 LOOP 지연루프

const loop = (iter, f) => {
    //iterable이라면 iterator를 얻음
    if(typeof iter[Symbol.iterator] == 'function'){
        iter = iter[Symbol.iterator]();
    }
    //iteratorObject가 아니면 건너뜀(숼드 패턴)
    if(typeof iter.next != 'function') return;
    
    while (true){
        const v = iter.next();
        if(v.done) return; //종료 처리
        f(v.value);// 현제값을 전달함
    }
    
};

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

loop(iter, console.log);
//4
//3
//2
//1

위에 loop 함수를 사용하지 않고 내장 반복처리기들

  • 배열해체 Array destructuring

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


const [a,...b] = iter;
// 이터레이터도 테스트
// const [a,...b] = iter[Symbol.iterator]();
// const [a,...b] = [1,2,3,4];
// array도 이터레이터를 상속 받음
// console.log(typeof [][Symbol.iterator]);
// String도 이터레이터를 상속받음
// console.log(typeof ""[Symbol.iterator]);

console.log(a,b);
// 4,[3,2,1]

  • 펼치기 Spread

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

const a =[...iter];

console.log(a);
//[4,3,2,1]

배열을 전달 하는것 보다 객체를 전달하는것은 통제권을 객체안에서 가지고 올수 있다.

  • Rest Parameter 나머지 인자


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

const test = (...arg)=> console.log(arg);
test(...iter);


위에 펼치기와 비슷 하지만 함수 내부에서 해체되어 들어온다.

  • 함수 선언시에 사용되면 Rest Parameter
  • 함수가 아닌곳에서 사용하면 Spread

function() {
    // 지역변수
    arguments
    // 전역변수
    location
    //동적컨텍스트
    this
}

() => {
    // 자유변수 아니면 전역변수로 선언됨
    arguments
    location
    this
}

보다명확하게 단일한 규칙으로 표현하기 위해서 위처럼 지원한다.(ES6)


// ES5
const cls = function() {
  this.base = arguments;
}

new cls(1,2);
new cls(1,2,3);

const arr = [1,2,3,4,5,6,7,8];
// ES5에서는 arr를 생성자에 적용시킬 방법이 없다.
new cls();


// ES6
const cls = function(...arg){
  this.base = arg;
}
//ES6에서는 Spread로 적용가능
new cls(...arr);

FOR OF

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

//제어문이 소비 하는 방식
for (const v of iter){
    console.log(v);    
}
//4
//3
//2
//1

연습 문제

  • 객체로의 캡슐화 예제

const N2 = class{
    constructor(max){
        this.max = max
        
    },
    [Symbol.iterator](){
        let cursor = 0, max = this.max;
        return {
            done : false,
            next(){
                if(cursor > max){
                    this.done = true;
                }else{
                    this.value = cursor * cursor;
                    cursor ++;
                }
                return this;
            }
        };
    }
};

//Spread
console.log([... new N2(5)]);

for (const v of new N2(5)){
    console.log(v);
}

LOOP를 실행 할때 메모리에 값을 가지고 실행 했는데 지금은 함수에서 값을 가지고 있어서 지연 실행이 가능

Generator

위에 함수를 generator로 재구현

  • 함수로써의 캡슐화

const generator = function*(max) {
  let cursor = 0;
  while (cursor < max){
      yield cursor * cursorl
      cursor++;
  }
};

//Spread
console.log([... generator(5));

for (const v of generator(5)){
    console.log(v);
}

그런데 while을 썼는데 멈추었다. 이건 코루틴에 기초이다. generator 블록은 코루틴이라서 함수에서 지연호출이 가능함 현대 모던 언어에서는 코루틴을 가지고 있다.

오늘도 최고의 강의 였습니다. 감사합니다. ㅜㅜ

참조


Jan 15, 2018 - codespitz73_part3_1

코드스피츠73 part3_1

ITERATION & GENERATOR

INTERFACE
  1. 인터페이스란 사양에 맞는 값과 연결된 속성키의 셋트
  2. 어떤 Object라도 인터페이스의 정의를 충족 시킬수 있다.

const obj = {
    
    test(str){
        return true;      
    }
    
};

const Test = class{
    test(str){
        return true;
    }
};

//덕타이핑
const test = new Test();

//컴파일타임에는 타입체크가 안되니

우리 머리속에서만 있는 약속이라서 어렵다.

자바 스크립트에서 미리 정의하고 있는 인테페이스

ITERATOR
  1. next라는 키를 갖고
  2. 값으로 인자를 받지 않고 IteratiorResultObject를 반환하는 함수
  3. IteratiorResultObject는 value와 done이라는 키를 갖고 있다.
  4. 이중 done은 계속 반속 할수 있을지 없을지에따라 boolean 값을 반환

const iterator = {
    next() {
        return {
            value : 1,
            done : true
        };
    }
};


const con = document.getElementById("log");
const log = (...args) => con.innerHTML += '<br/>' + args.join(' ');

const iterator = {
    data : [1,2,3,4],
    next() {
        return {
            value : this.data.pop(),
            done : this.data.length === 0
        };
    }
};

let iResult = iterator.next();
log(iResult.value + ' , '+ iResult.done);
iResult = iterator.next();
log(iResult.value + ' , '+ iResult.done);
iResult = iterator.next();
log(iResult.value + ' , '+ iResult.done);
iResult = iterator.next();
log(iResult.value + ' , '+ iResult.done);
iResult = iterator.next();
log(iResult.value + ' , '+ iResult.done);


ITERABLE
  1. Symbol.iterator라는 키를 갖고
  2. 값으로 인자를 받지 않고 IteratorObject를 반환

const con = document.getElementById("log");
const log = (...args) => con.innerHTML += '<br/>' + args.join(' ');

const iterator = {
    data : [1,2,3,4],
    next() {
        return {
            value : this.data.pop(),
            done : this.data.length === 0
        };
    }
};

// new가 되지 않음
const s = Symbol();

const Iterator = class{
    constructor(){
        this.data = [1,2,3,4];
    },
    next() {
        return {
            value : this.data.pop(),
            done : this.data.length === 0
        };
    }
};

// Symbol은 참조가 일어나지 않고 복사가 일어난다(유일값)
const iterable = {
    
    //['@@iterator'] 
    [Symbol.iterator](){
        return new Iterator();
    }
    
}

LOOP


const con = document.getElementById("log");
const log = (...args) => con.innerHTML += '<br/>' + args.join(' ');

const a ={
    '0':3,
    a:5,
    [Symbol()]:7,
    b:6
};

let b = 0;
const c ={
    [b++]:3,
    [b++]:4   
};

ES6에서는 object에 순서가 생겼다.


let arr = [1,2,3,4];
//계속 반복할지 판단
while (arr.length > 0){
    //반복시마다 처리할 것
    console.log(arr.pop());
}
// 호출지연
// 값으로 호출 함수 내부에서 가지고 감 판단여부 및 실행
const iterator = {
    arr : [1,2,3,4],
    next() {
        return {
            //반복시마다 처리할 것
            value : this.arr.pop(),
            //계속 반복할지 판단
            done : this.arr.length === 0
        };
    }
};

문은 실행이 바로 됨 함수는 바로 실행이 안됨


//연산지연 
const a = b || c;

const d = b && c;

//지연 실행
const obj = {
    get a() {
        return 3;
    }
}
// 함수 호출됨
obj.a;

//호출지연
function a() {

      
}

참조


Jan 15, 2018 - POP_part14

사상 - 프로그래밍 이데올로기

UNIX 사상

절약의 원칙

큰 코드는 작성하지 않는다. 큰 코드는 제어 불능 코드를 덧붙이지 않는다.

투명성의 원칙

소프트웨어 동작의 시각화

  • 투명성 - 소프트웨어 동작에 관해 한눈에 봐도 곧바로 무엇을 어떻게 하고 있는지 이해할수 있을것

  • 개시성 - 소프트웨어 내부 상태에 관해 감시할 수 있거나 보여줄 수 있을 것

투명성과 개시성을 지니게끔 하는 설계가 사용자에게 직접적인 영향은 없다 하지만 프로젝트 전체에는 암묵적으로 좋은 영향을 미친다. 왜냐 하면 소프트웨어 동작을 시각화하면 디버깅이나 오류 확인이 간단해 지기 때문

디버깅을 위한 기능을 설계 초기 단계에 넣어두자 디버깅을 쉽게 만들어 줄 장치를 정식 코드에 넣는 데 망서리지 말자

안정성의 원칙

안정된 소프트웨어로 만들려면 내부 구조를 쉽게 설명할 수 있어야 한다. 이를 위해 투명성과 단순성을 충족하는 코드를 작성하도록 한다. 투명하고 단순한 코드를 항상 유지하도록 하자.

  • 코드리뷰

  • 특이한 입력이나 극던적으로 큰 입력에 견딜 수 있음을 검증(Validation)

참조