1.2.1 함수란 무엇인가?
자바스크립트에서 함수란
'작업을 수행하거나 값을 계산하는 등의 과정을 표현하고, 이를 하나의 블록으로 감사 실행 단위로 만들어 놓은 것 '
// 함수의 기본적인 형태
function sum(a,b) {
return a + b
}
sum(10,24) //34
function 뒤에 오는 것이 함수명
함수수의 입력값으로 받는 a,b를 각각 매개변수라 하고, return으로 작성된 것이 반환값이다.
리액트에서 컴포넌트를 만드는 함수도 이러한 기초적인 형태를 따른다.
function Component(props) {
return <div>{props.hello}</div>
}
Component라고 하는 함수를 선언하고 매개변수로는 일반적으로 props라고 부르는 단일 객체를 받으며
return 문으로 JSX를 반환한다.
1.2.2 함수를 정의하는 4가지 방법
함수 선언문
- 자바스크립트에서 함수를 선언할 때 가장 일반적으로 사용하는 방식
function add(a, b) {
return a + b
}
함수 선언문은 표현식이 아닌 일반 문으로 분류된다.
표현식이란 무언가 값을 산출하는 구문을 의미하는데 어떠한 값이 표현되지 않았으므로 표현식이 아닌 문으로 분류된다.
const sum = function sum(a, b) {
return a + b
}
sum(10, 24)//34
그러나 이 예제는 sum이라는 변수에 함수 sum을 할당하는 표현식과 같은 작동을 보인다.
이는 자바스크립트 엔진이 코드의 문맥에 따라 동일한 함수를 문이 아닌 표현식으로 해석하는 경우가 있기 때문이다.
따라서 이름을 가진 형태의 함수 리터럴은 코드 문맥에 따라 선언문으로도, 표현식응로도 사용될 수 있다.
함수 표현식
- 자바스크립트에서 함수는 일급 객체다.
- 함수는 다른 함수의 매개변수가 될 수도 있고, 반환값이 될 수도 있으며, 할당도 가능하므로 일급 객체가 될 수 있다.
일급 객체 : 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체
함수 표현식에서는 할당하려는 함수의 이름을 생략하는 것이 일반적이다.
>> 함수 호출에 전혀 도움이 되지 않고, 코드를 읽는 데 방해가 될 수 있다.
함수 표현식과 선언 식의 차이
함수 표현식과 함수 선언 식의 가장 큰 차이는 호이스팅(hoisting) 여부이다.
ㄴ 함수 선언문이 마치 코드 맨 앞단에 작성된 것 처럼 작동하는 자바스크립트 특징
hello() //hello
function hello() {
console.log('hello')
}
hello() //hello
| - >> 함수에 대한 선언을 실행 전에 미리 메모리에 등록하는 작업
함수의 호이스팅이라는 특징 덕분에 함수 선언문이 미리 메모리에 등록되어
코드의 순서에 상관없이 정상적으로 함수를 호출할 수 있게 되었다.
반면 함수 표현식은 함수를 변수에 할당했다.
변수도 호이스팅이 발생하지만 함수의 호이스팅과는 다르게, 호이스팅 되는 시점에서 var의 경우에는 undefined로 초기화한다.
console.log(typeof hello === 'undefined') //true
hello() // Uncaught TypeError : hello is not a function
var hello = function () {
console.log('hello')
}
hello()
함수와 다르게 변수는, 런타임 이전에 undefined로 초기화되고,
할당문이 실행되는 시점, 즉 런타임 시점에 함수가 할당되어 작동한다.
Fiction 생성자
const add = new Function('a','b', 'return a + b')
add(10, 24) //34
생성자 함수 방식으로 함수를 만드는 것은 권장되지 않는다.
화살표 함수
- ES6에서 새롭게 추가된 함수 생성 방식
- function 이라는 키워드 대신 => 라는 화살표를 활용해서 함수를 만든다.
const add = (a, b) => {
return a + b
}
const add = (a, b) => a + b
화살표 함수는 앞서 언급한 함수 생성 방식과 몇 가지 큰 차이점이 있다.
- 화살표 함수에서는 constructor을 사용할 수 없다. 즉, 생성자 함수로 화살표 함수를 사용하는 것은 불가능.
- 화살표 함수에서는 arguments가 존재하지 않는다.
- 가장 큰 차이점은 바로 this 바인딩이다.
this
ㄴ 자신이 속한 객체나 자신이 생성할 인스턴스를 가리키는 값
this는 화살표 함수 이전까지 함수를 정의 할 때 결정되는 것이 아니라, 함수가 어떻게 호출되느냐에 따라 동적으로 결정된다.
함수가 일반 함수로서 호출된다면 , 그 내부의 this는 전역 객체를 가리킨다.
이와 달리 화살표 함수는 함수 자체의 바인딩을 갖지 않는다.
화살표 함수 내부에서 this를 참조하면 상위 스코프의 this를 그대로 따르게 된다.
즉, 화살표 함수는 별도의 작업을 추가로 하지 않고 this에 접근할 수 있다.
1.2.3 다양한 함수 살펴보기
즉시 실행 함수
- 함수를 정의하고 그 순간 즉시 실행되는 함수.
- 단 한 번만 호출되고, 다시 호출할 수 없는 함수.
(function (a, b) {
return a + b
})(10,24); //34
((a, b) => {
return a + b
},
)(10,24) //34
즉시 실행 함수는 한 번 선언하고 호출된 이후에 재호출이 불가능하기 때문에 이름을 붙이지 않는다.
장점은
- 함수의 선언과 실행이 바로 그 자리에서 끝나기 때문에 즉시 실행 함수 내부에 있는 값은 그 함수 내부가 아니고서는 접근이 불가능하기 때문에 글로벌 스코프를 오염시키지 않는 독립적인 함수 스코프를 운용할 수 있다.
- 선언돼 있으면 그 선언만으로도 실행이 거기서 끝난다는 것을 각인시킬 수 있기 때문에 리팩터링에도 매우 도움이 된다.
고차 함수
- 자바스크립트의 함수가 함수를 인수로 받거나 결과를 새로운 함수로 반환시키는 역할을 하는 함수.
// 함수를 매개변수로 받는 대표적인 고차 함수, Array.prototype.map
const doubledArray = [1, 2, 3].map((item) => item * 2)
doubledArray // [2, 4, 6]
// 함수를 반환하는 고차 함수의 예
const add = function (a) {
// a가 존재하는 클로저를 생성
return function (b) {
// b를 인수로 받아 두 합을 반환하는 또 다른 함수를 생성
return a + b
}
}
add(1)(3) // 4
이러한 특징을 활용해 함수 컴포넌트를 인수로 받아 새로운 함수 컴포넌트를 반환하는 고차 함수를 만들 수도 있다.
이런 컴포넌트를 고차 함수와 유사하게 고차 컴포넌트라고 부른다.
고차 함수 컴포넌트를 만들면 컴포넌트 내부에서 공통으로 관리되는 로직을 분리해 관리할 수 있어 효율적인 리팩터링이 가능하다.
1.2.4 함수를 만들 때 주의해야 할 사항
함수의 부수 효과를 최대한 억제하라
함수의 부수효과(side-effect) : 함수 내의 작동으로 인해 함수가 아닌 함수 외부에 영향을 끼치는 것
이러한 부수 효과가 없는 함수를 순수 함수, 부수 효과가 존재하는 함수를 비순수 함수라고 한다.
순수 함수 : 부수효과 X , 언제 어디서나 어떠한 상황에서든 동일한 인수를 받으면 동일한 결과를 반환해야 한다.
이러한 작동 와중에 외부에 어떠한 영향도 미쳐서는 안된다.
순수한 함수는 언제 실행되든 항상 결과가 동일하기 때문에 예측 가능하며 안정적이다.
자바스크립트 함수에서는 가능한 한 부수효과를 최소화하고,
함수의 실행과 결과를 최대한 예측 가능하도록 설계해야 한다.
가능한 함수를 작게 만들어라
누구나 이해할 수 있는 이름을 붙여라
'모던 리액트 Deep Dive 스터디' 카테고리의 다른 글
리액트에서 자주 사용하는 자바스크립트 문법 (0) | 2024.11.07 |
---|---|
이벤트 루프와 비동기 통신의 이해 (0) | 2024.11.06 |
리액트 개발을 위해 꼭 알아야 할 자바스크립트 - 클로저 (1) | 2024.11.06 |
리액트 개발을 위해 꼭 알아야 할 자바스크립트 - 클래스 (4) | 2024.11.05 |
자바스크립트의 동등 비교 (1) | 2024.11.04 |