JavaScript

8.10 콜백함수

jhlee_ 2020. 7. 16. 23:12

자바스크립트의 함수는 일급(fisrt-class)객체이다.

그렇다면 일급객체란 무엇인가?

1. 변수나 데이터 구조 안에 담을 수 있다.
2. 파라미터로 전달 할 수 있다.
3. 리턴 값으로 사용할 수 있다.
4. 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다.
5. 동적으로 프로퍼티 할당이 가능하다.

위와 같은 5가지 조건을 만족하는 객체를 일급객체라고 한다.

 

함수를 값으로 다룰 수 있다 = 변수에 함수에 값을 담을 수 있다

var a = function() { ... };

함수를 객체의 키 값으로 할당 할 수 있음.

var movie = {
    name: '옥자',
    director: '봉준호',
    show: function() {
        console.log(this.name + ' ' + this.director);
    }
}
var add = function(a,b) {
    return a + b;
}

var newAdd = add;
newAdd(2,3) // 5
$('form').on('submit',function() {
    //show specific text
});
$('a').on('click', function() {
    //show specific text
});

/* 줄여쓰기 */
function showText(e) {
    //show specific text
}
$('form').on('submit',showText);
$('a').on('click',showText);
var foo = function() {
    // 함수를 리턴
    return function() {
        console.log('이 함수는 함수를 반환한다.');
    };
};

익명함수를 리턴 - 함수 자체가 값으로 취급되기 때문

Callback

나중에 실행하는 함수

콜백 함수는 함수 안에서 어떤 특정한 시점에 호출되는 함수



call back

콜백 함수의 동작 방식은 일종의 식당 자리 예약과 같다.

식당에 자리가 없을 경우, 대기자 명단에 이름을 쓴 다음에 자리가 날 때까지 주변 식당을 돌아다닌다.

만약 식당에서 자리가 생기면 전화로 자리가 났다고 연락이 온다. 그 전화를 받는 시점은 콜백 함수가 호출되는 시점과 같다고 볼 수 있다. 손님 입장에서는 자리가 날 때까지 식당에서 기다리지 않고 근처 가게에서 잠깐 쇼핑을 할 수도 있고 아니면 다른 식당 자리를 알아볼 수도 있다.

자리가 났을 때만 연락이 오기 때문에 미리 가서 기다릴 필요도 없고, 직접 식당 안에 들어가서 자리가 비어 있는지 확인할 필요도 없다. 자리가 준비된 시점, 즉 데이터가 준비된 시점에서만 사용자가 원하는 동작(자리에 앉는다, 특정 값을 출력한다 등)을 수행할 수 있다.

호출해서 넘겨주는 함수

A : 함수를 호출해서 그 결과를 나한테 알려줘

B : OK 내가 알아서 처리하고 알려줄게

A가 B에게 제어권을 넘겨준다.

callback 함수

function plus(a, b, callback) {
  var sum = a + b;
  callback(sum);
}

function print(result) {
  console.log(result);
}                         

plus(1, 2, print);
document.body.innerHTML = '<div id="a">abc</div>';
function callbackFunc(x) {
    console.log(this, x)
};

document.getElementById('a').addEventListener('click', callbackFunc);

syntax

setInterval(function, milliseconds, param1, param2, ...)

setInterval(function(){ alert("Hello"); }, 3000);

// 매 3초마다 (3000 milliseconds) 
// function(){ alert("Hello"); }

// 1000 ms = 1 second.

syntax

arr.forEach(callback(currentvalue[, index[, array]])[, thisArg])

const items = ['item1', 'item2', 'item3'];
const copy = [];

// 이전
for (let i=0; i<items.length; i++) {
  copy.push(items[i]);
}

// 이후
items.forEach(function(item){
  copy.push(item);
});

8.11.1 화살표 함수 표현식으로 함수 정의하기

함수 리터럴 (함수 표현식)

var intervalID = setTimeout(function() { myFunc("one", "two", "three"); }, 1000);

Arrow function

var intervalID = setTimeout(() => { myFunc("one", "two", "three"); }, 1000);
var square = function(x) {return x * x}
//화살표 함수 표현식
// 매개변수 지정 방법
    () => { ... } // 매개변수가 없을 경우 / 소괄호 생략 불가
     x => { ... } // 매개변수가 한 개인 경우, 소괄호를 생략가능
(x, y) => { ... } // 매개변수가 여러 개인 경우, 소괄호를 생략불가, 쉼표로 구분

