JavaScript 함수

seul_velog·2021년 12월 3일
0

JavaScript

목록 보기
8/25
post-thumbnail

📍 함수(function)란?

함수는 프로그래밍을 구성하는 기본적인 빌딩 블럭으로, 하나의 로직을 재실행 할 수 있도록 기능 함으로써 코드의 재사용성을 높여준다.
대체적으로 함수는 한가지의 업무나 아니면 어떤 값을 계산하기 위해 쓰여진다.


✍️ 함수의 효용성

▼ 이 세가지는 서로 밀접한 관련이 있으며 프로그래밍이 발전됨에 있어서 핵심적인 부분이다.

  • 재사용성
    : 코드를 한번 정의하여 여러번, 여러맥락에서 다시 재사용한다.
    또, 한개의 함수는 호출 시 보내는 데이터(인수, argument)를 입력, 변경해줌에 따라 정의된 기능을 토대로 관련된 값을 계속해서 얻어낼 수가 있다.
  • 유지보수의 용이성
    : 정의된 코드에 수정, 개선이 생기면 이 함수가 사용된 모든 곳에서 수정, 개선 등이 동시에 일어난다.
  • 가독성
    : 긴 로직을 담고있는 함수를 잘 정의한 것으로도 전체적인 코드를 읽기가 쉬워진다. 함수명과 그에 따른 함수의 실행 효과를 (취지를) 쉽게 예상할 수 있으며 재사용, 유지보수에도 도움이 된다.



1. 함수의 형식

function 함수명( [인자...[,인자]] ){
   코드
   return 반환값
}

자바스크립트의 함수는 리턴 타입을 명시하지 않는다. function 키워드로 함수를 선언하고, 괄호 안에서 매개변수를 받으며, return 을 통해 값을 반환한다.

  • ❗️ return 이라는 키워드가 등장하면 두가지 일이 발생한다.
    1) 이 함수를 종료 시키며, 뒤에 코드가 있어도 실행되지 않는다.
    2) 리턴 뒤에 ; 전까지 있는 값을 이 함수의 출력 값으로 반환하게 된다.




2. 함수의 정의

함수를 정의하는 방법에는 여러가지가 있다.

❗️하나의 함수는 한가지의 일만 하도록 만드는게 포인트이며, 함수의 이름을 지정할 땐 동사나 커맨드 형태로 쓰는 것이 좋다고 한다. 만약 이름 정하기가 어렵다면 이 함수가 하는일이 너무 복잡하고 다양한 것은 아닌지 체크해봐야 한다.🧐

2-1. 함수 선언문

함수 선언문(Function declaration) 방식

function functionName (param1, param2, ... ) {
  // Do Something
}

끝에 ; 를 붙이지 않는다. (JS 엔진에 의해 함수 몸체를 닫는 중괄호 뒤에 ; 가 자동 추가된다.)

(1) 함수명
함수 선언문의 경우에는 함수명은 생략할 수 없다.
함수명은 함수 몸체에서 자신을 재귀적(recursive) 호출하거나 자바스크립트 디버거가 해당 함수를 구분할 수 있는 식별자이다. (우리가 디버깅을 할때 디버깅의 스택추적(stack traces)에 함수의 이름이 나오게 하기위해 쓰는 경우 등)

(2) 매개변수 목록
0개 이상의 목록으로 괄호로 감싸고 콤마로 분리한다. 다른 언어와의 차이점은 매개변수의 타입을 기술하지 않는다는 것이다. 이 때문에 함수 몸체 내에서 매개변수의 타입 체크가 필요할 수 있다.

📍 타입스크립트에서는 매개변수나 리턴의 타입을 명시해야 하는데, Type Script 에서 타입스크립트와 자바스크립트 두개를 비교할 수 있다. ( 타입스크립트 부분에 타입을 지정하지 않으면 에러가 뜨는 것을 확인할 수 있다.🧐 )

