내용 보기

작성자

관리자 (IP : 172.17.0.1)

날짜

2020-09-01 07:55

제목

[TypeScript] 함수 호출 방식 / this 타입 / 제네레이터 함수 / 반복자


10. 함수 호출 방식
function add(a: number, b: number) {
    return a + b;
}
 
add(1020);  // 30으로 평가
add.apply(null, [1020]);  // 30으로 평가
add.call(null1020);  // 30으로 평가
add.bind(null1020)();  // 30으로 평가
cs

apply : 함수 안에서 값을 this로 한정하며(여기서는 this를 null로 한정) 두 번째 인수를 평쳐 함수에 매개변수로 전달

call : apply와 같은 기능을 수행하지만 평쳐 전달하지 않고 순서대로 전달

bind : this 인수를 함수의 인수 목록으로 한정한다(여기서는 this를 null로 한정) bind는 함수를 호출하지 않고 새로운 함수를 반화하는데 개발자는 ()나 .call을 이용해 반환된 함수를 호출하거나 .apply로 아직 한정하지 않은 매게 변수를 추가로 전달


11. this 타입

let x = {
    a() {
        return this;
    }
}
x.a()  // a()의 바디안에서 this는 객체 x
cs

a() 메서드 안에서 this는 x객체를 가르킨다.
하지만 호출이 일어나기 전 어느 시점에서 a를 다시 할당하면 결과가 달라진다!

let a = x.a;
cs

위 처럼 호출시 a()메서드의 this는 정의되지 않은 상태이다. 

가령 다음과 같은 날짜의 타입을 포매팅 하는 유틸리티 메서드가 있다.

function fancyDate() {
    return `${this.getDate()} / ${this.getMonth() + 1/ ${this.getFullYear()}`;
}
console.log(fancyDate.call(new Date));
cs

위 fancyDate메서드는 this로 한정할 Date를 제공해줘야 정상적으로 날짜 관련 함수 사용이 가능하다.
깜빡하고 Date를 한정하지 않으면 런타임 예외가 발생한다.
이 처럼 this는 함수를 어떻게 호출하느냐에 따라 영향을 받는다.
console.log(fancyDate());  // 에러


12. 제네레이터 함수

제네레이터는 여러개의 값을 생성하는 편리한 기능을 제공한다.
제네레이터 함수를 이용하면 값을 생산하는 속도도 정교하게 조절할 수 있다.
제네레이터 함수는 게으르게 동작(호출되었을때 실행됨.)하기 때문에 무한의 목록을 생성하기 같은 까다로운 기능을 제공할 수 있다.

function* createFibonacciGenerator() {
    let a = 0;
    let b = 1;
    while(true) {
        yield a;
        [a, b] = [b, a + b];
    }
}
let fibonacciGenerator = createFibonacciGenerator();
console.log(fibonacciGenerator.next());  // { value: 0, done: false }로 평가
console.log(fibonacciGenerator.next());  // { value: 1, done: false }로 평가
console.log(fibonacciGenerator.next());  // { value: 1, done: false }로 평가
console.log(fibonacciGenerator.next());  // { value: 2, done: false }로 평가
console.log(fibonacciGenerator.next());  // { value: 3, done: false }로 평가
console.log(fibonacciGenerator.next());  // { value: 5, done: false }로 평가
console.log(fibonacciGenerator.next());  // { value: 8, done: false }로 평가
cs

01. 함수명 앞에 붙연 별표(*)는 제너레이터임을 의미한다. 제너레이터를 호출하면 이터러블 반복자가 반환된다.

02. yield키워드로 값을 리턴한다. 제너레이터에 다음 값을 요청하면(예: next호출), yield를 이용해 결과를  리턴하고 다음 값을 요청하기 전까지는 실행을 중지한다.

03. [a, b] = [b, a + b]; 피보나치 숫자를 계산하기 위해 a에 b를, b에 a + b를 한번에 다시 할당한다.


13. 반복자

이터러블(iterable) : Symbol.iterator라는 프로퍼티(반복자를 반환하는 함수)를 가진 모든 객체
반복자(iterator) : next라는 메서드(value, done 두 프로퍼티를 가진 객체를 반환)를 정의한 객체

가령 위에서 정의한 createFibonacciGenerator 함수를 호출하면 Symbol.iterator 프로퍼티와 next 메서드를 모두 정의한 값을 얻게 된다.
즉, 이터러블과 반복자 두 가지가 결합된 제너레이터가 반환된다.

Symbol.iterator와 next를 구현하는 객체(또는 클래스)를 만들어 반복자나 이터러블을 직접 정의 할 수 있다.

 // 1에서 10까지의 숫자를 반복하는 반복자를 정의하는 예

 let numbers = {
     *[Symbol.iterator]() {
         for (let n = 1; n <= 10; n ++) {
             yield n;
         }
     }
 }
cs

numbers는 이터러블이며, 제너레이터 함수 numbers[Symbol.iterator]()를 호출하면 이터러블 반복자가 반환된다.

numbers는 다음과 같이 사용할 수 있다.

 // for - of로 반복자 처리
 for (let a of numbers) {
     console.log(a);  // 1, 2, 3 .. 출력
 }
 
 // 반복자 스프레드
 let allNumbers = [...numbers];
 
 // 반복자 구조 분해 할당(destructure)
 let [one, two, ...rest] = numbers;
cs


출처1

출처2