▣ 함수 선언식(Function Declaration)
/* Function Declaration */
function greet() {
console.log("Hello.");
}
let result = greet();
console.log(result);
function greeting() {
return "Hello.";
}
result = greeting();
console.log(result);
'function' 이라는 선언 키워드(연산자)와 함수 이름 그리고 ( ) 기호 및 { } 블럭을 함께 작성함으로써 함수가 선언되며, 함수 이름과 ( ) 기호를 사용하면 함수를 호출하게 됩니다. { } 블럭 안에는 함수 호출 시 실행되는 명령 구문을 작성합니다.
위의 코드와 아래의 결과를 살펴보면, greet() 은 콘솔 화면에 "Hello."를 출력하는 명령을 실행하며 이때의 반환 값은 undefined 입니다. 반면에 greeting() 은 실행되는 내용이 아무것도 없으며, 다만 "Hello."라는 문자열을 반환할 뿐입니다. 결국 '함수'의 정의에서 함수의 실행 결과 어떤 일이 일어나며, 어떤 값을 반환하는지가 중요합니다.
![](https://blog.kakaocdn.net/dn/bAYW78/btq2D3to990/Cj9uNIsUuKWeaYyLeOf9tk/img.png)
□ 함수 선언 예시
/* With Arguments */
function greetTo(firstName, lastName) {
return `Hello ${firstName} ${lastName}.`;
}
console.log(greetTo("John", "Doe"));
console.log(greetTo());
/* Control undefined Type */
function greetingTo(firstName, lastName) {
if (typeof firstName === "undefined") firstName = "John";
if (typeof lastName === "undefined") lastName = "Doe";
return `Hello ${firstName} ${lastName}.`;
}
console.log(greetingTo());
/* With Default */
function greetingWithDefault(firstName = "John", lastName = "Doe") {
return `Hello ${firstName} ${lastName}.`;
}
console.log(greetingWithDefault());
함수에서 실행 결과와 반환값 만큼이나 중요한 것이 ( ) 안에 주어지는 인자(Parameter)입니다. 함수의 인자에 값이 아닌 변수가 주어지면 매개 변수(Argument), 함수가 주어지면 콜백 함수(Callback function)라고 합니다.
함수의 매개 변수는 원하는 갯수만큼 정의할 수 있으며, 다만 매개 변수의 값이 주어지지 않을 경우 undefined로 처리되기 때문에 이를 방지하기 위해 If 조건문을 이용하여 매개 변수의 값을 제어합니다. 그런데 함수를 정의할 때마다 매번 조건문을 작성하는 것은 번거운 일이므로 이런 상황에 대비하여 매개 변수에 기본(Default) 값을 설정할 수도 있습니다.
위의 코드와 아래의 결과에서 확인할 수 있듯이 처음에는 매개 변수만 이용하였고, 두 번째는 매개변수와 If조건문, 그리고 마지막 세 번째는 매개변수의 기본값을 설정하여 함수를 정의하고 호출해 보았습니다.
![](https://blog.kakaocdn.net/dn/cFkZfu/btq2zCRy5Sa/tiHrrK80fFNlRgSKjj0M0K/img.png)
▣ 함수 표현식(Function Expression)
/* Function Expression */
const square = function (x = 1) {
return x * x;
};
console.log(square(3));
console.log(square());
함수 표현식은 함수 선언식에서 함수 이름을 뺀 나머지 부분을 변수(함수 이름)에 할당하는 식으로 함수를 정의하는 또 다른 방법입니다. 이때 할당되는 변수가 새로 사용되는 변수라면 당연히 선언 키워드(연산자) const 또는 let 과 함께 작성됩니다.
위의 코드에서 익명 함수(Anonymous function) 형태의 function (x=1) { return x * x; } 이 변수 square와 함께 초기화되었고, 이 함수를 호출한 결과는 아래와 같습니다.
![](https://blog.kakaocdn.net/dn/yk44B/btq2DsUxfN1/KnVFr7WVVsqp15a8VPQnD1/img.png)
▣ 함수 선언식 VS 함수 표현식
□ 함수 선언과 호이스팅
/* Function Declaration -> Hoisting */
function hello() {
return "Hello world";
}
console.log(hello());
function hello() {
return "Hello";
}
위의 코드를 보면 hello() 함수를 호출하기 이전과 이후에 2번 함수를 정의하였습니다. 이때 함수 이름은 둘 다 hello로 같지만 반환되는 값은 각각 "Hello world" 와 "Hello"로 서로 다릅니다. 함수를 호출한 결과 어느 쪽이 실행될까요?
![](https://blog.kakaocdn.net/dn/K0wgq/btq2CIp0Ezw/617cAhp0R95BjF5yeIRp0k/img.png)
일반적인 코드 진행이라면 분명히 "Hello world"가 반환될 것처럼 보이지만 실제 결과는 "Hello"가 반환되었습니다. 당장 이해하기 어렵지만 일단 보이는 코드로만 설명하자면, 함수 호출 이전에 정의된 함수가 아닌 호출 이후에 재정의된 함수가 호출된 것이며, 자바스크립트에서 이러한 현상을 호이스팅(Hoisting)이라고 합니다.
조금 더 설명을 보태자면, 자바스크립트 컴파일러는 함수가 호출되는 시점을 기준으로 이전 코드로부터 함수 정의와 관련된 내용을 참조하는 것이 아니라 실제 메모리에 저장되어 있는 모든 영역(전역 객체; Global object)으로부터 참조합니다. 호이스팅과 관련된 자세한 내용은 링크를 참고하기 바랍니다.
□ 함수 표현과 재선언 방지
/* Function Expression -> Avoiding redeclaration */
const sayHello = function () {
return "Hello world";
};
console.log(sayHello());
// Uncaught SyntaxError: Identifier 'sayHello' has already been declared
function sayHello() {
return "Hello";
}
반면, 위와 같이 표현식으로 먼저 함수를 정의할 경우에는 이후에 함수를 재정의 하더라도 에러를 발생시켜 예측 가능하고 안전한 코드가 됩니다.
![](https://blog.kakaocdn.net/dn/dLwvxB/btq2zdxCuUf/kIgL6qa0QTMwoxp4GEGCgK/img.png)
결론은 표현식으로 함수 정의를 먼저하고 이후에 함수를 호출하여 사용하며, 선언식은 가급적 사용하지 않는 것이 좋습니다.
![](https://blog.kakaocdn.net/dn/Od6ru/btq2Dr2r7lj/hZhZKB7LUjUDXWSZtjidik/img.png)
▣ 즉시 호출 함수(Immediately Invoked Function Expression; IIFE)
다른 명칭으로 자기실행 익명함수(Self Executing Anonymous Function)라고도 하며, 함수가 정의되는 즉시 실행되기 때문에 함수 이름이 없습니다.
/* Immediately Invoked Function Expression : IIFE */
(function () {
console.log("This is IIFE.");
})();
(function (name) {
console.log(`Hello ${name}.`);
})("John");
// Uncaught SyntaxError: Function statements require a function name
function () {
console.log('This is IIFE.');
}
함수를 담아둘 (변수) 이름이 없기 때문에 반드시 ( ) 기호 안에 담겨 있어야 합니다. 그렇지 않으면 에러가 발생됩니다.
![](https://blog.kakaocdn.net/dn/dnk3FI/btq2z1qbnbt/iuJZAVDmzpLp0dZZ8FZwb0/img.png)
즉시 호출 함수를 호출하고자 할 때는 일반적인 함수와 마찬가지로 함수 오른쪽 옆에 ( ) 기호를 붙입니다. 그리고 매개변수도 동일하게 적용하여 사용할 수 있습니다.
![](https://blog.kakaocdn.net/dn/lA6pT/btq2yofg6Lx/OVMKkYP4xUNlKrXNBLnlpk/img.png)
▣ 객체 메서드 함수(Object Method Function)
객체를 정의 할때 특성의 값이 함수가 될 경우 이를 메서드(Method)라고 하며, 객체의 특성을 표기하는 방법과 마찬가지로 . 표기법(Dot notation) 또는 [ ] 표기법(Bracket Notation)에 ( ) 기호를 붙여 객체의 메서드를 호출할 수 있습니다. 또한, 객체 메서드는 객체 영역 { } 밖에서 정의되어 호출되는 것도 가능합니다.
□ 객체 메서드 함수 예시
/* Object Method Function */
const todo = {
add: function () {
console.log("Add to todo list.");
},
edit: function (id) {
console.log(`Edit todo item ID ${id}.`);
},
};
todo.add();
todo.edit(100);
todo['add']();
todo['edit'](100);
todo.delete = function () {
console.log("Delete from todo list.");
};
todo.delete();
객체 영역 내에서 정의된 메서드 todo.add() 와 todo.edit() 처럼 객체 영역 밖에서 정의된 메서드 todo.delete() 또한 정상적인 호출이 가능함을 결과를 통해 알 수 있습니다.
![](https://blog.kakaocdn.net/dn/dTzfnu/btq2CDCjmlD/IMvhtCiDA7zMzEdfdLnLw1/img.png)
□ 객체 메서드 함수의 단축 문법
/* Shorthand Syntax */
const todo = {
add() {
console.log("Add to todo list.");
},
edit(id) {
console.log(`Edit todo item ID ${id}.`);
},
};
todo.add();
todo.edit(100);
todo["add"]();
todo["edit"](100);
todo.delete = function () {
console.log("Delete from todo list.");
};
todo.delete();
단축 문법이 적용되면 위의 코드와 같이 객체 메서드가 좀 더 간략화 됩니다. 객체 정의 단계에서 약간의 차이가 있을 뿐 메서드를 호출하는 방법은 변함이 없습니다.
![](https://blog.kakaocdn.net/dn/CJglw/btq2Ds79Nmk/Ksd5oj5hjYtix0AGbFNaE0/img.png)
'자바스크립트 > 바닐라 JS' 카테고리의 다른 글
[자바스크립트] TIL10 : 윈도우 객체의 이용 방법 (0) | 2021.04.15 |
---|---|
[자바스크립트] TIL8 : 반복문의 종류와 구조 / 객체의 특성과 배열의 요소 순회를 위한 반복문 활용 (0) | 2021.04.14 |
[자바스크립트] TIL7 : 조건문의 종류와 구조 / 비교 및 논리, 삼항 연산자를 이용한 흐름 제어 (0) | 2021.04.13 |
[자바스크립트] TIL6 : 객체의 정의와 특성 이름의 표기 방법 / 데이트 객체를 이용한 날짜와 시간 처리 (0) | 2021.04.12 |
[자바스크립트] TIL5 : 배열 메서드를 이용한 배열의 요소 변경 / 템플릿 문자열의 이용 방법 (0) | 2021.04.11 |
댓글