(3) 함수 몸체
함수가 호출되었을 때 실행되는 문들의 집합이다. 중괄호({ })로 문들을 감싸고 return 문으로 결과값을 반환할 수 있다. 이를 반환값(return value)라고 한다.



2-2. 함수 표현식

함수 표현식(Function expression) 방식

let functionName = function( param1, param2, ... ) {
  // Do Something
};

끝에 ; 를 붙인다.

  • 변수를 선언하고 함수를 대입하는 방식이다.
  • 함수 표현식으로 정의한 함수는 함수명을 생략할 수 있다.
    - 함수명이 없는 함수 표현식: 익명 함수 표현식(anonymous function expression)
    - 함수명이 있는 함수 표현식: 기명 함수 표현식(named function expression)
  • 함수는 일급객체이기 때문에 변수에 할당할 수 있는데 이 변수는 함수명이 아니라 할당된 함수를 가리키는 참조값을 저장하게 된다.
    ❗️함수 호출시에는 함수명이 아니라 함수를 가리키는 변수명을 사용한다.

(1) ▼ 함수 표현식이 가능한 것은 JavaScript의 함수는 아래와 같은 특징을 갖기 때문이다.

  • 자바스크립트의 함수는 일급 객체(first-class object)이다.
  1. 무명의 리터럴로 표현이 가능하다.
  2. 변수나 자료 구조(객체, 배열…)에 저장할 수 있다.
  3. 함수의 파라미터로 전달할 수 있다.
  4. 반환값(return value)으로 사용할 수 있다.

📍 일급 객체란 생성, 대입, 연산, 인자 또는 반환값으로서의 전달 등 프로그래밍 언어의 기본적 조작을 제한없이 사용할 수 있는 대상을 의미한다.


(2) ▼ 함수 표현식에대해 조금 더 알아보자..✍️

ex.1)
const print = function (){  // anonymous function이다.
    console.log('print');
};
print(); // print
const printAgain = print;
printAgain(); // print
  • 1행을 보면 함수를 선언함과 동시에 바로 print라는 변수에 할당하는 것을 볼 수 있다. (함수의 이름 없이 필요한 부분만 작성해서 변수에 할당)
  • 1행 에서 이렇게 함수를 print 에 할당하게 되면, 4행 처럼 print 라는 변수에 함수를 호출하듯이 호출하여, print 라는 값을 볼 수 있다.
  • 5행에서 다시 다른변수에 할당을 하면 결국 printAgain1행print 함수를 가르키고 있는 것이므로, 6행 에 다시 함수를 호출하는 것 처럼 하면, print 가 출력되는 걸 볼 수 있다.
  • 원한다면 함수의 이름을 작성할 수도 있다. ( 1행 const print = function print() {...}) 그리고 이렇게 이름이 있는 것을 named function 이라고 한다.
ex.2)
function square(number) {
  return number * number;
} 

ex.2-1)
var square = function square(number) {
  return number * number;
};
  • ❗️ 위의 예제에서 주의할 점
    함수가 할당된 변수를 사용해 함수를 호출하지 않고 기명 함수의 함수명을 사용해 호출하게 되면 에러가 발생한다. 이는 함수 표현식에서 사용한 함수명은 외부 코드에서 접근 불가능하기 때문이다.
    함수 선언문의 경우 함수명으로 호출할 수 있었던 것은, 자바스크립트 엔진에 의해 함수 표현식으로 형태가 변경되었기 때문이라고 한다!
    (아래 예제를 보면 함수명과 함수 참조값을 가진 변수명이 일치하므로 함수명으로 호출되는 듯 보이지만 사실은 변수명으로 호출 된 것)
    즉, 함수 선언문도 함수 표현식과 동일하게 함수 리터럴 방식으로 정의되는 것
    ( ✍️ 리터럴이란, 선언함과 동시에 값 또는 코드를 지정해주는 것을 말한다. )


