함수 선언문은 function
키워드를 사용해서 함수를 정의한다
function foo() {
return "Hello World!";
}
console.log(foo()); // Hello World!
함수 표현식은 함수를 생성하고, 변수에 그 함수를 할당하여 정의하는 방법이다.
let foo2 = function () {
return "Fooooo";
}
console.log(foo2()); // Fooooo
자바스크립트에서 함수는 값 이다. 따라서 함수를 값처럼 취급할 수 있다. 따라서 변수를 복사해 다른 변수에 할당하는 것처럼 함수를 복사해 다른 변수에 할당할 수 있다.
// 함수 선언문
function sum(a, b) {
return a + b;
}
// 함수 표현식
let sum = function(a, b) {
return a + b;
}
함수 선언문 : 함수는 코드 흐름 중간에 독자적인 구문 형태로 존재한다.
함수 표현식 : 표현식이나 구문 구성 내부에 생성된다. 함수의 정의는 할당 연산자 =
우측에 생성된다.
함수 선언문 : 함수 선언문은 정의되기 전에 호출이 가능하다. 함수 선언문 또한 호이스팅이 일어나는데, 호이스팅은 변수와 함수의 선언 을 메모리에 할당한다. 따라서 아래와 같은 코드의 작성이 가능하다.
foo(); // Hello World!
function foo() {
console.log("Hello World!");
}
함수 표현식 : 함수 표현식은 실제 실행 흐름이 해당 함수에 도달했을 때 함수가 생성이 된다. 따라서 실행 흐름이 함수에 도달했을 때부터 해당 함수를 사용할 수 있다. 여기서 함수를 변수에 할당한다는게 중요한 키워드인 것 같다.
세 가지 예시를 들어보자면,
var foo = function() {
console.log("Hello World!");
};
foo() // Hello World!
위의 코드는 정상 작동한다.
foo(); // TypeError: foo is not a function
console.log(foo); // undefined
var foo() = function() {
console.log("Hello World!");
};
console.log(foo); //[Function: foo]
위의 코드는 실행 시 TypeError가 발생한다. foo()
를 잠시 주석 처리하고 함수 표현식의 위 아래로 log를 확인하면 차례대로 undefined, [Function: foo]가 출력되는 것을 확인할 수 있다.
그렇다면 let이나 const에 할당한 함수 표현식은 어떨까?
foo(); // ReferenceError: Cannot access 'foo' before initialization
const foo = function () {
console.log("Hello World!");
};
위의 코드는 var 함수 표현식과 다른 에러를 반환한다. 여기서 확인할 수 있는 건, 함수 표현식의 경우 변수의 호이스팅이 일어난다는 점이다.
함수 선언문은 "use strict"
사용 여부에 따라 다르게 작동한다.
"use strict";
{
function foo() {
console.log("Hello World!");
}
}
foo(); // ReferenceError: foo is not defined
"use strict"
를 사용하면 함수 선언문의 유효 범위는 코드 블록 내부가 된다.
{
function foo() {
console.log("Hello World!");
}
}
foo(); // Hello World!
반면 "use strict"
를 사용하지 않으면 코드 블록 내에서 선언한 함수를 코드 블록 밖에서 사용할 수 있다. 이 부분은 왜 이렇게 사용이 가능한지 좀 더 찾아봐야겠다.
아래 함수 표현식들은 "변수"로 생각하면 그 스코프를 생각하기 쉬워진다.
let foo = function () {
console.log("Hello");
};
foo(); // Hello
{
let foo = function () {
console.log("Hello");
};
}
foo(); //ReferenceError: foo is not defined
위의 let
혹은 const
에 할당한 foo
함수표현식은 코드 블록 {...}
내에서 선언이 되었으므로, 코드 블록 밖에서는 사용할 수 없다
{
var foo = function () {
console.log("Hello");
};
}
foo(); // Hello
반면 var에 할당한 경우, 코드 블록 밖에서도 호출이 가능하다.
https://velog.io/@bisu8018/%ED%95%A8%EC%88%98-%ED%91%9C%ED%98%84%EC%8B%9D-VS-%ED%95%A8%EC%88%98-%EC%84%A0%EC%96%B8%EC%8B%9D
https://ko.javascript.info/function-expressions#ref-255