TIL 06 | JavaScript 함수

41636 단어 JavaScriptJavaScript

function

function sum(x, y){ // 함수 선언할 때 선언된 변수 (매개 변수 = 파라미터)
  return x + y
}

const a = sum(1,3) // 함수가 호출될 때 들어가는 값 (인수 = 아규먼트)
const b = sum(4, 12)

console.log(a) // 4 === console.log(sum(1,3)) 
console.log(b) // 16 === console.log(sum(4,12))
console.log(a+b) // 20 === console.log(sum(1,3)+sum(4,12))

함수 호출이 반복적으로 필요할 시 변수를 사용하지 않으면 함수가 매번 실행되어 성능이 떨어질 수 있다. 함수를 만들때는 함수가 호출되는 횟수를 최소화하는 방향으로 코드를 작성해야한다.

파라미터

function greeting (name){
  console.log(`HI! My name is ${name}!`);
}

greeting(); // HI! My name is undefined!
//아규먼트가 전달되지 않을 때는 undefined가 출력된다. 
function greeting (name = 'Codeit'){ // 파라미터에 기본값 지정
  console.log(`HI! My name is ${name}!`);
}

greeting(); // HI! My name is Codeit, 아규먼트가 없을 때 기본값이 출력된다. 
function greeting (name = 'Codeit', interest){ 
  console.log(`HI! My name is ${name}!`);
  consoel.log(`I like ${interest}!`);
}

greeting('Javascript'); // HI! My name is Javascript! I like undefined!
// 아규먼트가 파라미터로 작동할 때에는 파라미터 기본값과는 상관 없이 함수 파라미터 순서대로 작동한다. 
// 따라서 기본값이 필요한 파라미터는 가급적 맨 오른편에 작성한다. 
function greeting (name = 'Codeit', interest = 'Javascript'){ // name 파라미터 기본값을 사용하고 싶다면?
  console.log(`HI! My name is ${name}!`);
  consoel.log(`I like ${interest}!`);
}

greeting(undefined,'Python'); // HI! My name is Codeit I like Python!
// 함수를 호출할 때 undeifined 값을 사용해서 파라미터의 기본값을 사용할 수도 있다. 
function defaultTest (x, y = x + 3){ // 파라미터의 기본값은 앞쪽의 파라미터를 활용할 수 있다. 
  console.log(`x: ${x}`);
  consoel.log(`y: ${y}`);
}

defaultTest(2)

01. 함수 선언

함수 선언시 함수 이름 지정, 함수 안에서 선언된 함수는 함수 밖에서 호출할 수 없지만 if나 for, while 문처럼 함수가 아닌 다른 코드블록에서 선언을 하면 전역적으로 호출이 가능하다.

function sum(x,y){}

02. 함수 표현

함수를 값으로 활용, 함수 표현식의 경우 할당된 변수에 따라 스코프가 정해진다.

const sum = function (x,y){}

03. 화살표 함수

화살표 함수는 기존의 함수 선언 방식을 좀 더 간결하게 만들어주는 문법이다. rest parameter를 사용한다거나 파라미터의 기본값을 지정하는 방식들은 기존의 함수와 똑같기 때문에 기존에 사용하던 함수 선언 방식들은 대부분 화살표 함수로 변환이 가능하다. 다만, 화살표 함수는 arguments 객체가 없기 때문에 arguments 객체를 활용하는 함수는 퐈살표 함수로 변환하기 가 어렵고 모든 화살표 함수는 익명함수라서 변수에 할당하거나 다른 함수를 호출할 때 아큐먼트로 사용된다.

// 함수 표현식
const double = function(x) {
  return x * 2
}
console.log('double: ', double(7)) 

// 화살표 함수
const doubleArrow =  x => x * 2
// 매개변수가 하나일 때는 x의 소괄호도 생략 가능, 매개변수가 둘 이상일 때는 (x, y) 소괄호가 필요하다.

const doubleArrow =  x => {return x * 2} // 실행문을 중괄호로 감싸면 반드시 return 필요
console.log('doubleArrow', doubleArrow(7))

const doubleArrow =  x => ({
  name : 'Heropy'
})// 객체 데이터 {} 의 경우 소괄호()로 한번 감싸면 축약형 화살표 함수로 표현 가능

 
const doubleArrow = x => {
  console.log(x) // 화살표 내부 return문 외 실행 코드가 있으면 축약형으로 표현 불가
  return x * 2
}

04. arguments 객체

함수 생성시 생성되는 유사배열 객체로 호출할 때 전달되는 아큐먼트에 따라 유연하게 동작하는 함수를 만들 수 있다. argument 객체는 인덱싱, length 프로퍼티, for of 문 등을 사용할 수 있지만 배열 메소드는 사용할 수 없다.

function printArguments(a,b,c){
  for (const arg of arguments){
    console.log(arg);
  }
}  

printArguments('Young', 'Mark', 'Koby'); // Young, Mark, Koby
printAguments('Captain'); // Captain
// 이렇게 arguments 객체를 사용하면 함수 호출 때 전달되는 argument 수에 따라 유연하게 동작하는 함수를 만들 수 있다. 


function sum(){
  console.log(arguments) // arguments 객체 안에 자동으로 배열 생성 [7,3]
  return arguments[0] + arguments[1]
}
console.log(sum(7,3))

