[모던 자바스크립트] 12. 함수

이상돈·2023년 7월 19일
0
post-thumbnail

12.1 함수란?

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

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

add(2,5) // 7

12.2 함수를 사용하는 이유

함수를 사용함으로써 유지보수의 편의성을 높이고, 코드의 신뢰성을 높힌다. 뿐만아니라 코드의 재사용이라는 측면에서 매우 유용하고, 코드의 가독성을 향상시킨다.

12.3 함수 리터럴

// 변수에 함수 리터럴을 할당
var f = function add(x,y){
  return x + y;
}

위 예시처럼 함수도 변수에 할당할 수 있다. 즉, 함수는 객체다.
함수는 객체지만 일반 객체와는 다르다. 일반 객체는 호출할 수 없지만 함수는 호출할 수 있다.

12.4 함수 정의

// 함수 선언문
function add(x,y){
  return x+y;
}
// 함수 표현식
var f = function add(x,y){
  return x+y;
}
// Function 생성자 함수
var add = new Function('x','y', 'return x+y');
// 화살표 함수(ES6)
var add = (x, y) => x+y;

함수 선언문

함수 리터럴은 함수 이름을 생략할 수 있으나, 함수 선언문은 함수이름을 생략할 수 없다.

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

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

함수 선언문은 표현식이 아닌 문이다.

// 함수 선언문은 표현식이 아닌 문이므로 변수에 할당할 수 없다
// 하지만 함수 선언문이 변수에 할당되는 것처럼 보인다.
// 이유는 자바스크립트 엔진이 여기서 피연선자는 함수 선언문이 아니라 함수 리터럴 표현식이라고 해석했기 때문이다.
var add = function add(x,y){
  return x+y;
}
console.log(add(2,5))
function foo(){ console.log('foo'); }
foo(); // foo

(function bar(){ console.log('bar'); })
bar(); /// ReferenceError : bar is not defined

"함수 이름은 함수 몸체 내에서만 참조할 수 있는 식별자다". 즉, 함수 몸체 외부에서는 함수 이름으로 함수를 참조할 수 없으므로 함수 몸체 외부에서는 함수 이름으로 함수를 호출할 수 없다는 의미이다. 따라서 bar는 호출이 불가능하다.

하지만 함수 선언문으로 선언된 foo는 외부에서 호출이 가능하다. 식별자가 없는데 어떻게 가능한가? 정답은 foo는 자바스크립트 엔진이 암묵적으로 생성한 식별자이다.

자바스크립트 엔진은 생성된 함수를 호출하기 위해 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고, 거기에 함수 객체를 할당한다.
즉, 함수는 함수 이름으로 호출하는 것이 아니라 함수 객체를 가리키는 식별자로 호출한다.

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


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

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

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

var sub = function(x,y){
  return x-y;
}

함수 선언문으로 정의한 함수와 함수 표현식으로 정의한 함수의 생성 시점이 다르다는 것을 알 수 있다.
모든 선언문과 같이 함수 선언문도 코드가 한 줄씩 순차적으로 실행되는 시점인 런타임 이전에 자바스크립트 엔진에 의해 먼저 실행된다.
add() 같은 경우 함수 선언문으로 생성되어 런타임 이전에 자바스크립트 엔진에 의해 생성된다. 하지만 sub 변수에 할당되는 함수 표현식은 런타임 이전엔 sub 변수만 생성되고 초기값 undefined가 할당된다. 따라서 함수 호이스팅이 발생하는 것이 아니라 변수 호이스팅이 발생하는 것 이다.

12.5 함수 호출

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

var result = add(2,5);

function add(x,y){
  console.log(arguments);
  //Arguments(3) [2,5,10, callee: f, Symbol(Symbol.iterator): f]
  return x+y;
}
add(2,5,10)

arguments 객체는 함수를 정의할 때 매개변수 개수를 확정할 수 없는 가변 인자 함수를 구현할 때 유용하게 사용된다.

profile
사람들의 더 나은 삶을 위한 개발자

1개의 댓글

comment-user-thumbnail
2023년 7월 19일

가치 있는 정보 공유해주셔서 감사합니다.

답글 달기