Javascript - 3. Function(3)

Jin Young Son·2021년 4월 15일
0

Javascript

목록 보기
5/5
post-thumbnail

함수를 선언하고 호출할 때, 일반적인 방법 외에도 자바스크립트에서 다양하게 선언하고 호출할 수 있습니다.

함수 유형

함수 선언식

여태까지 봐왔던 일반적인 함수 선언식입니다. function 구문을 이용하여 선언 방식입니다.

function foo() {
  // ...
}

익명 함수

이름이 없는 함수로 함수에 이름을 명시적으로 표기하지 않는 선언 방식입니다.

var foo = function () {
  // ...
}

함수 선언식과 비교해보면 함수에 name 속성의 차이로 볼 수 있습니다. 이름을 지정해주지 않는 경우 name 속성에 빈 문자열이 들어가게 됩니다.

function a() {}
var b = function () {};
var c = function func() {};

a.name; // 'a'
b.name; // ''
c.name; // 'func' 

대게 변수에 할당하는 함수에 선언하거나, 객체 내에 있는 메서드에 함수를 선언할 때 함수의 이름이 필요 없기 때문에 익명 함수를 사용합니다.

즉시 실행 함수

익명함수를 통해 생성과 동시에 실행시킬 수 있는 함수로, 초기화 정보나 전역공간에 영향없이 사용하기 위해 많이 사용합니다.

(
  // 생성
  function () {
  	// ...
  }
)(); // 실행

클로저

함수가 실행했을 때의 환경을 기억하고 있는 것을 클로저라고 합니다. 함수에서 지역변수는 함수가 종료될 때 같이 사라지게 됩니다. 다음 함수를 반환하게 되는 경우를 확인해보겠습니다.

function sum() {
  var a = 10;
  return function (b) {
  	return a + b;
  };
}

let res = sum();
res(20); // 30;
res(100); // 110

sum() 함수를 호출된 후에는 a 지역변수가 사라지지 않고 값을 지니고 있다가 반환한 함수의 내부에서 사용되는 것을 볼 수 있습니다. 이러한 형태를 클로저라 합니다.

내부에서는 접근 가능하지만, 외부에서는 접근할 수 없는 private 변수처럼 사용할 수 있습니다.

function Person(name) {
  this.getName = function () {
    return name;
  };
}

var person = new Person('camp-son');
person.getName(); // camp-son
person.name; // undefined

단, 클로저의 경우 환경을 기억하고 있기 때문에 메모리에 존재하게 됩니다. 이는 성능에 영향을 줄 수 있기 때문에 사용이 끝난 클로저는 메모리에서 해제하는 작업을 해줘야 합니다.

콜백함수

Javascript - 3.Function(1)#함수에서 1급 함수에 대한 설명을 했었습니다. 특징 중 하나인 함수를 함수의 인자로 전달할 수 있습니다. 이 말은 함수를 인자로 받는 함수에서 전달 받은 함수의 실행을 제어할 수 있고 이러한 특성을 활용하여 주로 비동기 처리를 할 때 많이 사용합니다. 대표적으로 자바스크립트의 내장함수인 setTimeout 함수를 볼 수 있습니다.

var count = 0;
function hello() {
  console.log('Hello world', count);
  count++;
}

setTimeout(hello, 1000); // Hello world 1

hello(); // Hello world 0

setTimeout의 인자로 받은 hello 함수를 콜백함수 라고 합니다. 이렇게 콜백함수는 비동기 처리, 이벤트 핸들러 등 함수의 실행 시점을 특정할 수 없어 함수의 실행을 함수에게 위임하는 형태로 사용됩니다.

콜백 지옥

단순한 콜백함수의 사용은 단순하여 가독성도 좋지만, 콜백함수를 중첩으로 사용하게 되면 가독성이 많이 떨어지고 테스트가 쉽지 않습니다.

asyncFunc1(function () {
  asyncFunc2(function () {
    asyncFunc3(function () {
      asyncFunc4(function () {
        // Processing data
      });
    });
  });
});

위와 같이 콜백함수를 중첩으로 많이 사용하게 되면 asyncFunc4가 실행되기까지의 많은 대기가 필요합니다. 이를 해결하기 위한 방법은 Promise, Generator, async/await 정도가 있는데 이에 대한 부분은 별도로 정리하도록 하겠습니다.

함수 호출

함수를 호출할 때엔 기본적으로 func() 형태로 호출합니다. 자바스크립트의 함수에서는 그 외에 다양한 방법으로 함수를 호출할 수 있는 메서드를 제공하는데 함수의 this와 밀접한 관계가 있습니다.

call/apply 메서드

두가지 메서드는 동일하게 동작하지만, 인자로 받는 값에 차이가 있습니다. call은 두번째 인자부터 순차적으로 인자를 전달해주고, apply는 두번째 인자에 배열형태로 인자를 전달합니다.

function empty(x) {}

empty(10);
empty.call(this, 10);
empty.apply(this, [10]);

위 3가지 방식의 호출은 모두 동일한 결과가 나옵니다.
다른 점은 첫번째 인자로 this가 전달되는 방식인데, 이 this는 다른 OOP 언어와 다르게 인스턴스 자신을 가르키지 않습니다. 함수 내부에서 사용하는 this에 대해 전달하는 것입니다. this에 대한 자세한 내용은 추후 따로 정리할 예정입니다.

function Person(age) {
  this.age = age;
  this.addAge = function (n) {
  	this.age += n;
  };
}

ver person = new Person(10);
person.addAge(2);
person.age; // 12

var darknight = {age: 40};
person.addAge.call(darknight, 10);
person.age; // 12
darknight.age; // 50

person.addAge.apply(darknight, [5]);
person.age; // 12
darknight.age; // 55

bind 메서드

bind는 단순히 함수에 this 객체만 지정해주는 함수입니다. bind 후 호출시 함수에서 연결된 객체를 this로 인지합니다.

정리

함수를 선언하고 사용하는 방식이 다양하지만, 이러한 유연성이 활용을 잘한다면 좋은 퍼포먼스를 낼 수 있을 것으로 생각됩니다. 많은 여러 유형과 그 사용법을 이해하고 활용할 수 있도록 많이 사용해봐야할 것 같습니다.

  • 유형
    1. 함수 선언식 function func() {}
    2. 익명 함수 var func = function () {}
    3. 즉시 실행 함수 (function () {})()
    4. 클로저 함수가 실행 됐을 때의 환경을 기억하는 것
    5. 콜백 함수 함수의 인자로 함수를 전달하는 것
  • 호출
    1. call func.call(thisArg, ...args)
    2. apply func.apply(thisArg, [...args])
    3. bind func.bind(thisArg)

마치며..

함수에 대해 공부하다보니 내용이 너무 많아져 챕터를 나누어 정리했습니다. 자바스크립트에서 많은 기능을 제공하지만, 그 기본이 되는 함수에 대해 자세히 알 필요성이 있다고 느끼는 시간이였습니다. 함수에 대해 정리하고 나니 뭔가 멍~해지는 기분이 듭니다.. 무의식에 사용했던 것들인데, 정확한 내용도 잘 모르고 그냥 사용했던 것에 대해 약간의(?) 후회가 듭니다. 이제 함수를 사용할 때 여러 고민을 해보고 사용할 것 같습니다. 그럼 함수에 대해서는 이만 마치도록 하겠습니다.

참고자료: https://medium.com/ibare-story/e252506f8525

profile
Front-end Developer

0개의 댓글