함수 리터럴은 function
키워드, 함수 이름, 매개변수 목록, 함수 몸체로 구성된다.
function add(x, y) {
return x + y;
}
함수 이름은 함수 몸체 내부에서만 유효한 식별자이고, 함수 이름으로 호출하면 ReferenceError
(참조 에러)가 발생한다.
const greet = function sayHello(name) {
console.log(name + ", Hello!");
}
greet("Seoltang"); // 'Seoltang, Hello!'
sayHello("Seoltang"); // ReferenceError: sayHello is not defined.
()
내에 있는 함수 리터럴은 함수 선언문으로 해석되지 않고 함수 리터럴 표현식으로 해석된다.undefined
를 출력한다. 이를 완료 값이라 한다. 완료 값은 표현식의 평가 결과가 아니기 때문에 다른 값과 같이 변수에 할당할 수 없고 참조할 수도 없다. 반대로 표현식인 문을 실행하면 언제나 평가된 값을 반환한다.함수 호이스팅과 변수 호이스팅은 선언문이 런타임 이전에 자바스크립트 엔진에 의해 먼저 실행되어 식별자를 생성한다는 점에서 동일하다. 하지만 var
키워드로 선언된 변수는 undefined
로 초기화되고, 함수 선언문을 통해 암묵적으로 생성된 식별자는 함수 객체로 초기화된다. 따라서 var
키워드를 사용한 변수 선언문 이전에 변수를 참조하면 변수 호이스팅에 의해 undefined
로 평가되지만 함수 선언문으로 정의한 함수를 함수 선언문 이전에 호출하면 함수 호이스팅에 의해 호출이 가능하다.
함수 표현식으로 함수를 정의하면 함수 호이스팅이 아니라 변수 호이스팅이 발생하는데, 변수 선언은 런타임 이전에 실행되어 undefined
로 초기화되지만 변수 할당문의 값은 할당문이 실행되는 시점, 즉 런타임에 평가되므로 함수 표현식의 함수 리터럴도 할당문이 실행되는 시점에 평가되어 함수 객체가 된다.
👉🏻 함수 선언문은 함수 호이스팅을 따르고 함수 표현식은 변수 호이스팅을 따른다!
함수 선언문으로 함수를 정의하면 자바스크립트 엔진이 런타임 이전에 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고 생성한 함수 객체를 할당한다.
console.log(add(3, 2)); // 5
function add(a, b) {
return a + b;
}
console.log(add(3, 2)); // 5
var
키워드로 선언한 변수는 자바스크립트 엔진에 의해 undefined
로 초기화되기 때문에 함수를 호출하려고 하면 TypeError
가 발생한다.
console.log(subtract(3, 2)); // TypeError: subtract is not a function
var subtract = function(a, b) {
return a - b;
}
console.log(subtract(3, 2)); // 1
const
키워드로 선언한 변수는 선언문에서 초기화되기 전에 참조할 수 없기 때문에 ReferenceError
가 발생한다.
console.log(subtract(3, 2)); // ReferenceError: subtract is not defined
const subtract = function(a, b) {
return a - b;
}
console.log(subtract(3, 2)); // 1
함수가 호출될 때 인수가 복사되어 매개변수에 전달된다.
function changeVal(name, score) {
name = 'Seoltang'; // 원시 값은 변경 불가능한 값이므로 재할당을 통해 할당된 원시 값을 새로운 원시 값으로 교체
score.math = 85; // 객체는 변경 가능한 값이므로 재할당 없이 직접 할당된 객체를 변경
}
let name = 'Sooya';
let score = { math: 100 };
changeVal(name, score);
console.log(name); // 'Sooya'
console.log(score); // { math: 85 }
고차 함수는 매개변수를 통해 전달받은 콜백 함수의 호출 시점을 결정해서 호출한다.
function printAge(birthYear, fn) {
console.log("age: " + fn(birthYear));
}
const getAge = function(birthYear) {
return 2023 - birthYear;
}
printAge(1997, getAge); // getAge 콜백 함수는 단 한 번만 생성된다.
printAge(1995, function(birthYear) {
return 2023 - birthYear;
}); // 고차 함수가 호출될 때마다 콜백 함수가 매번 새로 생성된다.
Array.map
Array.slice
Date.now
, Math.random
: 호출할 때마다 다른 결과를 반환Array.push
: 원본 배열을 변경