x => { return x * x }  // single line block
x => x * x             // 함수 몸체가 한줄의 구문이라면 중괄호를 생략, return도 생략

() => { return { a: 1 }; }
() => ({ a: 1 })  // 위 표현과 동일하다. 객체 반환시 소괄호를 사용한다.

() => {           // multi line block.
  const x = 10;
  return x * x;
};

함수 표현식과 화살표 함수의 차이점

  1. this

함수 리터럴 → 함수를 호출할 때 그 값이 정해진다

화살표 함수 → 함수를 정의할 때 결정됨

const user1 = {
    name: function() {
        console.log('name = ',this);
    },
    nickname: ()=> {
    console.log('nickname = ', this)
    }
}

화살표 함수는 함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정

동적으로 결정되는 일반 함수와는 달리 화살표 함수의 this 언제나 상위 스코프의 this를 가리킨다.

이를 Lexical this

  1. argument 변수가 없음

  2. 생성자로 사용할 수 없음

const Foo = () => {};

console.log(Foo.hasOwnProperty('prototype')); // false

const foo = new Foo(); // TypeError: Foo is not a constructor
  1. yield 키워드 사용 불가

인수에 추가된 기능

나머지 매개변수(Rest parameter)

rest parameter은 이름을 정해주지 않은 파라미터의 배열

arguments는 함수로 전달되는 모든 파라미터

ES5까지는 arguments 변수를 사용

arguments는?

배열로 변환해야하는 문제!

function f(a, b, ...theArgs) {
  // ...
}
function myFun(a, b, ...manyMoreArgs) {
  console.log("a", a); 
  console.log("b", b);
  console.log("manyMoreArgs", manyMoreArgs); 
}

myFun("월요일", "화요일", "수요일", "목요일", "금요일", "토요일", "일요일");

인수의 기본값

이전까지는?

function multiply(a, b) {
  return a * b;
}

multiply(5, 2); // 10
multiply(5);    // NaN !

function multiply(a, b) {
  b = b || 1
  return a*b;
}

multiply(5, 2); // 10
multiply(5); // 5
function multiply(a, b = 1) {
  return a*b;
}

multiply(5, 2); // 10
multiply(5); // 5
multiply(5, undefined); // 5

//출처 MDN

이터레이터와 for/of문

이터레이터 = 반복처리

이터레이션 = 반복처리가 가능한 객체

for of 루프는 순회를 시작하기 전,

Symbol.iterator 메소드를 호출하여 이터레이터 객체를 얻는다

순차적으로 next() 메소드를 호출하면서 하나씩 순회

var a = [1,4,5];

var iter = a[Symbol.iterator]();
console.log(iter.next())
console.log(iter.next())

반복 가능한 이터러블 객체

Array, String, TypedArray, Map, Set

제너레이터

제네레이터를 한마디로 말하자면, 이터러블, 이터레이터 객체를 만드는 손쉬운 방법

  • 반복가능한 이터레이터를 값으로
  • 작업의 일시정지와 재시작이 가능, 자기 자신의 상태를 관리
function* gen() {
  yield 1 // yield 함수의 실행을 일시적으로 정지, 일반 함수의 return과 매우 유사
  yield 2
  yield 3
}// foo()로 생성된 제너레이터를 순회하며 값을 읽어간다.

var iter = gen(); // 바로 실행되지 않음

console.log(iter.next()); // {value:1, done:false}
console.log(iter.next()); // {value:2, done:false}
console.log(iter.next()); // {value:3, done:true} 

이터레이터를 적은 코드로 가독성까지 높여서 손쉽게 만들 수 있다

동시성/비동기 프로그래밍을 위해 만들어 진 것

제너레이터 함수에서의 return

return은 수행되고 있는 이터레이터를 종료

return 뒤에 오는 값은 IteratorResult 객체의 value 프로퍼티에 할당되며,

done 프로퍼티는 true가 할당

function fakeSetTimeout(callback, delay) {
  callback();
}

// 실행 1
console.log(0);
fakeSetTimeout(function() {
  console.log('hello'); 
}, 0);
console.log(1);

// 실행 2
console.log(0);
setTimeout(function() {
  console.log('hello');
}, 0);
console.log(1);
728x90

'JavaScript' 카테고리의 다른 글

배열과 유사배열  (0) 2021.07.15
비동기 처리 - Promise  (0) 2020.07.19
커스텀 이벤트  (0) 2020.07.17
객체 잠그기  (0) 2020.03.19