JS (12) - 함수

최조니·2022년 6월 25일
0

JavaScript

목록 보기
9/36

12.1 함수란 ?

함수 : 일련의 과정을 문으로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것

  • 매개 변수 : 함수 내부로 입력을 전달하는 변수
  • 인수 : 입력
  • 반환 값 : 출력

함수 정의 : 함수 정의를 통해 함수 생성
      ↓
함수 호출 : 인수를 매개변수를 통해 함수에 전달하면서 실행을 명시적으로 지시
      ↓
함수 실행 : 문들이 일괄적으로 실행되고, 반환값 반환

// 함수 정의
function add(x, y) {	// add : 함수 이름, x·y : 매개변수
  return x + y;			// 반환 값
}

// 함수 호출
add(2, 5);				// 2·5 : 인수

12.2 함수를 사용하는 이유

  • 함수는 필요할 때 여러 번 호출할 수 있으므로, 코드의 재사용 측면에서 매우 유용

  • 코드의 중복을 억제하고 재사용성을 높여 유지보수의 편의성코드의 신뢰성을 높임


12.3 함수 리터럴

함수 리터럴은 function 키워드, 함수 이름, 매개변수 목록, 함수 몸체로 구성

// 변수에 함수 리터럴 할당
var f = function add(x, y) {
  return x + y;
}
  • 일반 객체는 호출할 수 없지만, 함수는 호출할 수 있다

  • 함수 객체만의 고유한 프로퍼티를 가짐


12.4 함수 정의

함수를 호출하기 전, 인수를 전달받을 매개변수와 실행할 문들, 그리고 반환할 값을 지정하는 것

  • 함수 정의 방법 4가지
    • 함수 선언문
    • 함수 표현식
    • Function 생성자 함수
    • 화살표 함수 (ES6)

1) 함수 선언문

function add(x, y) {
  return x + y;
} 
  • 함수 선언문은 함수 이름을 생략할 수 없다. (리터럴은 생략 가능)

  • 표현식이 아닌 문이므로, 완료 값 undefined 출력


2) 함수 표현식

var add = function(x, y) {
  return x + y;
}
  • 자바스크립트의 함수는 일급 객체 (변수에 할당할 수도 있고 프로퍼티 값이 될 수 있는 값, 즉 값의 성질을 갖는 객체)

  • 리터럴로 생성한 함수 객체를 변수에 할당 가능

  • 함수 표현식의 함수 리터럴은 함수 이름을 생략하는 것(익명 함수)이 일반적

var add = function foo(x, y) {
  return x + y;
}

console.log(add(2, 5));		// 7
console.log(foo(2, 5));		// ReferenceError : foo is not defined

3) Function 생성자 함수

var add = new Function('x', 'y', 'return x+y');
  • new 연산자 없이 호출해도 결과는 동일

  • 일반적이지도, 바람직하지도 않음

  • Function 생성자 함수로 생성한 함수는

    • 클로저(closure) 생성 X
    • 함수 선언문이나 함수 표현식으로 생성한 함수와 다르게 동작

4) 화살표 함수

var add = (x, y) => x + y;
  • 항상 익명 함수

  • 기존 함수보다 표현, 내부 동작 간략화

  • 생성자 함수로 사용할 수 없음

    • 기존 함수와 this 바인딩 방식이 다름
    • prototype 프로퍼티가 없음
    • arguments 객체 생성 X

- 함수 생성 시점과 함수 호이스팅

console.log(add);			// f add(x, y)
console.log(sub);			// undefined

console.log(add(2, 5));		// 7
console.log(sub(2, 5));		// TypeError : sub is not a function

function add (x, y) {		// 함수 선언문
  return x + y;
}

function sub (x, y) {		// 함수 표현식
  return x - y;
}

함수 호이스팅 : 함수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징

  • 함수 선언문으로 정의한 함수는 함수 선언문 이전 호출 가능
    함수 표현식으로 정의한 함수는 함수 표현식 이전에 호출 불가능
    → 함수의 생성 시점이 다르기 때문 !!

  • 함수 선언문으로 함수를 정의하면 런타임 이전에 함수 객체가 먼저 생성된다.

  • 함수 표현식은 함수 리터럴인 문, 함수 정의 시 함수 호이스팅이 아닌 변수 호이스팅이 발생

  • 변수 호이스팅 vs 함수 호이스팅
    런타임 이전에 자바스크립트 엔진에 의해 먼저 실행되어 식별자를 생성

    변수 호이스팅함수 호이스팅
    undefined로 초기화함수 객체로 초기화

12.5 함수 호출

1) 매개변수와 인수

  • 매개 변수 : 함수 내부로 입력을 전달하는 변수
  • 인수 : 입력
  • 매개 변수

    • 함수를 정의할 때 선언됨
    • 함수 몸체 내부에서 변수와 동일하게 취급
    • 매개 변수의 스코프는 함수 내부
    • 매개 변수의 최대 개수는 명시적으로 제한을 하고 있진 않지만, 이상적인 함수는 한 가지 일만 해야 하며 가급적 작게 만들어야 함
  • 인수

    • 평가될 수 있는 표현식으로 개수와 타입에 제한 없음

