티스토리 뷰

WEB/JavaScript

[JavaScript] 함수

devOhzl 2023. 12. 13. 15:33

선언과 표현 , 호이스팅

📌 함수 선언문 ( Declaration )

function hello() { }

 

📌 함수 표현식 ( Expression )

변수의 이름을 지정하고, 할당 연산자를 통해 function 키워드로 시작하는 함수를 할당한다.

const hello = function() { }

 

📌 호이스팅 ( Hoisting )

함수의 선언부가 유효한 범위 안에서 제일 꼭대기로 끌어올려서 동작하는 현상

hello()			// hello

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

 

⭐ 호이스팅 현상은 함수 선언문에서만 발생하고 함수 표현에서는 발생하지 않는다.

hello()		// hello is not defined

const hello = function() {
  console.log('hello')
}

화살표 함수 ( Arrow function )

기존 function 키워드를 사용하는 함수보다 훨씬 더 단순하고 간결하게 함수 문법을 작성할 수 있다.

 

매개변수가 하나인 경우에는 소괄호 생략 가능

리턴 키워드가 함수 로직의 제일 처음에 시작이 된다면 중괄호 생략 가능

const a = () => {}
const b = x => {}
const c = (x,y) => {}
const d = x => { return x * x }
const e = x => x * x
const f = x => {
  console.log(x*x)
  return x*x
}

 

반환되는 값이 객체라면, 객체 데이터를 정확하게 알려주기 위해 소괄호로 묶어줘야 한다.

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

즉시실행함수 ( IIFE )

함수의 이름 없이 익명 함수로 내용을 만들고 바로 실행을 할 수 있다.

위에서 작성되고 있는 코드와 겹칠 수 있으므로 앞에 세미콜론을 붙이고 실행한다.

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

 

1️⃣ (F)()

;(() => {})()
;(() => { console.log('hello') })()

 

⭐ function 키워드를 사용하는 일반 함수를 사용하면 다양한 패턴으로 즉시실행함수를 만들 수 있다.

2️⃣ (F)()

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

3️⃣ (F())

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

4️⃣ !F()

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

5️⃣ +F()

 

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

 

👉 두 번째 소괄호로 들어가는 각각의 데이터들을 매개변수로 전달할 수 있다.

;((a,b) => { 
  console.log(a)
  console.log(b)
})(1,2)

콜백 ( Callback )

다른 함수가 실행될 때 그 함수 호출에 인수로 사용되는 하나의 함수

우리가 해당하는 내용을 정확하게 필요한 위치에서 실행할 수 있다.

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

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

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

sum(1,2, value => { 
  console.log(value)   // 3
})

 

ex) callback을 활용한 이미지 로드 기다리기

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('http://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()	// 'A', 'A', 'A', 'A'

호출 스케줄링

함수의 호출을 지연하거나 반복적으로 호출할 수 있도록 만들어준다.

 

📌setTimeout

사용하고자 하는 특정한 함수의 실행 시간을 지연할 수 있다.

const hello = () => {
  console.log('hello')
}
setTimeout(hello, 2000)

 

📌clearTimeout

호출 스케줄을 종료할 수 있다.

const hello = () => {
    console.log('hello')
}
const timeout = setTimeout(hello, 2000)
const h1El = document.querySelector('h1')
h1El.addEventListener('click', () => {
    clearTimeout(timeout)
})

 

📌setInterver

특정한 함수를 반복적으로 실행한다.

const hello = () => {
  console.log('hello')
}
setInterver(hello, 2000)

 

📌clearInterver

호출 스케줄을 종료할 수 있다.

const hello = () => {
    console.log('hello')
}
const timeout = setInterval(hello, 2000)
const h1El = document.querySelector('h1')
h1El.addEventListener('click', () => {
    console.log('clear!')
    clearInterval(timeout)
})

this

📌 일반 함수this는 호출 위치에서 정의

this → 현재 getFullName 속성이 들어있는 객체이므로 다른 속성에 접근할 수 있다.

const user = {
  firstName: 'Aeri',
  lastName: 'Kim',
  age: 25,
  getFullName: function() {
    return `${this.firstName} ${this.lastName}`
  }
}

console.log( user.getFullName() )	// Aeri Kim

 

📌 화살표 함수this는 자신이 선언한 함수 범위에서 정의

this → 자신이 선언된 함수를 감싸고 있는 외부의 또 다른 함수가 기준이 된다.

const user = {
  firstName: 'Aeri',
  lastName: 'Kim',
  age: 25,
  getFullName: () => {
    return `${this.firstName} ${this.lastName}`
  }
}

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

 

📌 화살표 함수의 this는 감싸고 있는 외부 함수를 참조하므로 user 함수의 this.firstName/this.lastName을 참조한다.

일반 함수의 this는 호출 위치를 참조하므로 return 한 객체의 firstName, lastName을 참조한다.

function user() {
  this.firstName = 'Neo'
  this.lastName = 'Choi'
  
  return {
    firstName: 'Aeri',
    lastName: 'Kim',
    age: 25,
    getFullName1: function () {
      return `${this.firstName} ${this.lastName}`
    },
    getFullName2: () => {
      return `${this.firstName} ${this.lastName}`
    }
  }
}

const u = user()
console.log( u.getFullName1() )	// 'Aeri Kim'
console.log( u.getFullName2() )	// 'Neo Choi'

 

📌 일반 함수는 this라는 키워드를 호출 위치에서 정의하기 때문에 

객체 데이터가 가지고 있는 특정한 메소드를 다른 객체 데이터가 빌려와서 사용할 수 있다.

function user() {
  return {
    firstName: 'Aeri',
    lastName: 'Kim',
    age: 25,
    getFullName: function () {
      return `${this.firstName} ${this.lastName}`
    }
  }
}

const lewis = {
  firstName: 'Lewis',
  lastName: 'Yang'
}
const u = user()
console.log( u.getFullName() )			// 'Aeri Kim'
console.log( u.getFullName.call(lewis) )	// 'Lewis Yang'

 

특정한 함수 내부에서 this 키워드를 반복적으로 쓸 때

함수 내부에 또 다른 함수가 들어있는 구조라면 화살표 함수를 사용하는 것이 더 적합하다.

const timer = {
  title: 'TIMER !',
  timeout1: function () {
    setTimeout(function (){
      console.log(this.title)
    }, 1000)
  },
  timeout2: function () {
    setTimeout(() => {
      console.log(this.title)
    }, 1000)
  }
}

timer.timeout1()	// undefined
timer.timeout2()	// 'TIMER !'

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
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 31
글 보관함