[TIL] JavaScript : Function

AcidΒ·2021λ…„ 8μ›” 5일
0

πŸ“’ JavaScript

λͺ©λ‘ 보기
2/8
post-thumbnail

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ ν•¨μˆ˜(function)의 λ‹€μ–‘ν•œ μ •μ˜ 방법과 μ‹€ν–‰, μ‚¬μš© 이유 등에 λŒ€ν•œ λ‚΄μš©μž…λ‹ˆλ‹€. 😊

πŸ“’ μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ ν•¨μˆ˜λž€?

ν”„λ‘œκ·Έλž˜λ°μ—μ„œ ν•¨μˆ˜(function)λž€ ν•˜λ‚˜μ˜ νŠΉλ³„ν•œ λͺ©μ μ˜ μž‘μ—…μ„ μœ„ν•΄ λ…λ¦½μ μœΌλ‘œ μ„€κ³„λœ ν”„λ‘œκ·Έλž¨ μ½”λ“œμ˜ 집합이라고 μ •μ˜ν•  수 μžˆλ‹€.

ν•΄λ‹Ή μ •μ˜λ₯Ό μ΄λ―Έμ§€λ‘œ ν‘œν˜„ν•˜λ©΄,

μœ„μ™€ 같이 ν‘œν˜„λ  수 μžˆλŠ”λ°, μ΄λ―Έμ§€μ—μ„œ λ‚˜μ˜¨ νŠΉμ • μž…λ ₯ 값이 νˆ¬μž…λ˜λ©΄ ν•¨μˆ˜λ₯Ό 거쳐 μƒˆλ‘œμš΄ 좜λ ₯ 값을 λ°˜ν™˜ν•˜λŠ” 것과 같은 역할을 ν•˜λŠ” 것이닀.

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ ν•¨μˆ˜λŠ” 일급 객체둜 μ·¨κΈ‰λœλ‹€.

πŸ’‘ 일급(first-class) κ°μ²΄λž€

λ‹€λ₯Έ 객체듀에 일반적으둜 적용 κ°€λŠ₯ν•œ 연산을 λͺ¨λ‘ μ§€μ›ν•˜λŠ” 객체λ₯Ό 가리킨닀. 일급 객체λ₯Ό μœ„ν•œ 쑰건은 λ‹€μŒκ³Ό κ°™λ‹€.

  • λ³€μˆ˜(variable)에 담을 수 μžˆλ‹€.
  • 인자(parameter)둜 전달할 수 μžˆλ‹€.
  • λ°˜ν™˜ κ°’(return value)으둜 전달할 수 μžˆλ‹€.

πŸ”– 좜처

1κΈ‰ 객체 : μœ„ν‚€λ°±κ³Ό 일급 객체
1κΈ‰ 객체 : μ΅œμ •λ ¬λ‹˜ github.io


μœ„ 일급 객체에 λŒ€ν•œ μ„€λͺ…μ—μ„œ λ‚˜μ˜¨ λ³€μˆ˜μ™€ 인자 그리고 λ°˜ν™˜ 값에 λŒ€ν•œ λ‚΄μš©μ΄ μ΄μ–΄μ§€λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ ν•¨μˆ˜μ˜ μ‚¬μš©λ²•μ—μ„œ 닀뀄진닀.

βš™οΈ ν•¨μˆ˜(function) μ‚¬μš©λ²•

ν•¨μˆ˜λ„ λ³€μˆ˜κ°€ μ„ μ–Έκ³Ό ν• λ‹Ήμ˜ 과정이 μžˆλ“―μ΄, λ§ˆμ°¬κ°€μ§€λ‘œ ν•¨μˆ˜λŠ” μ •μ˜μ™€ μ‹€ν–‰μ˜ 과정이 μžˆλ‹€.

ν•¨μˆ˜μ˜ μ •μ˜

ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜λŠ” λ‹€μŒκ³Ό 같은 방법듀이 μžˆλ‹€.

  • ν•¨μˆ˜ μ„ μ–Έλ¬Έ
  • ν•¨μˆ˜ ν‘œν˜„μ‹
  • ν™”μ‚΄ν‘œ ν•¨μˆ˜ ν‘œν˜„μ‹


μš°μ„  ν•¨μˆ˜ 선언문은 일반적인 ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œ ν•¨μˆ˜ μ„ μ–Έκ³Ό λΉ„μŠ·ν•œ ν˜•μ‹μœΌλ‘œ κ°€μž₯ 기본적인 방법이닀.

function functionName(parameter) {
	statements
}


μœ„ κ΅¬λ¬Έμ—μ„œ λ³΄μ΄λŠ” 바와 같이, function 을 μž‘μ„±ν•˜κ³  ν•¨μˆ˜ 이름(functionName)을 μž‘μ„±ν•œ 뒀에 μ†Œκ΄„ν˜Έ(()) μ•ˆμ— λ§€κ°œλ³€μˆ˜(parameter)의 이름을 μž‘μ„±ν•œλ‹€. 그리고 μ€‘κ΄„ν˜Έλ₯Ό μ—΄μ–΄ ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν–ˆμ„ λ•Œ μž‘λ™λ˜κ³ μž ν•˜λŠ” ꡬ문(statements)을 μž‘μ„±ν•œλ‹€.


ν•¨μˆ˜ ν‘œν˜„μ‹μ€ ν•¨μˆ˜ μ„ μ–Έμ‹μ˜ ꡬ문과 λΉ„μŠ·ν•˜μ§€λ§Œ λ³€μˆ˜ 값에 ν•¨μˆ˜λ₯Ό μ €μž₯ν•˜λŠ” ν˜•νƒœμ˜ ꡬ문을 κ°–λŠ”λ‹€.

