일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- FE
- 패캠부트캠프
- 프로그래머스 JS 코테
- 국비지원
- 프론트엔드개발자
- 영상처리
- 프로그래머스코테
- 패스트캠퍼스
- 패스트캠퍼스부트캠프
- 자바스크립트
- 패캠
- 코딩테스트
- 자바스크립트 코딩테스트
- 미니 프로젝트
- 프로그래머스
- 개인프로젝트
- 깃허브
- 프론트엔드부트캠프
- Java
- 국비지원취업
- 부트캠프
- JS
- pokeapi
- 깃
- js코테
- 개발블로그
- 개발 프로젝트
- 프로젝트
- 딥러닝
- 프론트엔드
- Today
- Total
가쟤의 해변일기 🐳
[Javascript] 함수 본문
함수 선언문 (Declaration)
function hello () {
}
함수 표현식 (Expresstion)
const hello = function () {}
// 할당 연산자로 함수를 할당함.
hello() //호출
호이스팅이라는 개념에서 차이가 발생한다.
호이스팅 (Hoisting)
function hello() {
console.log('hello~')
}
hello()
// 호출하는 위치에 상관 없이 출력 됨. -> 아직 정의되지 않은 함수도 !
// 유효 범위 내에서 가장 상단으로 끌어올려 동작함.
→ 함수 선언문에서만 동작. 함수 표현식은 X
(자주 사용) 함수 선언문에서 호출 부분을 위에 적는 이유 :
추상적인 부분을 위쪽에 적어서 전체적 코드 흐름을 빠르게 파악하기 쉽게 하고
자세한 코드 내용(함수의 구현부)은 아래쪽에 위치하면 깔끔하게 작성할 수 있다.
매개변수 패턴 (parameter patten)
function getEmail({email = '이메일이 없습니다'}) {
return email
}
=(이퀄기호)로 기본값을 설정할 수 있다. (값이 없을 때 출력할 값)
const { email } = user // <- 구조분해 할당
function getEmail({ email }){} // 이렇게 바꿔줄 수 있다.
나머지 매개변수 (Rest parameter)
function sum(...rest) {
console.log(rest)
console.log(arguments) // 유사 배열 (Array-like) 배열이 아니라 reduce 못 씀
return rest.reduce(function(acc, cur) {
return acc + cur
}, 0) // 0 이 기본값
}
console.log(sum(1, 2)) // 3
console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) // 55
.reduce()는 배열 데이터의 item 개수만큼 콜백 함수를 실행한다.
acc : 값이 누적되는 파라미터 → 처음 반복할 땐 0 ( ,0 ← 기본값으로 설정해서)
cur : 현재 값 → 반복되는 첫 번째 값
return acc로 들어감 (두 번째 반복)
화살표 함수 (Arrow function)
function sum() {}
const sum = function() {}
const sum = () => {} // 이게 화살표 함수다!
const sum = (a, b) => a + b // { return a + b } 와 같다.
console.log(sum(1,2))
파라미터가 1개면 소괄호를 생략할 수 있다. (없거나 2개 이상이면 생략 불가능)
첫 번째 로직이 return 키워드로 시작하면 중괄호를 생략할 수 있다.
const a = () => ({a: 1})
객체 데이터면 중괄호라 잘못 해석되는 것을 방지하기 위해서 소괄호로 다시 묶어주면 데이터 취급!
즉시 실행 함수 (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()
이런 여러 형태로 즉시 실행 함수를 구현할 수 있다.
앞에 세미콜론을 붙이는 이유는 즉시 실행 함수의 바로 전 코드에서 세미콜론을 무조건 붙여줘야 정상 작동하기 때문이다.
콜백 (Callback)
const a = (callback) => { // 2. a 함수의 매개변수(callbak)은 b
console.log('a')
callback() // b 호출 (callback = b)
}
const b = () => {
console.log('b')
}
a(b) // 1. a 함수에 b를 매개변수로 설정
주석으로 코드 흐름 순서를 달아뒀다.
const sum = (a, b, c) =>{
setTimeout(() => {
c(a + b)
}, 1000)
}
sum(1, 2, (value) => {
console.log(value) // 다른 함수가 호출될 때 인수로 사용되는 함수
})
코드를 스스로 작성할 수 있을만큼 연습해야 할 것 같다. 아직은 로직 이해정도..?
1초 뒤에 파라미터 둘을 더한 값을 콘솔에 출력한다. 콜백함수를 활용해서 만든 함수다.
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)
})
새 이미지가 1초 뒤에 로드되는 함수다.
재귀(Recursive)
let i = 0
const a = () => {
console.log('A')
i += 1
if (i < 4) { // 멈출 수 있는 조건 추가
a()
}
}
a()
함수에서 자기 자신을 다시 내부에서 호출해 사용하는 방법이다.
0, 1, 2, 3 으로 총 4번 a가 콘솔에 출력된다. (if문이 console.log 이후에 작성되어 있음)
const userA = { name: 'A', parent: null }
const userB = { name: 'B', parent: userA }
const userC = { name: 'C', parent: userB }
const getRootUser = (user) => {
if (user.parent) {
return getRootUser(user.parent)
}
return user
}
console.log(getRootUser(userC))
이 코드를 보고 반복문이 생각났다.
반복문이 있는데 왜 이런 방식으로 사용하는거지?
재귀와 반복문의 차이를 알아보겠다.
일단, 반복문 만으로 풀기 어려운 문제가 있다고 한다. (DFS, DP, Combination 등)
### 반복문
- 명령을 반복 실행
- 초기화, 조건, 루프 내 명령문 실행과 제어 변수 업데이트 포함
- 설정한 조건 도달 시까지 반복 실행
- 무한 루프는 CPU 사이클을 반복적으로 사용
- 스택 메모리를 사용하지 않음
- 빠른 실행
- 코드 길이가 길어지고 변수가 많아져 가독성이 떨어짐
### 재귀함수
- 함수 자체를 호출
- 종료 조건만 지정 (조건이 추가될 수도 있음)
- 함수 호출 본문에 조건부가 포함, 재귀를 호출하지 않고 함수를 강제 반환
- 조건에 수렴하지 않을 경우 무한 재귀 발생
- 무한 재귀는 스택 오버플로우 발생
- 스택 메모리 사용 : 함수가 호출 될 때마다 새 로컬 변수와 매개 변수 집합, 함수 호출 위치를 저장하는데 사용
- 느린 실행
- 코드 길이와 변수가 적어 가독성이 좋음
이럼에도 재귀 함수를 사용하는 이유
- 알고리즘이 재귀적 표현이 더 자연스러울 경우 재귀함수 사용이 유용하다.
- 변수 사용을 줄일 수 있고 가독성이 향상된다.
호출 스케줄링 (Scheduling a function call)
const hello = () => {
console.log('hello~')
}
const timeout = setTimeout(hello, 1000)
const h1El = document.querySelector('h1')
h1El.addEventListener('click', () => {
console.log('clear!')
clearTimeout(timeout)
})
호출되는 시간을 조절할 수 있다.
clear로 호출되는 시간 전에 호출을 중지할 수도 있다.
this
const timer = {
title: 'TIMER!',
timeout: function () { // 일반 함수
console.log(this.title)
setTimeout(() => { // 화살표 함수
console.log(this.title)
}, 1000)
}
}
timer.timeout()
this는 함수에 따라 범위가 다르다.
일반 함수의 this는 호출 위치에서 정의하고, 화살표 함수의 this는 자신이 선언된 함수(렉시컬) 범위에서 정의한다.
'Front-end' 카테고리의 다른 글
[Javascript] 표준 내장 객체 - String, Number, Math, Date, 배열, 객체, JSON (0) | 2023.07.20 |
---|---|
[React] 리액트란? (0) | 2023.07.20 |
[Javascript] 클래스 - getter/setter, 정적 메소드, 상속 (0) | 2023.07.20 |
[Javascript] 연산자, 조건문, 반복문 (0) | 2023.07.18 |
[Javascript] 콜백 함수 - 콜백 체이닝, 콜백 헬 (0) | 2023.07.18 |