2-3. 함수선언문과 함수표현식의 차이점

  • 함수 선언문 (function declaration)
    : 함수 선언문이 정의되기 전에도 호출 가능하다. 즉, 호이스팅이 된다.

  • 함수 표현식 (function expression)
    : 할당된 다음부터 호출이 가능하다. 실제 실행 흐름이 해당 함수에 도달했을 때 함수를 생성하기 때문에, 실행 흐름이 함수에 도달했을 때부터 해당 함수를 사용할 수 있다. (함수 표현식의 경우 함수 호이스팅이 아니라 변수 호이스팅이 발생한다고 한다.)

✍️ ❗️ 함수 호이스팅이 함수 호출 전 반드시 함수를 선언하여야 한다는 규칙을 무시하므로 함수 표현식을 사용할 것을 권장한다고 한다.



2-4. Function 생성자 함수

  • Function 생성자 함수는 Function.prototype.constructor 프로퍼티로 접근할 수 있다.
  • 일반적으로 사용하지는 않는다.

생성자 함수 방식

new Function(arg1, arg2, ... argN, functionBody)





3. 매개변수(Parameter) & 인수(argument)

3-1. 매개변수(인자)

매개변수(Parameter), 인자 값(Parameter) 이란 함수를 정의할 때 외부로부터 받아들이는 임의의 값을 의미한다.

  • 함수의 작업 실행을 위해 추가적인 정보가 필요할 경우, 매개변수를 지정한다. 매개변수는 함수 내에서 변수와 동일하게 동작한다.

(1) Call-by-value
❗️ primitive type (원시타입) 인수를 매개변수로 전달할 경우, 메모리에 값이 그대로 저장되어 있기 때문에 값이 전달이 된다.

  • 즉, 함수 호출 시 원시 타입 인수를 함수에 매개변수로 전달할 때 매개변수에 값을 복사하여 함수로 전달하는 방식이다.
  • 함수 내에서 매개변수를 통해 값이 변경되어도 전달이 완료된 원시 타입 값은 변경되지 않는다.
let num = function(primitive){
    return primitive + 1;
}
const a = 1;
console.log(num(a)); // 2
console.log(a); // 1

(2) Call-by-reference
❗️ object (객체형) 인수 같은 경우에는 메모리에 reference주소가 저장되어 지므로, ref가 전달된다.

  • 즉, 함수 호출 시 참조 타입 인수를 함수에 매개변수로 전달할 때 매개변수에 값이 복사되지 않고 객체의 참조값이 매개변수에 저장되어 함수로 전달되는 방식
  • 함수 내에서 매개변수의 참조값을 이용하여 객체의 값을 변경했을 때 전달되어진 참조형의 인수값도 같이 변경된다.
let seul = function(p, object){
    p += 2;
    obj.name = 'kim';
    obj.gender = 'female';
}
let num = 0;
let obj = {
    name: 'lee',
    gender: 'male'    
};
seul('num', 'obj');
console.log(num);   // 0
console.log(obj);   // {name: 'kim', gender: 'female'}


3-2. 인수

인수(argument) 란 함수를 호출할 때 사용되는 값들이다.


매개변수는 함수 내에서 변수와 동일하게 메모리 공간을 확보하며, 함수에 전달한 인수는 매개변수에 할당된다. 만약 인수를 전달하지 않으면 매개변수는 undefined로 초기화된다.

let seul = function (p1, p2) {
  console.log(p1, p2);
};
seul(1); // 1 undefined

✍️ 지금까지 매개변수와 인자가 각각 parameter, argument 인줄 알았는데, 사실 매개변수와 인자는 parameter로 같은 의미이고, 인수라는 것이 argument라는 걸 알게 되었다. 앞으로 헷갈리지 않도록 잘 숙지할 것! 🙂





4. 함수의 선언과 호출

4-1. 함수의 선언

▼ (1) 함수 선언문

function functionName (param1, param2, ... ) {
  // Do Something
}

▼ (2) 함수 표현식

let functionName = function( param1, param2, ... ) {
  // Do Something
};