let functionExpression = function functionName(parameter) {
	statements
}

λ³΄μ΄λŠ” 바와 같이 ν•¨μˆ˜ μ„ μ–Έλ¬Έκ³Ό λΉ„μŠ·ν•œ ν˜•μ‹μ΄μ§€λ§Œ λ³€μˆ˜(functionExpression)λ₯Ό μ„ μ–Έν•˜μ—¬ ν•΄λ‹Ή λ³€μˆ˜μ˜ κ°’μœΌλ‘œ ν•¨μˆ˜(fucntionName)λ₯Ό ν• λ‹Ήν•œλ‹€.

μœ„μ™€ 같이 ꡬ문 μž‘μ„± λ°©μ‹μ˜ 차이가 있기 λ•Œλ¬Έμ—, 두 방식은 차이점이 μ‘΄μž¬ν•œλ‹€. κ·Έ 차이점은 ν˜Έμ΄μŠ€νŒ…κ³Ό κ΄€λ ¨λœ 사항인데, ν˜Έμ΄μŠ€νŒ… κ΄€λ ¨ λ‚΄μš©μ€ 이전 μžλ°”μŠ€ν¬λ¦½νŠΈ 기본에 λŒ€ν•œ ν¬μŠ€νŠΈμ— κΈ°μž¬ν–ˆμœΌλ‹ˆ κΈ°μ–΅ μ•ˆλ‚˜λ©΄ λ‹€μ‹œ λ³΄λŠ”κ±Έλ‘œ!

πŸ’‘ ν•¨μˆ˜ μ„ μ–Έλ¬Έκ³Ό ν•¨μˆ˜ ν‘œν˜„μ‹μ˜ 차이점

κ°„λ‹¨νžˆ λ§ν•˜μžλ©΄, ν•¨μˆ˜ 선언문은 ν˜Έμ΄μŠ€νŒ…μ— 영ν–₯을 λ°›κ³ , ν•¨μˆ˜ ν‘œν˜„μ‹μ€ ν˜Έμ΄μŠ€νŒ…μ— 영ν–₯을 받지 μ•ŠλŠ”λ‹€!

ν•΄λ‹Ή λ‚΄μš©μ„ μ˜ˆμ‹œλ₯Ό ν™œμš©ν•˜μ—¬ μ•Œμ•„λ³΄μž

// ν•¨μˆ˜ μ„ μ–Έλ¬Έ
sayHello(); // output : hello
function sayHello(parameter) {
	console.log('hello')
}
// ν•¨μˆ˜ ν‘œν˜„μ‹
sayHello(); // ReferenceError: sayHello is not defined
let functionExpression = function sayHello(parameter) {
	console.log('hello')
}


μœ„ 두 가지 ꡬ문은 κ³΅ν†΅μ μœΌλ‘œ ν•¨μˆ˜ μ‹€ν–‰ 이후 선언이 μ΄λ£¨μ–΄μ§€λŠ” ν˜•νƒœμ΄λ‹€.

κ·ΈλŸ¬λ‚˜ ν•¨μˆ˜ μ„ μ–Έλ¬Έμ˜ κ²½μš°μ—λ§Œ μ •μƒμ μœΌλ‘œ ν•¨μˆ˜ 싀행이 μž‘λ™ν•˜λŠ” κ²°κ³Όλ₯Ό 확인할 수 μžˆλ‹€.

μ΄λŠ” μœ„μ—μ„œ μ–ΈκΈ‰ν•œ 바와 같이 ν˜Έμ΄μŠ€νŒ…μ΄ ν•¨μˆ˜ μ„ μ–Έλ¬Έμ˜ κ²½μš°μ—λ§Œ μΌμ–΄λ‚˜κΈ° λ•Œλ¬Έμ΄λ‹€.

λ³€μˆ˜λŠ” varλŠ” ν˜Έμ΄μŠ€νŒ…μ΄ μΌμ–΄λ‚˜κΈ° λ•Œλ¬Έμ— ν•΄λ‹Ή 방법을 μ§€μ–‘ν•˜κ³  letκ³Ό const 방식을 지ν–₯ν•΄μ•Ό ν–ˆλ‹€.

λ§ˆμ°¬κ°€μ§€λ‘œ, ν•¨μˆ˜λ„ ν˜Έμ΄μŠ€νŒ…μœΌλ‘œ 인해 μŠ€μ½”ν”„κ°€ 꼬이고 문제 λ°œμƒμ— λŒ€ν•œ μ •ν™•ν•œ 원인 뢄석이 μ–΄λ €μ›Œμ§€λŠ” 문제점 등이 λ°œμƒν•˜κΈ° λ•Œλ¬Έμ—, λŒ€μ²΄μ μœΌλ‘œ ν•¨μˆ˜ ν‘œν˜„μ‹μ„ 지ν–₯ν•œλ‹€!


μ΄μ–΄μ„œ ν™”μ‚΄ν‘œ ν•¨μˆ˜(Arrow function)λŠ” 문법에 λ“€μ–΄κ°€λŠ” => ν•΄λ‹Ή 뢀뢄이 마치 ν™”μ‚΄ν‘œ κ°™μ•„μ„œ 이름 지어진 ν•¨μˆ˜ μ •μ˜ 방식이닀. ν™”μ‚΄ν‘œ ν•¨μˆ˜μ˜ 문법은 λ‹€μŒκ³Ό κ°™λ‹€.

let arrowFunc = (parameter) => {
	console.log('Hi')
}

