함수 : 일련의 과정을 문으로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것
- 매개 변수 : 함수 내부로 입력을 전달하는 변수
- 인수 : 입력
- 반환 값 : 출력
함수 정의 : 함수 정의를 통해 함수 생성
↓
함수 호출 : 인수를 매개변수를 통해 함수에 전달하면서 실행을 명시적으로 지시
↓
함수 실행 : 문들이 일괄적으로 실행되고, 반환값 반환
// 함수 정의
function add(x, y) { // add : 함수 이름, x·y : 매개변수
return x + y; // 반환 값
}
// 함수 호출
add(2, 5); // 2·5 : 인수
함수는 필요할 때 여러 번 호출할 수 있으므로, 코드의 재사용
측면에서 매우 유용
코드의 중복을 억제하고 재사용성을 높여 유지보수의 편의성
과 코드의 신뢰성
을 높임
함수 리터럴은 function 키워드, 함수 이름, 매개변수 목록, 함수 몸체로 구성
// 변수에 함수 리터럴 할당 var f = function add(x, y) { return x + y; }
일반 객체는 호출할 수 없지만, 함수는 호출할 수 있다
함수 객체만의 고유한 프로퍼티를 가짐
함수를 호출하기 전, 인수를 전달받을 매개변수와 실행할 문들, 그리고 반환할 값을 지정하는 것
function add(x, y) {
return x + y;
}
함수 선언문은 함수 이름을 생략할 수 없다. (리터럴은 생략 가능)
표현식이 아닌 문이므로, 완료 값 undefined 출력
var add = function(x, y) {
return x + y;
}
자바스크립트의 함수는 일급 객체 (변수에 할당할 수도 있고 프로퍼티 값이 될 수 있는 값, 즉 값의 성질을 갖는 객체)
리터럴로 생성한 함수 객체를 변수에 할당 가능
함수 표현식의 함수 리터럴은 함수 이름을 생략하는 것(익명 함수)이 일반적
var add = function foo(x, y) {
return x + y;
}
console.log(add(2, 5)); // 7
console.log(foo(2, 5)); // ReferenceError : foo is not defined
var add = new Function('x', 'y', 'return x+y');
new
연산자 없이 호출해도 결과는 동일
일반적이지도, 바람직하지도 않음
Function
생성자 함수로 생성한 함수는
var add = (x, y) => x + y;
항상 익명 함수
기존 함수보다 표현, 내부 동작 간략화
생성자 함수로 사용할 수 없음
console.log(add); // f add(x, y)
console.log(sub); // undefined
console.log(add(2, 5)); // 7
console.log(sub(2, 5)); // TypeError : sub is not a function
function add (x, y) { // 함수 선언문
return x + y;
}
function sub (x, y) { // 함수 표현식
return x - y;
}
함수 호이스팅 : 함수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징
함수 선언문으로 정의한 함수는 함수 선언문 이전 호출 가능
함수 표현식으로 정의한 함수는 함수 표현식 이전에 호출 불가능
→ 함수의 생성 시점이 다르기 때문 !!
함수 선언문으로 함수를 정의하면 런타임 이전에 함수 객체가 먼저 생성된다.
함수 표현식은 함수 리터럴인 문, 함수 정의 시 함수 호이스팅이 아닌 변수 호이스팅이 발생
변수 호이스팅 vs 함수 호이스팅
런타임 이전에 자바스크립트 엔진에 의해 먼저 실행되어 식별자를 생성
변수 호이스팅 | 함수 호이스팅 |
---|---|
undefined로 초기화 | 함수 객체로 초기화 |
- 매개 변수 : 함수 내부로 입력을 전달하는 변수
- 인수 : 입력
매개 변수
인수
function add(x, y) {
return x + y;
}
console.log(add(2)); // NaN
console.log(add('a', 'b')); // 'ab'
return 키워드와 표현식(반환값)으로 이뤄진 반환문을 사용해 실행 결과를 함수 외부로 반환
반환문은 함수 몸체 내부에서만 사용 가능
반환문의 역할
function foo() {
return;
}
console.log(foo()); // undefined
function changeVal(primitive, obj) {
primitive += 100;
obj.name = 'Kim';
}
var num = 100;
var person = { name: 'Lee' };
console.log(num); // 100
console.log(person); // {name: "Lee"}
changeVal(num, person);
console.log(num); // 100
console.log(person); // {name: "Kim"}
primitive : 원시 타입 인수 / obj : 객체 타입 인수
원시 타입 인수는 값 자체가 복사되어 매개변수에 전달되기 때문에 함수 몸체에서 그 값을 변경해도, 원본은 훼손되지 않음
person 같이 함수가 외부 상태를 변경하면, 상태 변화 추적이 어려워짐 (코드의 복잡성 증가, 가독성 ↓)
즉시 실행 함수 : 함수 정의와 동시에 즉시 호출되는 함수
(function () {
var a = 3;
var b = 5;
return a * b;
}());
익명함수를 사용하는 것이 일반적
그룹 연산자 (...)
로 감싸야 함
값을 반환할 수도, 인수를 전달할 수도 있음
var res = (function() {
var a = 3;
var b = 5;
return a * b;
}());
console.log(res); // 15
res = (function (a, b) {
return a * b;
}(3, 5));
console.log(res); // 15
재귀 함수 : 자기 자신을 호출하는 행위(재귀 호출)를 수행하는 함수
function factorial(n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
중첩 함수 (내부 함수) : 함수 내부에 정의된 함수
외부 함수 : 중첩 함수를 포함하는 함수
function outer() {
var x = 1;
function inner() {
var y = 2;
console.log(x + y);
}
inner();
}
콜백 함수 : 함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수
고차 함수 : 매개변수를 통해 함수의 외부에서 콜백 함수를 전달받은 함수
function repeat(n, f) {
for (var i=0; i<n; i++) {
f(i);
}
}
var logAll = function(i) {
console.log(i);
};
repeat(5, logAll); // 0 1 2 3 4
콜백 함수는 고차 함수에 의해 호출되며, 고차 함수는 필요에 따라 콜백 함수에 인수를 전달할 수 있음
콜백 함수는 함수형 프로그래밍 패러다임 뿐만 아니라 비동기 처리에 활용되는 중요한 패턴
document.getElementById('mybutton').addEventListener('click', function() {
console.log('button clicked!');
});
setTimeout(function () {
console.log('1초 경과');
}, 1000);
순수 함수 : 어떤 외부 상태에 의존하지도 않고 변경하지도 않는, 부수효과가 없는 함수
비순수 함수 : 외부 상태에 의존하거나 외부 상태를 변경하는, 부수 효과가 있는 함수
// 순수 함수
var count = 0;
function increase(n) {
return ++n;
}
// 재할당해서 상태 변경
count = increase(count);
console.log(count); // 1
count = increase(count);
console.log(count); // 2
// 비순수 함수
var count = 0;
function increase() {
return ++count;
}
increase();
console.log(count); // 1
increase();
console.log(count); // 2