05. Rest Parameter

arguments 객체를 이용하는 것 말고도 불규칙적으로 전달되는 아규먼트를 다루는 방법이 있는데 그 방법이 Rest Parameter를 이용하는 것이다. 파라미터 앞에 마침표 세 개를 붙여주면, 여러 개로 전달되는 아규먼트들을 배열로 다룰 수가 있게 된다. arguments객체는 유사 배열이기 때문에 배열의 메소드를 활용할 수 없는 반면, rest parameter는 배열이기 때문에 배열의 메소드를 자유롭게 사용할 수 있다는 장점이 있다.

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

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

Rest parameter를 일반 파라미터와 함께 사용할 때는 일반 파라미터와 함께 사용할 때는 반드시 가장 마지막에 작성해야 한다. 앞에 정의된 파라미터에 argument를 먼저 할당하고 나머지 argument를 배열로 묶는 역할을 하기 때문이다.

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');

06. 즉시 실행 함수 IIFE, Immediately-Invoked Function Expression

함수를 반복해서 사용할 필요가 없을 때, 만들자마자 바로 작동하는 함수를 만들 때 즉시 실행 함수를 활용한다.

// 선언 함수
const a = 7
function double(){
  console.log(a*2)
}
double(); // 여기에 세미콜론을 붙이지 않으면 에러가 발생한다. 엔진이 아래 즉시 실행 함수와 double 함수를 구분하지 못하기 때문

// 즉시 실행 함수 
(function (){
  console.log(a * 2)
}());

(function (){
  console.log(a * 2)
})();// 소괄호를 외부에 배치해도 작동한다. 

(function (x, y) {
  console.log(x + y);
})(3, 5); // 즉시 실행 함수도 일반 함수처럼 파라미터를 작성하고, 함수를 호출할 떄 아규먼트를 전달할 수 있다.

즉시 실행 함수는 함수에 이름을 지어주더라도 외부에서 재사용할 수 없다. 그래서 일반적으로 이름이 없는 익명함수를 사용한다. 다만, 함수 내부에서 자기 자신을 호출하는 재귀적인 구조를 만들고자 할 땐 이름이 필요하기도 하다.

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

sayHi(); // ReferenceError

(function countdown(n) {
  console.log(n);
  if (n === 0) {
    console.log('End!');
  } else {
    countdown(n - 1);
  }
})(5); // 재귀함수를 포함한 즉시 실행 함수 

즉시 실행 함수는 선언과 동시에 실행이 이뤄지기 때문에 일반적으로 프로그램 초기화 기능에 활용되거나 재사용이 필요 없는, 일회성 동작을 구성할 때 활용한다.

//함수의 리턴값을 바로 변수에 할당하고 싶을 때 사용되는 즉시 실행 함수
const firstName = Young;
const lastName = Kang;

const greetingMessage = (function () {
  const fullName = `${firstName} ${lastName} `;

  return `Hi! My name is ${fullName}`;
})();

07. 호이스팅(Hoisting)

함수 선언부가 유효범위 최상단으로 끌어올려지는 현상.
함수 표현 방식은 함수 호출이 상단에 오면 에러가 발생하지만 함수 선언 방식은 함수 호출이 함수 선언보다 우선해도 작동한다.

const a = 7

double();
const double = function(){
  console.log(a*2)
} // 함수 표현식 > TypeError

double();
function double(){
  console.log(a*2)
}// 함수 선언식, 호이스팅으로 인해 함수 호출이 에러 없이 작동

08. 타이머 함수

  • setTimeout(함수, 시간) : 일정 시간 후 함수 실행
  • setInterval(함수, 시간) : 시간 간격마다 함수 실행
  • clearTimeout() : 설정된 Timeout 함수를 종료
  • clearInterval() : 설정된 Interval 함수를 종료
// 3초 뒤에 함수 실행
const timer1 = setTimeout(function(){
  console.log('Heropy!')
},3000)// 시간 단위는 ms, 1000ms은 1초

// h1 태그를 클릭하면 함수 실행 종료
const h1El = document.querySelector('h1')

h1El.addEventListener('click',()=>{
  clearTimeout(timer1)
})

//3초 마다 함수 실행
const timer2 = setInterval(() => {
  console.log('Heropy!')
},3000)

// h1 태그를 클릭하면 인터벌 함수 실행 종료
h1El.addEventListener('click',()=>{
  clearInterval(timer2)
})

09. 콜백

함수의 인수로 사용되는 함수
ex. setTimeout(함수, 시간) => 여기서 인수로 들어가는 함수가 바로 콜백

// 요구사항 : timeout 함수가 실행된 뒤, Done을 출력한다.
function timeout(){
  setTimeout(() => {
    console.log('timeout')
  },3000)
}

timeout()
console.log('Done') // timeout()이 3초 뒤 실행되기 때문에 Done이 먼저 출력되는 일이 발생된다. 

// 콜백함수를 이용한 해결 방안
function timeout(cb){
  setTimeout(() => {
    console.log('timeout')
    cb()
  },3000)
}
// timeout 함수 안에 콜백 함수를 인수로 지정
timeout(()=>{
  console.log('Done')
}) // 콜백 함수가 매개변수 cb로 할당, timeout 함수 내에 cb() 함수 실행으로 문제 해결

좋은 웹페이지 즐겨찾기