위 예제에서 함수를 선언해줌과 동시에 우리는 functionName 이라는 단어를 사용할 수 있게 되고, JavaScript 실행 엔진도 functionName 이라는 단어가 지정된 함수를 의미한다는 것을 알게 된다.



4-2. 함수의 호출

  • 선언해 놓은 함수는 아래와 같이 소괄호를 이용하여 호출할 수 있다.
  • 함수를 호출하기 전까지는 함수 내부의 코드 구문들은 실행되지 않는다.

(1) 함수 선언문일 경우, 선언 전 또는 선언 후에 호출할 수 있다. (함수호이스팅)

functionName( argument1, argument2, ... );
function functionName( param1, param2, ... ) {
  // Do Something
}
function functionName( param1, param2, ... ) {
  // Do Something
}
functionName( argument1, argument2, ... );

(2) 함수 표현식일 경우, 호출은 함수 선언 후에 해야 한다.

let functionName = function( param1, param2, ... ) {
  // Do Something
};
functionName( argument1, argument2, ... );


4-3. 즉시 실행 함수 IIFE

  • IIFE (Immediately Invoked Function Expression)로 JavaScript에서 함수를 바로바로 실행하고 싶을 때 유용하게 쓸 수 있다.
  • 즉시 실행 함수 내에 처리 로직을 모아 두고, 혹시 있을 수도 있는 변수명 또는 함수명의 충돌을 방지하는 목적으로써 사용되기도 한다.

(1) 함수 선언 후 따로 호출을 해줄 경우

function hello(){
    console.log('IIFE');
}
hello();

(2) 선언함과 동시에 호출된다.

(function hello(){
    console.log('IIFE');
})();

😓 요즘에는 잘 쓰이지 않는다고 한다.





5. 반환값

함수는 자신을 호출한 코드에게 수행한 결과를 반환(return) 할 수 있다. 이때 반환된 값을 반환값(return value) 이라 한다.

  • return 키워드는 함수를 호출한 코드에게 값을 반환할 때 사용한다.
  • 함수는 배열 등을 이용하여 한 번에 여러 개의 값을 리턴할 수 있다.
  • 함수는 반환을 생략할 수 있는데, 이때 함수는 암묵적으로 undefined 를 반환한다.
  • 자바스크립트 해석기는 return 키워드를 만나면 함수의 실행을 중단한 후, 함수를 호출한 코드로 되돌아간다.

(1) 단일 값일 경우

function calculate(width, height){
    let a = width + height
    return a;
}
console.log(calculate(2,4)); // 6

(2) 복수 값일 경우

function getSize(whith, height, depth){
    let a = whith * height;
    let b = whith * height * depth;
    return [a, b]
}
console.log(getSize(2,3)[0]); //6
console.log(getSize(2,3,4)[1]); //24





6. 화살표 함수

❗️ 화살표 함수(Arrow function)는 함수를 간결하게 만들어주는 함수이다.
항상 이름이 없는 anonymous function 이다.

✍️ arrow function 작성해보기.

ex1.)
const simplePrint = function (){
    console.log('simplePrint!');
};const simplePrint = () => console.log('simplePrint!');


ex2.)
const add = function (a, b){
    return a + b;
}const add = (a, b) => a + b;


ex3.)
const simpleMultiply = (a, b) => {
    //do something more
    return a + b;
}
  • ex.1,2) : 이렇게 함수 표현식 function expression 을 쓰게되면,function 이라는 키워드도 써야하고 {} 블럭도 계속 써야하는 번거로움이 있는데, arrow function 은 이것을 간단하게 해준다 !

  • ex.3) : 예제 1, 2는 한줄일 경우 블럭없이 작성이 가능하지만, 함수 안에서 조금 더 다양한 일들을 해야해서 블록이 필요할 경우, 블록을 넣어서 처리할 수 있다. 대신 블록을 쓰면 return 키워드를 이용해서 값을 내야한다.




reference
dream coding MDN-function ofcourse zerocho poiemaweb Coding Everybody

profile
기억보단 기록을 ✨

0개의 댓글