코드 블록으로 감싸져 있는, 문으로 이루어진 하나의 실행 단위
function add(x,y) {
return x + y;
}
add(2,5)
일급 객체: 값의 성질을 갖는 객체
별도의 할당 명령 없이, 함수 이름을 포함하는 함수 리터럴로 함수를 생성하는 방식
이때의 함수 리터럴은 표현식이 아닌 문임
JS 엔진은 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고, 생성된 함수 객체를 할당함
-> 즉, 함수 이름이 아니라 함수 객체를 가리키는 식별자로 함수를 호출하는 것임
-> 결론적으로, JS 엔진은 함수 선언문을 함수 표현식으로 변환하여 함수 객체를 생성함 (but 함수 선언문 ≠ 함수 표현식)
function add(x, y) {
return x + y;
}
console.log(add(2, 5)); // 7
함수 리터럴로 생성한 함수를 변수에 할당하는 방식
const add = function (x, y) {
return x + y;
};
console.log(add(2, 5)); // 7
함수 호이스팅: 런타임 이전에 함수 객체가 생성되고, 함수 이름과 동일한 이름의 식별자가 해당 객체로 초기화됨
변수 호이스팅: var 키워드로 선언됐을 경우, 런타임 이전에 식별자가 undefined로 초기화됨
const add = Function("x", "y", "return x+y");
console.log(add(2, 5)); // 7
cf) 생성자 함수: 객체를 생성하는 함수
this
바인딩 방식이 다름arguments
객체 생성 Xconst add = (x, y) => x + y;
console.log(add(2, 5)); // 7
undefined
임function add(x, y) {
console.log(x, y);
}
add(2); // 2 undefined
arguments
객체에 보관됨function add(x, y) {
console.log(x, y);
console.log(arguments);
}
add(2, 3, 4); // 2 3
// Arguments(3) [2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ]
function add(x, y) {
if (typeof x !== "number" || typeof y !== "number")
throw new TypeError("인수는 모두 숫자 값이어야 합니다.");
return x + y;
}
console.log(add(2)); // Uncaught TypeError: 인수는 모두 숫자 값이어야 합니다.
function add(x = 0, y = 0) {
return x + y;
}
console.log(add(1)); // 1
function call(obj) {
console.log(obj.data.id); // 1
}
call({
method: "POST",
url: "/user",
data: { id: 1, name: "J" },
cache: false,
});
return
키워드 뒤의 표현식을 평가하여 반환함undefined
를 반환함function multiply(x, y) {
return x * y;
console.log("실행 X");
}
console.log(multiply(2, 3)); // 6
function foo() {}
console.log(foo()); // undefined
Object.freeze()
)로 만들거나, 전달받은 객체를 방어적 복사(by Object.assign()
or spread operator
)하여 내용을 변경함으로써 외부 상태가 변경되는 부수 효과를 방지함function changeVal(primitive, obj) {
primitive += 100;
obj.name = "H";
}
let num = 100;
obj = { name: "J" };
console.log(num, obj); // 100 {name: 'J'}
changeVal(num, obj);
console.log(num, obj); // 100 {name: 'H'}
const res = (function (a, b) {
return a * b;
})(3, 5);
console.log(res); // 15
function countdown(n) {
if (!n) return;
console.log(n);
countdown(n - 1);
}
countdown(5); // 5 4 3 2 1
function factorial(n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
console.log(factorial(5)); // 120
cf) 외부 함수: 중첩 함수를 포함하는 함수
function outer() {
const x = 1;
function inner() {
const y = 2;
console.log(x + y);
}
inner();
}
outer(); // 3
매개변수를 통해 다른 함수의 내부로 전달되는 함수
매개변수를 통해 외부에서 콜백 함수를 전달받는 함수
-> 콜백 함수는 고차 함수에 의해 호출됨
function foo(cb) {
cb();
}
foo(function () {
console.log(1);
}); // 고차 함수가 호출될 때마다 콜백 함수가 생성됨
function foo(cb) {
cb();
}
// 콜백 함수는 한 번만 생성됨
const cb = function () {
console.log(1);
};
foo(cb);
순수 함수: 외부 상태를 변경하지 않고, 외부 상태에 의존하지도 않는 함수
-> 동일한 인수가 전달되면 언제나 동일한 값을 반환함
함수가 외부 상태를 변경하면 상태 변화를 추적하기 어려워지므로, 순수 함수를 사용하는 것이 좋음
let count = 0;
// 순수 함수
function increase(n) {
return ++n;
}
// 비순수 함수
function increase() {
return ++count;
}
cf) 함수형 프로그래밍: 순수 함수를 통해 부수 효과를 최대한 억제하여 프로그램의 안정성을 높이려는 프로그래밍 패러다임