유명한 담벼락

Javascript : JS에서의 함수

by 담담이담

1. 함수 선언 방법

 

1) 함수 선언(function 키워드 사용)

 

// 함수 선언
function sayHi() {
  console.log('Hi!');
}

이렇게 작성하는 방식을 함수 선언(function declaration)이라고 한다.

함수 선언식은 호이스팅이 발생하며, 함수 스코프를 갖는다. 

 

2) 함수 표현식

그리고 자바스크립트에서 함수는 값으로 취급될 수도 있기 때문에 변수에 할당해서 함수를 선언할 수도 있다.

// 함수 표현식
const sayHi = function () {
  console.log('Hi!');
};


myBtn.addEventListener('click', function() {
  console.log('button is clicked!');
});

이렇게 함수를 값으로 다루는 방식을 함수 표현식 (function expression)이라고 한다.


함수 표현식은

var로 선언한 경우에는 호이스팅이 발생하며, 함수 스코프를 갖지만,

let이나 const로 선언한 경우에는 호이스팅이 발생하지 않는 것처럼 보이며, 블록 스코프를 갖는다.

 

2)-1 기명 함수 표현식

함수 표현식으로 함수를 만들 때 선언되는 함수에 이름을 붙일 수 있으며, 

이러한 함수 표현식을 기명 함수 표현식이라고 한다.

함수 표현식으로 할당된 변수는 자동으로 name이라는 프로퍼티를 갖는다.

 

i) 기명 함수 표현식이 아닌 경우

 

아래의 경우는 이름을 붙이지 않는 함수의 예시이다.

이름이 없는 함수를 변수에 할당할 때, 변수의 name 프로퍼티는 변수 이름이 된다.

const sayHi = function () {
  console.log('Hi');
};

console.log(sayHi.name); // sayHi

 

 

ii) 기명 함수 표현식을 사용한 경우

 

 이름이 있는 함수를 변수에 할당하면,

변수의 name 프로퍼티는 함수 이름이 된다.

 

보통 재귀함수처럼 함수 내부에서 함수 자신을 다시 호출할 때는

기명 함수 표현식을 사용하는 게 좋다.

const sayHi = function printHiInConsole() {
  console.log('Hi');
};

console.log(sayHi.name); // printHiInConsole

 

2. 다양한 함수의 형태

자바스크립트에서 함수는 값으로 취급된다.

이런 특징은 코드를 작성할 때 다양한 형태로 활용될 수 있다.

// 변수에 할당해서 활용
const printJS = function () {
  console.log('JavaScript');
};

// 객체의 메소드로 활용
const codeit = {
  printTitle: function () {
    console.log('Codeit');
  }
}

// 콜백 함수로 활용(1) 
myBtn.addEventListener('click', function () {
  console.log('button is clicked!');
});

// 콜백 함수로 활용(2)
function makeQuiz(quiz, answer, success, fail) {
  if (prompt(quiz) === answer) {
    console.log(success());
  } else {
    console.log(fail());
  }
};

function getSuccess() {
  return '정답';
};

function getFail() {
  return '오답!';
};

const question = '5 + 3 = ?';
makeQuiz(question, '8', getSuccess, getFail);


// 고차 함수로 활용
function myFunction() {
  return function () {
    console.log('Hi!?');
  };
};

const sayHi = getPrintHi();

sayHi();
getPrintHi()();

1) 콜백함수

 

다른 함수의 파라미터로 전달되는 함수

첫 번째 예시에서는 addEventListener의 두 번째 파라미터가

두 번째 예시에서는 getSuccess와 getFail이 콜백함수이다.

 

 

2) 고차함수 

 

함수를 리턴하는 함수

 

 

3. 파라미터의 기본값

 

자바스립트에서 함수의 파라미터는 기본값을 가질 수가 있다.

기본값이 있는 파라미터는 함수를 호출할 때 아규먼트를 전달하지 않으면,

함수 내부의 동작은 이 파라미터의 기본값을 가지고 동작하게 된다.

 

 

function sayHi(name = 'Codeit', interest = "Python") {
  console.log(`Hi! ${name}.`);
  console.log(`I like ${interest}.`);
}

// 예시 1
sayHi('JavaScript'); 
/* Hi! JavaScript.
I like undefined. */

// 예시 2
sayHi(undefined, 'JavaScript'); 
/* Hi! Codeit.
I like JavaScript.*/

//예시 3
sayHi(null, 'JavaScript'); 
/* Hi! null.
I like JavaScript.*/

 

예시 1 

만약 파라미터가 두 개인데, 아규먼트는 하나만 전달했다면

 기본값과 무관하게 무조건 순서대로 전달된다.

 

예시 2, 3

undefined를 아규먼트로 넘기면, 기본값이 작동하지만,

null을 아규먼트로 넘기면 null값이 그대로 삽입된다.

 

 

4. arguments 객체

자바스크립트 함수 안에는 arguments라는 독특한 객체가 존재한다.

 

arguments 객체는 함수를 호출할 때

전달한 아규먼트들을 배열의 형태로 모아둔 유사 배열 객체다.

 

특히, 함수를 호출할 때 전달되는 아규먼트의 개수가

