JavaScript 함수

현성·2023년 11월 28일
0

😃 함수 (Function)

👉 함수 선언문(Declaration)

function hello() {}

👉 함수 표현식(Expression)

const hello = function () {}

함수 선언문과 함수 표현식은 호이스팅(Hoisting)이라는 개념에서 차이가 발생합니다.

  • JavaScript 호이스팅은 인터프리터가 코드를 실행하기 전에 함수, 변수, 클래스 또는 임포트(import)의 선언문을 해당 범위의 맨 위로 이동시키는 과정을 말합니다.
    이러한 호이스팅은 함수 표현식에서는 동작하지 않고 함수 선언문에서만 동작합니다.

  • 예제
hello(); // Hello~

function hello() {
  console.log('Hello~')
}
hello(); // error

const hello = function () {
  console.log("Hello~");
};

👉 반환 및 종료

  • 반환
function hello() {
  return 'Hello~'
}

console.log(hello()) // Hello~

  • 종료
function hello() {
  return 'Hello~'
  console.log('Wow!')
}

// return 키워드 밑의 코드는 작동하지 않습니다.
console.log(hello()) // Hello~

  • 예제
function plus(num) {
  if (typeof num !== 'number') {
    console.log('숫자를 입력해주세요!')
    return 0;
  }
  return num + 1;
}

console.log(plus(2)); // 3
console.log(plus(7)); // 8
console.log(plus()); // 숫자를 입력해주세요! 0

👉 매개변수 패턴 (Parameter pattern)

  • 매개변수에 = 기호를 사용하여 기본값을 할당해줄 수 있습니다.
function sum(a, b = 3) {
  return a + b;
}

console.log(sum(1, 2)) // 3
console.log(sum(7)) // 10

  • 구조 분해 할당 (객체)
const user = {
  name: 'AA',
  age: 20,
}

function getName({ name }) {
  return name;
}

function getEmail({ email = '이메일이 없습니다.' }) {
  return email;
}

console.log(getName(user)); // AA
console.log(getEmail(user)); // 이메일이 없습니다.

  • 구조 분해 할당 (배열)
const fruits = ['Apple', 'Banana', 'Cherry']
const numbers = [1, 2, 3, 4, 5, 6, 7];

function getSecondItem([, b]) {
  return b;
}

console.log(getSecondItem(fruits)) // Banana
console.log(getSecondItem(numbers)) // 2

  • 나머지 매개변수 (Rest parameter)
function sum(...rest) {
  return rest.reduce(function (acc, cur) {
    return acc + cur;
  }, 0);
}

console.log(sum(1, 2)); // 3
console.log(sum(1, 2, 3, 4)); // 10
console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); // 55

💡 argument들을 나머지 매개변수 개념을 사용하여 배열로 가져올 때, 이와 비슷한 방식으로 함수 내부에서 사용가능한 객체 arguments를 사용할 수 있습니다. 하지만 arguments객체는 배열과 비슷하지만 배열의 메소드를 사용할 수 없는 유사배열이기 때문에 우리가 원하는 동작의 함수를 구현하기에는 활용도가 떨어집니다.


👉 화살표 함수 (Arrow function)

function sum() {}

const sum = function () {}

const sum = () => {}

  • 예제
const sum = (a, b) => {
  return a + b;
}

console.log(sum(1, 2)) // 3
console.log(sum(10, 20)) // 30
const sum = (a, b) => a + b;

console.log(sum(1, 2)) // 3
console.log(sum(10, 20)) // 30
const a = () => {}

const b = x => {} // 파라미터가 하나인 경우 소괄호는 생략가능합니다.

const c = (x, y) => {} // 파라미터가 두 개 이상인 경우 소괄호를 생략할 수 없습니다.

const d = x => { return x * x }

const e = x => x * x // 함수 d, e는 같은 함수입니다.

const f = x => {
  console.log(x * x)
  return x * x
} // return 키워드가 먼저 나오지 않는 경우 중괄호를 생략할 수 없습니다.

const g = () => { return { a: 1 } }

const h = () => { a: 1 } // 함수 g를 함수 h와 같이 작성하는 것은 JavaScript문법에 맞지 않습니다.

const i = () => ({ a: 1}) // 이 함수는 g와 같은 함수입니다.

const j = () => { return [1, 2, 3]}

const k = () => [1, 2, 3] // 이 함수는 j와 같은 함수입니다.

👉 즉시 실행 함수 (IIFE, Immediately-Invoked Function Expression)

const a = 7

const double = () => {
  console.log(a * 2);
}

double(); // 14

(() => {
  console.log(a * 2)
})()  // 14
(() => {})();       // (F)()
(function () {})(); // (F)()
(function () {}()); // (F())
!function () {}();  // !F()
+function () {}();  // +F()
const a = 7;