2) 인수 확인

  • 자바스크립트 함수는 매개변수와 인수의 개수가 일치하는지 확인하지 않는다.
  • 자바스크립트는 동적 타입 언어이므로, 매개변수의 타입을 사전에 지정할 수 없다.
function add(x, y) {
  return x + y;
}

console.log(add(2));		// NaN
console.log(add('a', 'b'));	// 'ab'

3) 반환문

return 키워드와 표현식(반환값)으로 이뤄진 반환문을 사용해 실행 결과를 함수 외부로 반환

  • 반환문은 함수 몸체 내부에서만 사용 가능

  • 반환문의 역할

    • 함수의 실행을 중단하고 함수 몸체를 빠져나옴
    • return 키워드 뒤에 오는 표현식을 평가해 반환 (명시적으로 지정하지 않으면 undefined 반환)
function foo() {
  return;
}

console.log(foo());		// undefined

12.6 참조에 의한 전달과 외부 상태의 변경

function changeVal(primitive, obj) {
  primitive += 100;
  obj.name = 'Kim';
}

var num = 100;
var person = { name: 'Lee' };

console.log(num);				// 100
console.log(person);			// {name: "Lee"}

changeVal(num, person);			

console.log(num);				// 100
console.log(person);			// {name: "Kim"}

primitive : 원시 타입 인수 / obj : 객체 타입 인수

  • 원시 타입 인수는 값 자체가 복사되어 매개변수에 전달되기 때문에 함수 몸체에서 그 값을 변경해도, 원본은 훼손되지 않음

  • person 같이 함수가 외부 상태를 변경하면, 상태 변화 추적이 어려워짐 (코드의 복잡성 증가, 가독성 ↓)

    • 객체 변경을 추적하려면 옵저버 패턴 등을 통해 객체를 참조를 공유하는 모든 이들에게 변경 사실을 통지하고, 대처하는 추가 대응이 필요
    • 해결 방법 : 객체를 불변 객체로 만들어 사용
      • 객체의 본사본을 새롭게 생성, 원시 값처럼 변경 불가능한 값으로 동작
      • 객체의 상태 변경을 막고, 상태 변경이 필요한 경우에는 객체 깊은 복사

12.7 다양한 함수의 형태

1) 즉시 실행 함수

즉시 실행 함수 : 함수 정의와 동시에 즉시 호출되는 함수

(function () {
  var a = 3;
  var b = 5;
  return a * b;
}());
  • 익명함수를 사용하는 것이 일반적

  • 그룹 연산자 (...)로 감싸야 함

  • 값을 반환할 수도, 인수를 전달할 수도 있음

var res = (function() {
  var a = 3;
  var b = 5;
  return a * b;
}());

console.log(res);			// 15

res = (function (a, b) {
  return a * b;
}(3, 5));

console.log(res);			// 15

2) 재귀 함수

재귀 함수 : 자기 자신을 호출하는 행위(재귀 호출)를 수행하는 함수

function factorial(n) {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
}
  • 탈출 조건을 반드시 만들어야 함

3) 중첩 함수

중첩 함수 (내부 함수) : 함수 내부에 정의된 함수
외부 함수 : 중첩 함수를 포함하는 함수

function outer() {
  var x = 1;
  
  function inner() {
    var y = 2;
    console.log(x + y);
  }
  
  inner();
}

4) 콜백 함수

콜백 함수 : 함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수
고차 함수 : 매개변수를 통해 함수의 외부에서 콜백 함수를 전달받은 함수

function repeat(n, f) {
  for (var i=0; i<n; i++) {
    f(i);
  }
}

var logAll = function(i) {
  console.log(i);
};

repeat(5, logAll);		// 0 1 2 3 4
  • 콜백 함수는 고차 함수에 의해 호출되며, 고차 함수는 필요에 따라 콜백 함수에 인수를 전달할 수 있음

  • 콜백 함수는 함수형 프로그래밍 패러다임 뿐만 아니라 비동기 처리에 활용되는 중요한 패턴

document.getElementById('mybutton').addEventListener('click', function() {
  console.log('button clicked!');
});

setTimeout(function () {
  console.log('1초 경과');
}, 1000);

5) 순수 함수와 비순수 함수

순수 함수 : 어떤 외부 상태에 의존하지도 않고 변경하지도 않는, 부수효과가 없는 함수
비순수 함수 : 외부 상태에 의존하거나 외부 상태를 변경하는, 부수 효과가 있는 함수

// 순수 함수
var count = 0;

function increase(n) {
  return ++n;
}

// 재할당해서 상태 변경
count = increase(count); 
console.log(count);			// 1

count = increase(count); 
console.log(count);			// 2
// 비순수 함수
var count = 0;

function increase() {
  return ++count;
}

increase(); 
console.log(count);			// 1

increase(); 
console.log(count);			// 2
profile
Hello zoni-World ! (◍ᐡ₃ᐡ◍)

0개의 댓글