자바스크립트 함수

Date
Created
Apr 26, 2024 08:17 AM
Tags
1장

함수 선언문

function add (){}

함수 표현식

‘일급 객체’: 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 의미함.
자바스크립트의 함수는 일급 객체로 매개변수나, 반환값, 할당도 가능해 일급 객체의 조건을 잘 갖추고 있다.
const sum = function sum (){}
일반적으로는 혼란을 방지하기 위해 함수 이름을 생략한다.
const sum = function add (){} add() // error

함수 선언식, 표현식의 차이

가장 큰 차이점은 호이스팅 여부.
add() // good function add () {} add() // error var add = function(){}
선언적으로 선언해 어디서든 자유롭게 사용하거나 변수 선언과 명확하게 구별할 수 있다는 장점이 있지만 함수 호출은 제일 먼저 보이고 실제 함수가 어디서 어떻게 선언 되었는지 끝까지 확인하지 않으면 찾기가 힘들다.
프로젝트의 상황에 알맞는 작성을 일관되게 사용해야 한다.

화살표 함수

function 키워드 대신 ⇒ 를 통해 만드는데 글자수가 줄어드는 측면에서 많이 활용하는 것 같다고 함.
일반 함수와 다른 점은 다음과 같은데
  • Constructor(생성자) 사용 불가능 즉, 생성자 함수로 화살표 함수를 사용할 수 없다.
    • const Car = () => {} const myCar = new Car('asd') //error
  • 화살표 함수는 arguments 가 존재하지 않는다.
    • function asd(){ console.log(arguments); } asd(1,2,3) // [1,2,3, ...] const asd = () = >{ console.log(arguments); } asd(1,2,3) // error
  • this 바인딩이 존재하지 않는다.

this

this 바인딩이란 자신이 속한 객체나 자신이 생성할 인스턴스를 가리키는 값.
this는 화살표 함수 이전까지 함수를 정의할 떄 결정되는 것이 아니라, 함수가 어떻게 호출되느냐에 따라 동적으로 결정.
만약 일반 함수로 호출되면 내부의 this 객체는 전역 객체를 가리킴.
이와 달리 화살표 함수는 함수 자체의 바인딩을 가지지 않음.
화살표 함수 내부에서 this를 참조하면 상위 스코프의 this를 그대로 따르게됨.
class Component extends React.Component{ constructor(props){ super(props) this.state = { counter: 1, } } countUp () { console.log(this) // undefined this.setState((prev) => {counter: prev.counter + 1}); } arrowCountUp = () => { console.log(this) // class Component this.setState((prev) => {counter: prev.counter + 1}); } render () { return ( <button onClick = {this.countUp}>일반 함수</button> // error <button onClick = {this.arrowCountUp}>화살표 함수</button> // 정상 작동 ) } }
이는 바벨에서의 차이점도 볼 수 있다.
const hello = () => { console.log(this) } function hello () { console.log(this) } // ----- var _this = void 0 const hello = () => { console.log(_this) // 바벨에서 화살표 함수 내부의 _this 자체를 undefined로 바꿔버림 } function hello () { console.log(this) }
화살표 함수는 this가 선언되는 시점에 이미 상위 스코프로 결정되어 미리 _this를 받아서 사용함.
일반 함수는 호출하는 런타임 시점에 결정되는 this를 그대로 따름.
  • 함수 종류에 따라 this가 가리키는 객체가 다름
    • 생성자 : 새로운 객체
    • strict 모드에서의 함수 : undefined
    • 객체 메서드 : 베이스 객체
    • callback 함수 : 전역 객체 window
  • Arrow Function에서는 전역 컨텍스트에서 실행 될 때 this를 새로 정의하지 않음
    • 코드에서 바로 바깥의 함수(혹은 class)의 this(Lexcial this) 값을 사용
    • this를 클로저 값으로 처리하는 것과 같음

즉시 실행 함수

말그대로 함수를 정의하고 그 순간 즉시 실행됨. 단 한 번만 호출되고, 다시금 호출할 수 없음.
(function (a, b){ return a + b }(10, 20)) ((a, b) => { return a + b }(10, 20))
즉시 실행 함수의 장점은 글로벌 스코프를 오염시키지 않는 독립적인 함수 스코프를 운용할 수 있다는 장점이 있음.
선언과 실행이 그 자리에서 끝나기 때문에 즉시 실행 함수의 내부에 있는 값은 함수 내부가 아니면 접근이 불가능.

고차 함수

자바스크립트의 함수는 일급 객체로 이 특징을 활용해 함수를 인수로 받거나 새로운 함수를 반환할 수 있음.
이런 역할을 하는 함수가 고차 함수.
// 함수를 매개변수로 받는 대표적인 고차 함수, Array.prototype.map const arry = [1, 2, 3].map((item) => item * 2)
이런 특징을 활용해 함수형 컴포넌트를 인수로 받아 새로운 함수형 컴포넌트를 반환하는 고차 함수를 만들 수 있음.
이런 컴포넌트를 고차 함수와 비슷하게 고차 컴포넌트라고 부름.
고차 함수를 만들면 컴포넌트 내부에 공통으로 관리되는 로직을 분리해 관리할 수 있어 효율적인 리팩토링이 가능함.

함수를 만들 때 주의할점

함수의 부수 효과를 최대한 억제할 것

함수의 부수 효과(side effect) 함수 내의 작동으로 인해 함수가 아닌 함수 외부에 영향을 끼치는 것.
부수효과가 없는 순수한 함수로 작성하는게 좋지만 개발을 하다보면 피할수는 없는 요소.
console.log, 외부 data fetch, html 수정 등 이런 외부적인 부수 효과도 존재한다.
리액트의 관점에서는부수 효과를 처리하는 훅인 useEffect의 작동을 최소화 하는 것이 그 일환이라고 할 수 있다.
useEffect의 사용은 피할 수 없지만 최소한으로 줄여 함수의 역할을 좁히고 버그를 줄이며, 안정성을 높여야 한다.

가능한 한 함수를 작게 만들 것

함수가 커지면 문재가날 확률이 높아지고 내부에 무슨일이 일어나는지 추적이 힘들어짐.
하나의 함수가 하나의 일만 하게 할 것 이것이 재사용을 높이는 좋은 방법(나는 이 규칙을 반드시 따라야 한다고는 생각 안한다.)
결국 적절히 함수를 분리하고 가능한 작은 단위를 유지하며 함수를 설계하라는 말인것 같다.

누구나 이해할 수 있는 이름

여기서는 useEffect나 useCallBack에 넘겨주는 콜백 함수에 이름을 붙여주는 방법도 가독성에 도움이 된다고 한다.