arrowFunc() // output : Hi


λ˜ν•œ, μ•žμ˜ 두 가지 λ°©μ‹κ³ΌλŠ” λ‹€λ₯΄κ²Œ ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” ꡬ문이 짧고, this의 바인딩 λ°©μ‹μ—μ„œ 일반 ν•¨μˆ˜μ™€ κ΅¬λΆ„λœλ‹€.

πŸ’‘ 일반 ν•¨μˆ˜μ™€ ν™”μ‚΄ν‘œ ν•¨μˆ˜μ˜ 차이

this 에 λŒ€ν•œ κ°„λ‹¨ν•œ 이해


this λ₯Ό κ°„λ‹¨ν•˜κ²Œ μ„€λͺ…ν•˜μžλ©΄, ν˜„μž¬ μ‹€ν–‰ν•˜κ³  μžˆλŠ” λ¬Έλ§₯이 무엇인가에 λŒ€ν•œ λ‚΄μš©μ΄λ‹€.

λˆ„κ°€ ν˜ΈμΆœν–ˆλŠλƒμ— λŒ€ν•œ λ‚΄μš©μ΄ μ€‘μš”ν•œ 뢀뢄인데, λΈŒλΌμš°μ € μ½˜μ†”μ„ κΈ°μ€€μœΌλ‘œ 기본은 window λ‹€.

// in browser
console.log(this); // output : window
// strict λͺ¨λ“œμΌ 경우, undefined 라고 ν•œλ‹€.

μ΄λŸ¬ν•œ this 객체 μ•ˆμ—μ„œλŠ” κ²°κ³Ό 값이 달라진닀.

var obj = {
  a: function() { console.log(this); },
};
obj.a(); // obj
var a2 = obj.a;
a2(); // window

μ΄λŠ” 객체 λ©”μ„œλ“œ 호좜 μ‹œ, this λ₯Ό λ‚΄λΆ€μ μœΌλ‘œ λ°”κΎΌλ‹€κ³  ν•œλ‹€.

κ·ΈλŸ¬λ‚˜ μ•„λž˜μ˜ κ²½μš°μ—λŠ” window κ°€ 좜λ ₯λœλ‹€. μ™œλƒν•˜λ©΄ μ•„λž˜μ˜ κ²½μš°μ—λŠ” λ³€μˆ˜μ— 값을 μ €μž₯ν•œ μˆœκ°„ 객체의 λ©”μ„œλ“œκ°€ μ•„λ‹Œ 일반적인 ν•¨μˆ˜κ°€ λ˜μ—ˆκΈ° λ•Œλ¬Έμ— 더 이상 obj 의 λ©”μ„œλ“œκ°€ μ•„λ‹Œ 것이닀.

μ΄λ ‡κ²Œ μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ this λŠ” 정적인 것이 μ•„λ‹Œ 동적인 쑴재둜 여겨진닀. μ΄λŠ” 일반 ν•¨μˆ˜μ˜ thisκ°€ 동적 μŠ€μ½”ν”„(dynamic scope)에 ν•΄λ‹Ήν•œλ‹€κ³  ν•  수 μžˆλ‹€.

κ·ΈλŸ¬λ‚˜ this λŠ” 동적 μŠ€μ½”ν”„κ°€ μ•„λ‹Œ 정적 μŠ€μ½”ν”„(lexical scope)의 thisλ₯Ό κ°–λŠ”λ°, μ΄λŸ¬ν•œ λΆ€λΆ„μ—μ„œ 차이점을 가지며 바인딩 방식에 차이λ₯Ό 보인닀.

동적 μŠ€μ½”ν”„μ™€ 정적 μŠ€μ½”ν”„μ— λŒ€ν•œ λ‚΄μš©μ€ μ•„λž˜ κ°„λ‹¨νžˆ μ„€λͺ…ν•  κ²ƒμ΄λ―€λ‘œ ν•„μš” ν•˜μ— λͺ©μ°¨λ₯Ό 눌러 μ΄λ™ν•˜μž!(ν•΄λ‹Ή λ‚΄μš©μ΄ λ„ˆλ¬΄ κΈΈμ–΄μ Έ λ³„λ„λ‘œ μž‘μ„± πŸ˜‚)

바인딩(binding) λ°©μ‹μ˜ 차이


멀고도 λ¨Ό κΈΈμ΄μ—ˆλ‹€. 이제 λ°”μΈλ”©μ˜ 차이에 λŒ€ν•΄ μ•Œμ•„λ³΄μž.

동적 μŠ€μ½”ν”„μ™€ 정적 μŠ€μ½”ν”„μ— λŒ€ν•œ 이해λ₯Ό λ§ˆμ³€λ‹€λŠ” μ „μ œ ν•˜μ— κ°„λ‹¨νžˆ μ„€λͺ…ν•˜μžλ©΄, ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” ν•¨μˆ˜ 선언을 ν•  λ•Œthis 에 λ°”μΈλ”©ν•˜λŠ” 객체가 μ •μ μœΌλ‘œ κ²°μ •λœλ‹€λŠ” 점이닀. 이 말은 ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” μ–Έμ œλ‚˜ μƒμœ„ μŠ€μ½”ν”„μ˜ this λ₯Ό κ°€λ¦¬ν‚¨λ‹€λŠ” 것이닀.

μ˜ˆμ‹œ μ½”λ“œλ₯Ό λ³΄λ©΄μ„œ ν•΄λ‹Ή λ‚΄μš©μ„ μ΄ν•΄ν•΄λ³΄μž.