불규칙적일 때 유용하게 활용될 수 있다.

function printArguments() {
  // arguments 객체의 요소들을 하나씩 출력
  for (const arg of arguments) {
    console.log(arg);
  }
}

printArguments('Young', 'Mark', 'Koby');

참고로 arguments라는 객체를 활용하고자 한다면

함수 안에서 사용할

파라미터나 변수, 함수의 이름을 arguments라고 짓는 것은 피하는게 좋다.

 

 

5. Rest Parameter

 

arguments 객체를 이용하는 것 말고도 불규칙적으로 전달되는 아규먼트를 다루는 방법이 있다.

파라미터 앞에 마침표 세 개를 붙여주면, 여러 개로 전달되는 아규먼트들을 배열로 다룰 수 있다.

 

그리고 arguments객체는 유사 배열이기 때문에 배열의 메소드를 활용할 수 없는 반면,

rest parameter는 배열이기 때문에 배열의 메소드를 자유롭게 사용할 수 있다는 장점이 있다.

function printArguments(...args) {
  // args 객체의 요소들을 하나씩 출력
  for (const arg of args) {
    console.log(arg);
  }
}


printArguments('Young', 'Mark', 'Koby');

 

 

rest parameter는 다른 일반 파라미터들과 함께 사용될 수도 있다.

 

function printRankingList(first, second, ...others) {
  console.log('코드잇 레이스 최종 결과');
  console.log(`우승: ${first}`);
  console.log(`준우승: ${second}`);
  for (const arg of others) {
    console.log(`참가자: ${arg}`);
  }
}

printRankingList('Tommy', 'Jerry', 'Suri', 'Sunny', 'Jack');

이름 그대로 앞에 정의된 이름 그대로 앞에 정의된 파라미터에 argument를 먼저 할당하고

나머지 argument를 배열로 묶는 역할을 하기 때문에

일반 파라미터와 함께 사용할 때는

반드시 가장 마지막에 작성해야 한다는 점을 유의해야한다.

 

 

6. Arrow Function

 

arrow function은 익명 함수를 좀 더 간결하게 표현할 수 있도록

ES2015에서 새롭게 등장한 함수 선언 방식이다.

 

즉, 모든 arrow function은 익명함수이다.

 

아래 코드와 같이 표현식으로 함수를 정의할 때 활용될 수도 있고

콜백 함수로 전달할 때 활용할 수도 있다.

 

방법은 먼저 1) function 키워드를 지워주고,

2) 소괄호() 오른편에 화살표 기호를 추가해준다.

const getTwice = function(number) {
  return number * 2;
};

myBtn.addEventListener('click', function() {
  console.log('button is clicked!');
});


// Arrow Function 적용 
const getTwice = (number) => {
  return number * 2;
};


myBtn.addEventListener('click', () => {
  console.log('button is clicked!');
});

 

화살표 함수는 다양한 상황에 따라 축약형으로 작성될 수 있다. 

 

// 1. 함수의 파라미터가 하나 뿐일 때
const getTwice = (number) => {
  return number * 2;
};

// 파라미터를 감싸는 소괄호 생략 가능
const getTwice = number => {
  return number * 2;
};

// 2. 함수 동작 부분이 return문만 있을 때
const sum = (a, b) => {
  return a + b;
};

// return문과 중괄호 생략 가능
const sum = (a, b) => a + b;


// 2번에서 리턴값이 객체일 때 
const getCodeit = () => {
	return { name : "Codeit",};
};

// 객체를 나타내는 {}를 함수의 동작 부분을 나타내는 중괄호로 해석해버리기에
// 이렇게 ()를 덧붙여줘야 에러가 뜨지 않는다.
const getCodeit = () => ({ name : "Codeit",});

1. 파라미터가 하나일 때 파라미터를 감싸는 소괄호 생략 가능

2. 함수 동작 부분이 return만 있을 때, return문과 중괄호 생략 가능

단, return 값이 객체일 때는 소괄호 추가해줘야함

 

※ Arrow function과 일반 함수와의 차이점

 

가장 대표적인 차이점은 arguments 객체가 없고,

this가 가리키는 값이 일반 함수와 다르다는 점이다.

 

arrow function에서 this 값은 일반함수에서

호출한 대상에 따라 상대적으로 변하는 게 아니라,

 

arrow fuction이 선언되기 직전에 유효한 this 값과

똑같은 값을 가지고 동작한다.
따라서 arrow function에서 this 값은 window 객체를 의미한다.

 

이런 특징 때문에 객체에서 메소드를 만들 때는 

일반함수를 사용하는 것을 권장한다.

 

 

 

7. this

웹 브라우저에서 this가 사용될 때는

전역 객체, Window 객체를 가지게 된다.

 

 

하지만 객체의 메소드를 정의하기 위한 함수 안에선

메소드를 호출한 객체를 가리키게 된다.

const user = {
  firstName: 'Tess',
  lastName: 'Jang',
  getFullName: function () {
    return `${this.firstName} ${this.lastName}`;
  },
};

console.log(user.getFullName()); // getFullName 안에서의 this는 getFullName을 호출한 user객체가 담긴다!

블로그의 정보

유명한 담벼락

담담이담

활동하기