본문 바로가기

JavaScript

[Deep dive] 12장 함수(1)

12.1 함수란?

 

함수

- 일련의 과정을 문(statement)로 구현하고 코드 블록을 감싸서 하나의 실행 단위로 정의

- 함수정의(function definition)을 통해 생성

- 함수 호출(function call)

  - 인수를 매개변수를 통해 함수에 전달하면서 함수의 실행을 명시적으로 지시 

 

매개변수(parameter)

- 함수 내부로 입력을 전달받는 함수 

 

인수(argument)

- 함수의 입력

 

반환값(return value)

-함수의 반환

//f(x,y) = x+y
function add(x,y) {
    return x+y;
}

//f(2,5) = 7
add(2,5); //7

 

12.2 함수 리터럴

 

- 자바스크립트의 함수는 객체타입의 값

- 함수도 함수 리터럴로 생성 가능

- 일반 객체와 달리 함수는 호출 가능

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

- 함수 이름은 함수 몸체 내에서만 참조할 수 있는 식별자 

 

12.3 함수 정의 

 

- 함수를 호출하기 이전에 인수를 전달받을 매갭ㄴ수와 실행할 문들, 반환할 값들을 지정하는 것

- 정의된 함수는 자바스크립트 엔진에 의해 평가되어 함수 객체가 됨

 

12.3.1 함수 선언문

 

- 함수 선언문을 통한 함수 정의 

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

- 함수 이름 생략 불가 

- 표현식이 아닌 문 (값으로 평가될 수 없는 문)이므로 변수에 할당 불가(처럼 보임)

//함수 선언문은 표현식이 아닌문이므로 변수에 할당 불가 
//하지만 함수 선언문이 변수에 할당되는 것 처럼 보임
var add = function add(x,y) {
    return x+y;
};

//함수 호출
console.log(add(2,5)); //7

 

- but 자바스크립트 엔진은 함수 선언문을 해석해 함수 객체를 생성

- 함수 이름은 함수 몸체 내부에서만 유효한 식별자 이므로 함수이름과는 별도로 생성된 함수 객체를 가리키는 식별자가 필요

-자바스크립트 엔진은 생성된 함수를 호출하기 위해 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고, 거기에 함수 객체를 할당

 

- 함수는 함수 이름으로 호출하는 것이 아니라, 함수 객체를 가리키는 식별자로 호출

- 함수 선언문으로 생성한 함수를 호출하는 것은 함수 이름 add가 아님

- 자바스크립트 엔진이 암묵적으로 생성자 식별자 add로 함수 호출된것

 

 

12.3.2 함수 표현식

 

일급 객체

- 함수를 값처럼 자유롭게 사용가능

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

//함수 표현식
var add = function (x,y) {
   return x+y;
};

console.log(add(2,5)); //7

- 함수 리터럴의 함수 이름은 생략 가능(익명함수)

 

//기명 함수 표현식
var add = function foo(x,y) {
    return x+y;
};

//함수 객체를 가리키는 식별자로 호출
console.log(add(2,5)); //7

//함수 이름으로 호출하면 ReferenceError 발생
//함수 이름은 함수 몸체 내부에서만 유효한 식별자 
console.log(foo(2,5)); //ReferenceError

 

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

 

1) 함수 선언문의 생성시점

//함수 참조 
console.dir(add); //f add(x,y)

//함수 호출
console.log(add(2,5)); //7

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

- 함수 선언문으로 정의한 함수는 함수 선언문 이전에 호출 가능

- 함수 선언문은 런타임 이전에 자바스크립트 엔진에 의해 먼저 실행 

 ( 런타임 이전에 함수 객체가 먼저 생성됨)

 

- 함수 호이스팅 (function hoisting)

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

  - 함수 선언문을 통해 암묵적으로 생성된 식별자는 함수 객체로 초기화 

  - 함수 선언문으로 정의한 함수를 함수 선언문 이전에 호출하면 함수 호이스팅에 의해 호출 가능

 

2) 함수 표현식의 생성 시점

//함수 참조 
console.dir(sub); //undefined

//함수 호출
console.log(sub(2,5)); //TypeError

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

- 함수 표현식으로 함수를 정의하면 함수 호이스팅이 발생하는 것이 아니라 변수 호이스팅이 발생

 

- 변수 호이스팅

  - var 키워드로 선언된 변수는 undefined로 초기화 

  - 변수 할당문의 값은 런타임에 평가되므로 함수 표현식의 함수 리터럴도 할당문이 실행되는 시점에 평가되어 함수 객체가됨

  - 함수 표현식 이전에 함수를 참조하면 undefined로 평가 -> undefined를 호출하면 타입에러 발생

 

- 함수 표현식으로 정의한 함수는 반드시 함수 표현식 이후에 참조 또는 호출 해야함

 

 

12.3.4 Function 생성자 함수 

var add = new Function ('x','y', 'return x+y');

console.log(add(2,5)); //7

 

12.3.5 화살표 함수 

 

- ES6에서 도입 

- function 키워드 대신 화살표 =>를 사용해 간략하게 함수 선언 가능

- 화살표 함수는 항상 익명함수로 정의 

//화살표 함수 
const add = (x,y) => x+y;
console.log(add(2,5)); //7

 

 

12.4 함수 호출

 

12.4.1 매개변수와 인수 

 

- 함수를 실행하기 위해 필요한 값을 함수 외부에서 함수 내부로 전달할 필요가 있는 경우,

매개변수를 통해 인수로 전달

 

- 매개변수는 함수 몸체 내부에서만 참조 가능하고 함수 몸체 외부에서는 참조 불가

 (매개변수의 스코프는 함수 내부)

 

- 함수는 매개변수의 개수와 인수의 개수가 일치하는지 체크하지 않음

 

- 인수가 부족해서 인수가 할당되지 않은 매개변수의 값은 undefined

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

console.log(add(2)); //NaN

- 매개변수보다 인수가 더 많은 경우 초과된 인수는 무시됨

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

console.log(add(2,5,10)); //7

- 모든 인수는 암묵적으로 argument 객체의 프로퍼티로 보관

 

 

12.4.2 인수 확인

 

- 자바스크립트 함수는 매개변수와 인수의 개수가 일치하는지 확인하지 않음

- 자바스크립트는 동적 타입 언어다. 따라서 자바스크립트 함수는 매개변수의 타입을 사전에 정의 할 수 없다.

 -> 함수를 정의할 때 적절한 인수가 전달되었는지 확인할 필요가 있음

 

- ES6에서 도입된 매개변수 기본값을 사용하면 함수 내에서 수행하던 인수 체크 및 초기화 간소화 가능

function add(a=0, b=0, c=0) {
  return a+b+c;
}

console.log(add(1,2,3)); //6
console.log(add(1,2)); //3
console.log(add(1)); //0
console.log(add()); //0

 

12.4.3 매개변수의 최대 개수 

 

- ECMAScrpit 사양에서는 매개변수의 최대 개수에 대해 명시적으로 제한하고 있지 않음

- 이상적인 매개변수 개수는 0개이며 적을수록 좋음

- 이상적인 함수는 한가지 일만 해야 하며 가급적 작게 만들어야 함

 

12.4.4 반환문

 

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

- 함수 호출 표현식은 return 키워드가 반환한 표현식의 평가 결과 즉 반환값으로 평가됨

 

- 반환문의 역할 

 1) 반환문은 함수의 실행을 중단하고 함수 몸체를 빠져나옴

 2) 반환문은 return 키워드 뒤에 오는 표현식을 평가해 반환

 

- 반환문은 생략 가능 (undefined 반환)

 

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