function Person(){
  this.age = 0;
  setInterval(() => {
    this.age++; // thisλŠ” Person 객체λ₯Ό μ°Έμ‘°
    console.log(this.age);
  }, 1000); // output : 1... 2... 3...
}
var p = new Person();

콜백 ν•¨μˆ˜(callback function)에 λŒ€ν•œ λ‚΄μš©μ€ μž μ‹œ 미뀄두고 μŠ€μ½”ν”„μ— λŒ€ν•œ λ‚΄μš©μ— μ§‘μ€‘ν•˜μžλ©΄, μœ„μ™€ 같은 μƒν™©μ—μ„œ setInterval() ν•¨μˆ˜μ˜ this λŠ” μƒμœ„ μŠ€μ½”ν”„μΈ Person의 객체λ₯Ό μ°Έμ‘°ν•˜μ—¬ ν•΄λ‹Ή 값인 0 을 μ‚¬μš©ν•œλ‹€.

μœ„μ—μ„œ 잠깐 μ–ΈκΈ‰ν•œ 바와 같이, ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” κ°„λ‹¨ν•˜κ²Œ ν•¨μˆ˜ ꡬ문을 μž‘μ„±ν•  수 μžˆλ‹€λŠ” μž₯점과 μ•žμ—μ„œ μ΄ν•΄ν•œ this의 바인딩 λΆ€λΆ„μ—μ„œ μƒμœ„μ˜ 객체λ₯Ό μ°Έμ‘°ν•  수 μžˆλ‹€λŠ” 점이 콜백 ν•¨μˆ˜λ₯Ό μž‘μ„±ν•˜λŠ” 데에 μš©μ΄ν•˜λ‹€.

이와 κ΄€λ ¨λ˜μ–΄ 콜백 ν•¨μˆ˜μ— κ΄€λ ¨λœ λ‚΄μš©κ³Ό ν™”μ‚΄ν‘œ ν•¨μˆ˜λ‘œ λŒ€μ²΄ κ°€λŠ₯ν•œ κ²½μš°μ— λŒ€ν•œ λ‚΄μš©μ€ λ³„λ„λ‘œ ν¬μŠ€νŒ…μ„ ν•  μ˜ˆμ •μ΄λ‹€. πŸ‘Š

πŸ”– 좜처

this : μ œλ‘œμ΄ˆλ‹˜ κ°œμΈλΈ”λ‘œκ·Έ : μžλ°”μŠ€ν¬λ¦½νŠΈ thisλŠ” 무엇인가?
Arrow Function Binding : Nesoy Blog : Javascript Arrow functionκ³Ό Binding에 λŒ€ν•΄

πŸ’‘ Lexical Scope와 Dynamic Scope

Lexical Scope λŠ” λ³€μˆ˜λ‚˜ ν•¨μˆ˜κ°€ μ„ μ–Έλœ 곳의 λ‚΄μš© μ‚¬μš©ν•œλ‹€λŠ” 의미이고, Dynamic Scope λŠ” λ³€μˆ˜λ‚˜ ν•¨μˆ˜κ°€ 호좜된 곳의 λ‚΄μš© μ‚¬μš©ν•œλ‹€λŠ” 의미λ₯Ό κ°–λŠ”λ‹€.

ν•΄λ‹Ή λ‚΄μš©μ€ μ–΄λ–»κ²Œ 해석할 수 μžˆμ„κΉŒμ— λŒ€ν•΄ μ˜ˆμ‹œ μ½”λ“œλ₯Ό λ³΄λ©΄μ„œ μ•Œμ•„λ³΄μž

function log() {
  console.log(name);
}
function wrapper() {
  var name = 'nero';
  log();
}
var name = 'zero';
wrapper(); // output : zero

ν•΄λ‹Ή μ½”λ“œλŠ” 두 가지 방식에 따라 κ²°κ³Όκ°€ 달라진닀.

μš°μ„  μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” Lexical Scope 의 방식을 λ”°λ₯΄κ³  ν•¨μˆ˜μ˜ 선언에 따라 μƒμœ„ μŠ€μ½”ν”„κ°€ κ²°μ •λ˜κΈ° λ•Œλ¬Έμ—, μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄ κ²°κ³Ό κ°’μœΌλ‘œ zero λ₯Ό λ°˜ν™˜ν•œλ‹€.

μ΄λŠ” 선언을 κΈ°μ€€μœΌλ‘œ μŠ€μ½”ν”„λ₯Ό κ²°μ •ν•˜κΈ° λ•Œλ¬Έμ—, μ„ μ–Έν•˜λŠ” μˆœκ°„ 자기 μŠ€μ½”ν”„ κΈ°μ€€μœΌλ‘œ μƒμœ„ μŠ€μ½”ν”„μ˜ κ°€μž₯ κ°€κΉŒμš΄ 곳의 λ³€μˆ˜λ₯Ό κ³ μ •μ μœΌλ‘œ μ°Έμ‘°ν•œλ‹€.

κ·Έλ ‡κΈ° λ•Œλ¬Έμ—, μœ„ μ½”λ“œμ˜ κ²½μš°μ—λŠ” wrapper() ν•¨μˆ˜κ°€ μ„ μ–Έλœ μ‹œμ μ—μ„œ μƒμœ„ μŠ€μ½”ν”„μ˜ μ „μ—­ λ³€μˆ˜ name을 κ³ μ •μ μœΌλ‘œ μ°Έμ‘°ν•˜κΈ° λ•Œλ¬Έμ—, μ„ μ–Έ μ‹œ nero λΌλŠ” 값을 가진 name μ΄λΌλŠ” 지역 λ³€μˆ˜λŠ” 좜λ ₯ 결과에 영ν–₯을 주지 μ•ŠλŠ”λ‹€.

