[JavaScript] JS 함수
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 호이스팅편에서 공부해서 쉽게 이해할 수 있었다.
요약
- 함수는 값이다. 따라서 함수도 값처럼 할당, 복사, 선언할 수 있다.
- 함수선언문 방식으로 함수를 생성하면 함수가 독립된 구문 형태로 존재한다.
- 함수표현식으로 함수를 생성하면 함수는 표현식의 일부로 존재한다.
- 함수선언문은 코드블록이 실행되기 전에 처리되며 블록내 어디서든 활용 가능하다.
- 함수표현식은 실행 흐름이 표현식이 다다랐을 때 만들어진다.
🐥 공부를 하다 보니 함수 선언문은 함수 이름을 생략할 수 없다는 점을 제외하면 함수 리터럴과 형태가 동일하다는 생각이 들었다.
그렇다면 함수 이름이 있는 기명 함수 리터럴은 함수 선언문 또는 함수 리터럴 표현식으로 해석될 가능성이 있다는 것 아닌가? 예를 들어 { }는 블록문일 수도 있고 객체 리터럴일 수도 있다. 즉 { }는 중의적 표현이다.
여기서 드는 의문점 ! 자바스크립트는 { }를 코드블록으로 해석할까 객체 리터럴로 해석할까??
해답은 코드의 문맥에 있었다.
{ }가 단독으로 존재하면 자바스크립트 엔진은 { }를 블록문으로 해석한다.
하지만 { }가 평가되어야 할 문맥 ( 할당자의 우변 )에서 피연산자로 사용되면 자바스크립트엔진은 { }를 객체 리터럴로 해석한다.
이처럼 동일한 코드도 코드의 문맥에 따라 해석이 달라질 수 있다.
📌 리턴값
나는 리턴값을 이해하는데 굉장한 시간을 할애했던 것 같다. 어떻게 보면 굉장히 단순한 수식이었지만 동작을 이해하지 못하였고 때문에 리턴값을 사용할 때 조금 무서웠다. 하지만 이 코드를 연습하며 빠른 이해를 할 수 있었다.
우선 리턴값은 함수를 호출했을 때 함수를 호출한 그곳에 특정 값을 반혼하게 하는 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