(() => {console.log(a * 2)})();        // 14
(function () {console.log(a * 2)})();  // 14
(function () {console.log(a * 2)}());  // 14
!function () {console.log(a * 2)}();   // 14
+function () {console.log(a * 2)}();   // 14
((a, b) => {
  console.log(a);
  console.log(b);
})(1, 2); // 1 2

👉 콜백 (Callback)

함수가 실행될 때 인수로 들어가는 또 하나의 함수를 콜백이라고 합니다.


  • 예제
const a = callback => {
  console.log('A')
  callback()
}

const b = () => {
  console.log('B')
}

a(b) // A B
const a = callback => {
  callback()
  console.log('A')
}

const b = () => {
  console.log('B')
}

a(b) // B A
const sum = (a, b, c) => {
  setTimeout(() => {
    c(a + b);
  }, 1000);
};

sum(1, 2, (value) => {
  console.log(value);
}); // 1초 뒤에 3 출력

  • 이미지를 불러오는 예제
const loadImage = (url, cb) => {
  const imgEl = document.createElement("img");
  imgEl.src = url;
  imgEl.addEventListener("load", () => {
    setTimeout(() => {
      cb(imgEl);
    }, 1000);
  });
};

const containerEl = document.querySelector(".container");
loadImage("https://www.gstatic.com/webp/gallery/4.jpg", (imgEl) => {
  containerEl.innerHTML = "";
  containerEl.append(imgEl);
});

👉 재귀 (Recursive)

재귀란 함수 안에 같은 함수가 다시 호출되는 함수를 의미합니다.


  • 예제
let i = 0;
const a = () => {
  console.log("A");
  i += 1;
  if (i < 4) {
    a();
  }
};

a();
const userA = { name: "A", parent: null };
const userB = { name: "B", parent: userA };
const userC = { name: "C", parent: userB };
const userD = { name: "D", parent: userC };

const getRootUser = (user) => {
  if (user.parent) {
    return getRootUser(user.parent);
  }
  return user;
};

console.log(getRootUser(userD));

👉 호출 스케줄링 (Scheduling a function call)

const hello = () => {
  console.log("Hello ~");
};

const timeout = setTimeout(hello, 2000);
const h1El = document.querySelector("h1");
h1El.addEventListener("click", () => {
  console.log("Clear!");
  clearTimeout(timeout);
});
// 2초 후에 Hello~ 출력, h1태그 클릭 시 스케줄 종료

clearTimeoutsetTimeout으로 정해진 스케줄을 종료시키는 함수입니다.


const hello = () => {
  console.log("Hello ~");
};

const timeout = setInterval(hello, 2000);
const h1El = document.querySelector("h1");
h1El.addEventListener("click", () => {
  console.log("Clear!");
  clearInterval(timeout);
});
// 2초마다 Hello~ 출력, h1태그 클릭 시 스케줄 종료

⭐️ this

this라는 키워드는 앞으로 자주 마주하게 될 용어입니다.
일반 함수의 this는 호출 위치에서 정의되고, 화살표 함수의 this는 자신이 선언된 함수(렉시컬) 범위에서 정의됩니다.

  • 예제
const user = {
  firstName: "AA",
  lastName: "BB",
  age: 20,
  getFullName: function () {
    return `${this.firstName} ${this.lastName}`;
  },
};

console.log(user.getFullName()); // AA BB

위의 코드의 getFullName을 화살표 함수로 바꾸게 되면 아래와 같이 undefined가 출력이 됩니다.

const user = {
  firstName: "AA",
  lastName: "BB",
  age: 20,
  getFullName: () => {
    return `${this.firstName} ${this.lastName}`;
  },
};

console.log(user.getFullName()); // undefined undefined

화살표 함수에서 this키워드를 사용하려면 그 함수를 감싸고 있는 상위의 함수가 필요합니다.

function user() {
  this.firstName = "Neo";
  this.lastName = "Anderson";

  return {
    firstName: "AA",
    lastName: "BB",
    age: 20,
    getFullName: () => {
      return `${this.firstName} ${this.lastName}`;
    },
  };
}

const u = user();
console.log(u.getFullName()); // Neo Anderson

getFullNamecall 메소드를 통해 다른 객체에서 this를 사용할 수 있습니다.

  • 예제
function user() {
  this.firstName = "Neo";
  this.lastName = "Anderson";

  return {
    firstName: "AA",
    lastName: "BB",
    age: 20,
    getFullName: function () {
      return `${this.firstName} ${this.lastName}`;
    },
  };
}

const lewis = {
  firstName: "Lewis",
  lastName: "Yang",
};

const u = user();
console.log(u.getFullName()); // AA BB
console.log(u.getFullName.call(lewis)); // Lewis Yang
const timer = {
  title: "TIMER!",
  timeout: function () {
    console.log(this.title);
    setTimeout(() => { // 함수 선언식으로 작성하면 undefined 출력
      console.log(this.title);
    }, 1000);
  },
};

timer.timeout();
profile
👈🏻 매일 꾸준히 성장하는 개발자 !

0개의 댓글