λ§Œμ•½ Dynamic Scope 방식이라면 ν˜ΈμΆœμ„ κΈ°μ€€μœΌλ‘œ μŠ€μ½”ν”„κ°€ κ²°μ •λ˜κΈ° λ•Œλ¬Έμ—, ν•¨μˆ˜κ°€ μ„ μ–Έλ˜κ³  name의 값이 λ³€κ²½λ˜μ—ˆμ§€λ§Œ wrapper() ν•¨μˆ˜ λ‚΄μ˜ log() ν•¨μˆ˜κ°€ 호좜 된 μ‹œμ μ—μ„œ name 이 μž¬μ„ μ–Έ λ˜μ–΄ 좜λ ₯ 값은 nero둜 좜λ ₯될 것이닀.

μ΄μ •λ„λ‘œ κ°„λ‹¨ν•˜κ²Œ 각 μŠ€μ½”ν”„μ— λŒ€ν•΄ μ„€λͺ…ν•  수 μžˆλ‹€. πŸ‘Œ

πŸ”– 좜처

Lexical and Dynamic Scope : Suyeon Bakλ‹˜ medium : (JavaScript) Lexical Scope(Static Scope) and Dynamic Scope
Lexical and Dynamic Scope : μ œλ‘œμ΄ˆλ‹˜ 개인 λΈ”λ‘œκ·Έ : ν•¨μˆ˜μ˜ λ²”μœ„(scope)


ν•¨μˆ˜λͺ…에 λ”°λ₯Έ ꡬ뢄

λ˜ν•œ, ν•¨μˆ˜ μž‘μ„± λ°©μ‹μ—μ„œ ν•¨μˆ˜μ˜ 이름(μ‹λ³„μž : identifier)을 μž‘μ„±ν•˜λŠ” μ§€μ˜ μœ λ¬΄μ— 따라 κ΅¬λΆ„λ˜κΈ°λ„ ν•œλ‹€.

μ‹λ³„μž κ·œμΉ™μ— λŒ€ν•œ λ‚΄μš© λ¦¬λ§ˆμΈλ“œ! 🧐

일반적으둜 ν•¨μˆ˜μ˜ 이름을 μ •μ˜ν•˜λŠ” ν•¨μˆ˜ ν˜•νƒœλ₯Ό κΈ°λͺ… ν•¨μˆ˜λΌ ν•˜κ³ , λ°˜λŒ€λ‘œ μ°Έμ‘°ν•  μ‹λ³„μž 없이 μ„ μ–Έλœ ν•¨μˆ˜λ₯Ό 읡λͺ… ν•¨μˆ˜λΌ ν•œλ‹€.

// κΈ°λͺ… ν•¨μˆ˜
function sayHello1() {
	console.log('Hello, World')
}
// 읡λͺ… ν•¨μˆ˜ 1
let sayHello2 = function () {
	console.log('Hello, World')
}

μœ„μ™€ 같이 κΈ°λͺ… ν•¨μˆ˜(sayHello1())λŠ” ν•΄λ‹Ή ν•¨μˆ˜λͺ…을 톡해 μ„ μ–Έλ˜μ—ˆμ§€λ§Œ, μ•„λž˜ 읡λͺ… ν•¨μˆ˜(sayHello2())의 경우 ν•¨μˆ˜ ν‘œν˜„μ‹μ˜ ꡬ문으둜 let 을 톡해 λ³€μˆ˜μ— ν• λ‹Ήλ˜μ—ˆμœΌλ©°, λ³€μˆ˜λͺ…을 톡해 ꡬ뢄할 수 μžˆλ‹€.

그리고 κΈ°λͺ… ν•¨μˆ˜μ˜ κ²½μš°μ—” μ„ μ–Έλœ ν•¨μˆ˜λͺ…을 톡해 μ‹€ν–‰ν•˜μ§€λ§Œ, μ•„λž˜ 읡λͺ… ν•¨μˆ˜μ˜ κ²½μš°μ—λŠ” λ³€μˆ˜λͺ…을 톡해 μ‹€ν–‰ κ°€λŠ₯ν•˜λ‹€. μœ„ 읡λͺ… ν•¨μˆ˜μ˜ κ²½μš°μ—λŠ” μ•„λž˜μ™€ 같이 μ‹€ν–‰λœλ‹€.

sayHello2(); // κΈ°λͺ… ν•¨μˆ˜μ™€ 동일

μ΄λŸ¬ν•œ 읡λͺ… ν•¨μˆ˜λŠ” 주둜 λ‹€λ₯Έ ν•¨μˆ˜μ— λŒ€ν•œ 인수둜 μ‚¬μš©ν•˜κ±°λ‚˜, ν΄λ‘œμ €(closure)둜 μ‚¬μš©ν•˜λŠ” κ²½μš°μ— ν™œμš©λœλ‹€.

ν΄λ‘œμ €(closure)λŠ” κ°„λ‹¨ν•˜κ²Œ λ§ν•˜μžλ©΄ λ‚΄λΆ€ ν•¨μˆ˜κ°€ μ™ΈλΆ€ ν•¨μˆ˜μ— μ ‘κ·Όν•  수 μžˆλŠ” 것에 λŒ€ν•œ λ‚΄μš©μΈλ°, 이후 λ³„λ„μ˜ ν¬μŠ€νŒ…μ„ 진행할 것이닀. κ·Έλž˜λ„ μ§€κΈˆ λ‹Ήμž₯ 이해가 ν•„μš”ν•˜λ‹€λ©΄ μ•„λž˜ 링크둜!

