3 minute read

2022.10.08

💡 오늘의 JavaScript 공부 + 복습

▶️ 함수

함수는 자바스크립트에서 가장 중요한 개념이라고 할 수 있다. 사실상 오늘 공부한 내용중에 가장 자세하게 다룰 내용이기도 하다.

📌그렇다면 함수는 왜 사용할까?

함수를 사용하는 가장 큰 목적은 코드의 재사용이다.

함수는 동일한 작업을 반복적으로 수행해야 한다면 같은 코드를 중복해서 여러 번 작성하는 것이 아니라 미리 정의된 함수를 재사용하는 것이 효율적이다.

함수는 코드의 중복을 억제하고 재사용성을 높이기 때문에 유지보수의 편의성을 높이고 실수를 줄여 코드의 신뢰성을 높이는 효과가 있다.

함수에는 4가지 종류가 있다.

📌 함수 리터럴

자바스크립트의 함수는 객체( object )타입의 값이다. 따라서 숫자 값을 숫자 리터럴로 생성하고 객체를 객체 리터럴로 생성하는 것처럼 함수도 함수 리터럴로 생성할 수 있다.

[ 리터럴 ] : 사람이 이해할 수 있는 문자나 약속된 기호를 사용해 값을 생성하는 표기법

// 변수에 함수 리터럴을 할당 
let k = function add(a,b){
	return a + b ;
}

함수는 객체이지만 일반 객체와는 다르다. 일반 객체는 호출할 수 없지만 함수는 호출할 수 있다. 그리고 일반 객체에는 없는 함수 객체만의 고유한 프로퍼티를 갖는다.

📌 함수의 종류
// 함수 선언문 
function add( x + y ){
  return x + y;
}

// 함수 표현식
let add = function( x , y ){
  return x + y;
}

// Function 생성자함수 
let add = new Function('x' , 'y' , 'return x + y');

// 화살표 함수
let add = ( x , y ) => x + y;
📌 함수선언문 vs 함수표현식의 차이는 뭘까?

간단한 예시를 보면서 이해해보기로 했다.

// 함수선언문 => 함수를 선언
function sayMyname(){       
  console.log('sehoon')
}

//함수표현식 => 함수를 생성하고 변수에 값을 할당
let sayMyname = function(){
  console.log('sehoon')
}																

// 결과값은 둘다 'sehoon'

결과값도 같고 <span style= color:red>함수식</span> 말고는 다른 것을 모르겠는데 ? 라고 생각할 수 있다.

하지만 둘의 차이점은 이것 말고도 하나 더 있다.

두번째 차이는 <span style= color:red>JS엔진이 언제 함수를 생성하는지</span>에 있다.

함수표현식은 실제 실행 흐름이 해당함수에 도달했을 때 함수를 생성한다. 즉 실행 흐름이 함수에 도달했을 때부터 해당 함수를 사용할 수 있다.

함수선언문은 조금 다르다 . 함수선언문이 정의되기 전에도 호출할 수 있다. ( 호이스팅‼️ ) , 즉 전역 함수선언문은 스크립트 어디서든 사용할 수 있다.

위의 코드로 실행하면서 이해해보자면?

console.log(sayMyname())  // => sehoon
console.log(Myname())     // => ReferenceError

// 함수선언문 
function sayMyname(){       
  console.log('sehoon')  	
}													

//함수표현식 
let Myname = function(){
  console.log('sehoon')
}																

이것이 가능한 이유는 JS 호이스팅편에서 공부해서 쉽게 이해할 수 있었다.

요약

  1. 함수는 값이다. 따라서 함수도 값처럼 할당, 복사, 선언할 수 있다.
  2. 함수선언문 방식으로 함수를 생성하면 함수가 독립된 구문 형태로 존재한다.
  3. 함수표현식으로 함수를 생성하면 함수는 표현식의 일부로 존재한다.
  4. 함수선언문은 코드블록이 실행되기 전에 처리되며 블록내 어디서든 활용 가능하다.
  5. 함수표현식은 실행 흐름이 표현식이 다다랐을 때 만들어진다.

🐥 공부를 하다 보니 함수 선언문은 함수 이름을 생략할 수 없다는 점을 제외하면 함수 리터럴과 형태가 동일하다는 생각이 들었다.

그렇다면 함수 이름이 있는 기명 함수 리터럴은 함수 선언문 또는 함수 리터럴 표현식으로 해석될 가능성이 있다는 것 아닌가? 예를 들어 { }는 블록문일 수도 있고 객체 리터럴일 수도 있다. 즉 { }는 중의적 표현이다.

여기서 드는 의문점 ! 자바스크립트는 { }를 코드블록으로 해석할까 객체 리터럴로 해석할까??

해답은 코드의 문맥에 있었다.

{ }가 단독으로 존재하면 자바스크립트 엔진은 { }를 블록문으로 해석한다.

하지만 { }가 평가되어야 할 문맥 ( 할당자의 우변 )에서 피연산자로 사용되면 자바스크립트엔진은 { }를 객체 리터럴로 해석한다.

이처럼 동일한 코드도 코드의 문맥에 따라 해석이 달라질 수 있다.

📌 리턴값

나는 리턴값을 이해하는데 굉장한 시간을 할애했던 것 같다. 어떻게 보면 굉장히 단순한 수식이었지만 동작을 이해하지 못하였고 때문에 리턴값을 사용할 때 조금 무서웠다. 하지만 이 코드를 연습하며 빠른 이해를 할 수 있었다.

우선 리턴값은 함수를 호출했을 때 함수를 호출한 그곳에 특정 값을 반혼하게 하는 return value이다.

// 단순 return값 연습 
function add( num1, num2 ){
  return num1 + num2
}
console.log(add(1,2))
// 3

// 빠른 이해를 도와준 예제  ( 이중 return )
function checkAge(age){
  if ( age >= 18 ){
    return true;
  }else{
    return confirm('보호자의 동의가 있습니까?');
  }
}

let age = prompt('당신의 나이는 몇살인가요?', ' ');
if( checkAge(age) ){
  alert('접속허용')
}else{
  alert('접속거절')
}
// 개인적으로 return , function , if 모두 이해하기 쉬운 예제였다. 

지시자 return은 함수 내 어디에서든 사용할 수 있다. 실행 흐름이 return을 만나면 함수는 즉시 중단되고 함수를 호출한 곳에 값을 반환한다.

📌 화살표함수
const add = function (num1, num2){
  const result = num1 + num2;  
  return result;
}
const add = (num1,num2) => {
  return = num1 + num2;   
}
const add = (num1,num2) => num1 + num2;
모두 같은 결과값을 도출하는 함수

화살표 함수는 일반 함수와는 달리 자신만의 this를 가지지 않는다. 
화살표 함수 내부에서 this를 사용하면,  this는 외부에서 값을 가져온다. 

Comments