πŸ”– μ°Έκ³ 

closure : μƒν™œμ½”λ”© : ν΄λ‘œμ €


return 문의 μ—­ν• 

그리고 ν•¨μˆ˜μ—μ„œ μž‘λ™λœ ꡬ문에 따라 λ‚˜μ˜€λŠ” κ²°κ³Ό 값을 λ°˜ν™˜ν•˜κΈ° μœ„ν•΄μ„œλŠ” return 문이 μ‘΄μž¬ν•΄μ•Ό ν•œλ‹€. λ‹€μŒμ˜ μ½”λ“œλ₯Ό μ‚΄νŽ΄λ³΄λ©΄μ„œ μ•Œμ•„λ³΄μž.

// return 문이 μ—†λŠ” ν•¨μˆ˜
function sayHello() {
	let a = 'Hello, World'
}
console.log(sayHello()) // output : undefined


ν•΄λ‹Ή ν•¨μˆ˜μ˜ 경우 λ³€μˆ˜ a 에 'Hello, World' λΌλŠ” λ¬Έμžμ—΄μ„ μ €μž₯ν•˜μ˜€μ§€λ§Œ, 이λ₯Ό μ‹€ν–‰ν•˜μ—¬ console 에 좜λ ₯ν•˜λ‹ˆ undefined λΌλŠ” 값을 λ°˜ν™˜ν•˜μ˜€λ‹€.

μ΄λŠ” ν•¨μˆ˜μ˜ κΈ°λ³Έ λ°˜ν™˜ 값이 undefined 둜 μ •ν•΄μ Έμžˆκ³ , returtn 값을 μ„€μ •ν•˜μ§€ μ•Šμ•˜κΈ°μ— κΈ°λ³Έ 값이 좜λ ₯된 것이닀.

ν•΄λ‹Ή μ½”λ“œμ—μ„œ λ³€μˆ˜ a 의 값을 좜λ ₯ν•˜κΈ° μœ„ν•΄μ„œ λ‹€μŒκ³Ό 같이 μˆ˜μ •ν•  수 μžˆλ‹€.

// return 문이 μžˆλŠ” ν•¨μˆ˜
function sayHello() {
	let a = 'Hello, World'
	return a
}
console.log(sayHello()) // output : 'Hello, World'


μœ„ μ½”λ“œμ—μ„œ return κ°’μœΌλ‘œ a λ₯Ό μ„€μ •ν•˜λ‹ˆ μ˜λ„ν•œ λŒ€λ‘œ Hello, Worldλ₯Ό 좜λ ₯ν•˜λŠ” 것을 μ•Œ 수 μžˆμ—ˆλ‹€.

ν•΄λ‹Ή κ²½μš°μ—λŠ” λ‹¨μˆœνžˆ console 에 좜λ ₯ν•˜λŠ” 것이 λͺ©μ μ΄μ—ˆμ§€λ§Œ, return 은 ꡬ문에 λŒ€ν•œ 값을 λ°˜ν™˜ν•œλ‹€λŠ” μ μ—μ„œ μ€‘μš”ν•œ μš”μ†Œ 쀑 ν•˜λ‚˜μ΄λ‹€.

ν•¨μˆ˜μ˜ μ‹€ν–‰

이미 μœ„μ—μ„œλ„ 많이 λ΄€κ² μ§€λ§Œ, ν•¨μˆ˜μ˜ 싀행은 λ‹€μŒκ³Ό 같은 ν˜•μ‹μœΌλ‘œ ν•  수 μžˆλ‹€.

function sayHello() {
	console.log('Hello, World')
}
sayHello(); // output : 'Hello, World'

μœ„μ™€ 같이 ν•¨μˆ˜λͺ…에 μ†Œκ΄„ν˜Έλ₯Ό λΆ™ν˜€ μ‹€ν–‰ν•  수 μžˆλ‹€. λ˜ν•œ μ•žμ—μ„œ μ–ΈκΈ‰ν•œ 읡λͺ… ν•¨μˆ˜μ˜ κ²½μš°μ—λŠ” λ³€μˆ˜λͺ…을 ν™œμš©ν•˜μ—¬ ν•¨μˆ˜λ₯Ό μ„ μ–Έν•  수 μžˆλ‹€.

그리고 ν•¨μˆ˜ 싀행을 μ„ μ–Έ 이후에 λ³„λ„λ‘œ μ§„ν–‰ν•˜λŠ” 것 말고도, μ„ μ–Έκ³Ό λ™μ‹œμ— μ¦‰μ‹œ ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λŠ” ν•¨μˆ˜λ„ μ‘΄μž¬ν•œλ‹€.

// κΈ°λͺ… μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜ 1
(function sayHello() {
	console.log('Hello, World')
})(); // output : 'Hello, World'
// κΈ°λͺ… μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜ 2
(function sayHello() {
	console.log('Hello, World')
}()); // output : 'Hello, World'
// 읡λͺ… μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜ 1
(function () {
	console.log('Hello, World')
})(); // output : 'Hello, World'
// 읡λͺ… μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜ 2
(function () {
	console.log('Hello, World')
}()); // output : 'Hello, World'

μœ„ λ„€ 가지 ν•¨μˆ˜ ꡬ문은 κΈ°λͺ…κ³Ό 읡λͺ… ν•¨μˆ˜λ‘œ κ΅¬λΆ„λ˜κ³  κ΄„ν˜Έμ˜ μœ„μΉ˜λ§Œ 달라진닀. κ΄„ν˜Έμ˜ μœ„μΉ˜κ°€ λ³€κ²½λ˜μ–΄λ„ λ³΄μ‹œλ‹€μ‹œν”Ό κ²°κ³Ό 값은 λ™μΌν•˜λ‹€.

μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜μ˜ 문법을 λ§ν•˜μžλ©΄ ν•¨μˆ˜λ₯Ό μž‘μ„±ν•˜κ³  ν•¨μˆ˜λ₯Ό μ†Œκ΄„ν˜Έλ‘œ 감싼 λ’€, 인자λ₯Ό 포함할 μ†Œκ΄„ν˜Έλ₯Ό λ‹€μ‹œκΈˆ μž‘μ„±ν•΄μ£Όλ©΄ λœλ‹€.

ν•¨μˆ˜ ν‘œν˜„μ‹μœΌλ‘œλ„ μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜λ₯Ό μž‘μ„±ν•˜μ˜€μ§€λ§Œ, 읡λͺ… κΈ°λͺ… ꡬ뢄 없이 였λ₯˜κ°€ λ°œμƒν–ˆλ‹€.

(let sayHello = function () {
	console.log('Hello, World')
})(); // SyntaxError: /src/index.js: Unexpected reserved word 'let' (2:1)

μœ„μ™€ 같은 ꡬ문 였λ₯˜λ₯Ό λ°˜ν™˜ν•˜λŠ” 것을 μ•Œ 수 μžˆλ‹€.

πŸ”– 좜처

μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜ : beomyλ‹˜ tistory : [μžλ°”μŠ€ν¬λ¦½νŠΈ] ν•¨μˆ˜(Function), μ¦‰μ‹œμ‹€ν–‰ν•¨μˆ˜(Immediately-invoked function expression)

🧐 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 이유

μ΄λ ‡κ²Œ ν•¨μˆ˜μ— λŒ€ν•΄ μ–΄λŠ 정도 μ•Œμ•„λ΄€μœΌλ‹ˆ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” μ΄μœ μ— λŒ€ν•΄μ„œλ„ κ°„λ‹¨ν•˜κ²Œ μ•Œμ•„λ³΄μž. ν•΄λ‹Ή λ‚΄μš©μ— λŒ€ν•΄μ„œλŠ” μž¬μ‚¬μš©μ„±, 가독성, λͺ¨λ“ˆν™”λΌλŠ” μ„Έ 가지 ν‚€μ›Œλ“œλ₯Ό 톡해 μ•Œ 수 μžˆλ‹€.

μž¬μ‚¬μš©μ„±

μž¬μ‚¬μš©μ„±μ€ λ§κ·ΈλŒ€λ‘œ μ½”λ“œμ˜ μž¬μ‚¬μš©μ— λŒ€ν•œ 것을 μ˜λ―Έν•œλ‹€.

예λ₯Ό λ“€μ–΄, 같은 κΈ°λŠ₯을 ν•˜λŠ” ꡬ문이 μžˆμ§€λ§Œ μ‚¬μš©λ˜λŠ” μΈμžκ°€ λ‹¬λΌμ„œ μΈμžλ§ˆλ‹€ 같은 ν˜•μ‹μ˜ ꡬ문을 λ°˜λ³΅ν•œλ‹€λ©΄ ν•΄λ‹Ή ꡬ문은 맀우 κΈΈμ–΄μ§ˆ 것이며, λΆˆν•„μš”ν•œ 반볡 업무 λ˜ν•œ λŠ˜μ–΄λ‚  것이닀.

// 일정 κ΅¬κ°„μ—μ„œ 2의 λ°°μˆ˜λ“€μ„ 배열에 λ‹΄λŠ” ꡬ문
let two = []
for (let i = 1; i < 10; i++) {
  two.push(i*2)
} 
console.log(two) // output :  [2, 4, 6 ... , 18]
// 일정 κ΅¬κ°„μ—μ„œ 3의 λ°°μˆ˜λ“€μ„ 배열에 λ‹΄λŠ” ꡬ문
let three = []
for (let i = 1; i < 10; i++) {
  two.push(i*3)
} 
console.log(three) // output :  [3, 6, 9 ... , 27]


ν•΄λ‹Ή κ²½μš°μ— ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€λ©΄ 같은 ν•¨μˆ˜μ— 인자만 λ‹€λ₯΄κ²Œ λŒ€μž…ν•˜μ—¬ μ½”λ“œλ₯Ό μž¬μ‚¬μš©ν•  수 있고, κ°„λž΅ν•œ μ½”λ“œμ™€ 반볡 μ—…λ¬΄μ˜ κ°μ†Œλ₯Ό 도λͺ¨ν•  수 μžˆλ‹€.

function pushMultiple(n) {
  let arr = []
  for (let i = 1; i < 10; i++) {
    arr.push(i*n)
  }
  return arr
}
console.log(pushMultiple(2)) // output :  [2, 4, 6 ... , 18]
console.log(pushMultiple(3)) // output :  [3, 6, 9 ... , 27]

가독성

가독성 λ˜ν•œ κ°„λ‹¨ν•˜κ²Œ 말해 읽기 μ‰¬μš΄ μ½”λ“œλ₯Ό μ˜λ―Έν•œλ‹€. ν•΄λ‹Ή λ‚΄μš©λ„ μž¬μ‚¬μš©μ„±μ—μ„œ μ‚¬μš©ν•œ μ˜ˆμ‹œλ₯Ό ν™œμš©ν•˜μ—¬ μ„€λͺ…ν•  수 μžˆλ‹€.

λ¨Όμ € 읽기 μ‰½λ‹€λŠ” 것은 λ³΅μž‘ν•˜μ§€ μ•Šκ³  κ°„λž΅ν•˜λ‹€λŠ” μ˜λ―Έκ°€ 될 수 μžˆλ‹€.

μœ„ μ˜ˆμ‹œλ₯Ό 보면 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šμ€ ꡬ문과 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œ ꡬ문이 λ‹¨μˆœνžˆ μ½”λ“œ 쀄 갯수의 λΆ€λΆ„μ—μ„œ 차이가 μžˆλ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€. μ½”λ“œκ°€ μ§§λ‹€λŠ” 것은 κ°„λž΅ν•˜κ²Œ 같은 κΈ°λŠ₯을 μ‹€ν–‰ν•˜κ³  이해할 수 μžˆλ‹€λŠ” μž₯점이 λœλ‹€.

λ˜ν•œ, 읽기 μ‰½λ‹€λŠ” 것은 해석에 μš©μ΄ν•˜λ‹€λŠ” μ˜λ―Έλ„ ν¬ν•¨λœλ‹€.

μ•žμ„œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  μž‘μ„±ν•œ ꡬ문의 κ²½μš°μ—λŠ” 좜λ ₯ν•˜κΈ° 이전에 ν•΄λ‹Ή λ³€μˆ˜λͺ…μ΄λ‚˜ for 문을 보고 μ§κ΄€μ μœΌλ‘œ κ²°κ³Ό 값을 μ˜ˆμΈ‘ν•˜κΈ° μ–΄λ €μš΄ 뢀뢄이 μžˆλ‹€.

κ·ΈλŸ¬λ‚˜ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œ ꡬ문은 pushMultiple() μ΄λΌλŠ” ν•¨μˆ˜λͺ…μ—μ„œ ν•΄λ‹Ή ν•¨μˆ˜κ°€ λ°°μˆ˜μ™€ push() λ©”μ„œλ“œλ₯Ό ν™œμš©ν•œλ‹€λŠ” 뢀뢄에 λŒ€ν•΄ μ–΄λŠ 정도 μœ μΆ”ν•  수 μžˆκΈ°μ— ν•΄λ‹Ή μ½”λ“œλ₯Ό 읽고 ν•΄μ„ν•˜λŠ” 것에 μžˆμ–΄ μœ μš©ν•˜λ‹€.

λͺ¨λ“ˆν™”

λͺ¨λ“ˆν™”에 λŒ€ν•œ 이해λ₯Ό μœ„ν•΄ μš°μ„  λͺ¨λ“ˆ(module)에 λŒ€ν•œ κ°œλ…μ„ κ°„λ‹¨νžˆ μ΄ν•΄ν•΄λ³΄μž.

λͺ¨λ“ˆμ΄λž€ μ†Œν”„νŠΈμ›¨μ–΄ μ„€κ³„μ—μ„œ κΈ°λŠ₯ λ‹¨μœ„λ‘œ λΆ„ν•΄ν•˜κ³  좔상화 λ˜μ–΄ μž¬μ‚¬μš© 및 곡유 κ°€λŠ₯ν•œ μˆ˜μ€€μœΌλ‘œ λ§Œλ“€μ–΄μ§„ λ‹¨μœ„λ₯Ό μ˜λ―Έν•˜λŠ”λ°, κ·ΈλŸ¬ν•œ μ˜λ―Έμ—μ„œ λͺ¨λ“ˆν™”λŠ” μ›ν™œν•œ ν˜‘μ—…μ„ λ„μ™€μ£ΌλŠ” 역할을 ν•œλ‹€κ³  보면 λœλ‹€.

ν•„μš” κΈ°λŠ₯을 μ •μ˜ν•˜κ³  ꡬ쑰적인 λΆ€λΆ„μ—μ„œ μ„œλ‘œμ—κ²Œ 영ν–₯을 주지 μ•Šλ„λ‘ μ½”λ“œλ₯Ό μž‘μ„±ν•˜μ—¬, 였λ₯˜κ°€ λ°œμƒν•˜μ˜€μ„ λ•Œ λ””λ²„κΉ…μ˜ κ³Όμ •μ—μ„œ ν™•μ‹€ν•œ 원인 νŒŒμ•…κ³Ό 이후 μ›ν™œν•˜κ³  μ‹ μ†ν•œ μˆ˜μ • 및 보수의 과정을 ν•  수 μžˆλ‹€λŠ” 뢀뢄이 λͺ¨λ“ˆν™”에 λŒ€ν•œ λ‚΄μš©μ— ν¬ν•¨λœλ‹€.

πŸ”– 좜처

ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 이유 : 개발 흔적 남기기 : Javascript - ν•¨μˆ˜(Function)λ₯Ό μ‚¬μš©ν•˜λŠ” 이유, 문법
module : VincentGeranium Blog : λͺ¨λ“ˆ(Module)와 λͺ¨λ“ˆν™”λž€?

πŸ”– 전체적인 μ°Έκ³ 

ν•¨μˆ˜ : MDN Web Docs : ν•¨μˆ˜

πŸ““ μˆ˜μ • 둜그

μˆ˜μ • λ‚ μ§œλ‚΄μš©
210806λ―Έμž‘μ„±ν•œ return 에 λŒ€ν•œ κ°œλ… μΆ”κ°€
profile
μ΄μœ μ— μ§‘μ°©ν•˜λŠ” ν”„λ‘ νŠΈμ—”λ“œ 개발자 μ§€λ§μƒμž…λ‹ˆλ‹€ 🧐

0개의 λŒ“κΈ€