-
[Group Study, 모던 자바스크립트 Deep Dive] - 12 함수Front-end/Javascript 2022. 10. 26. 06:28반응형
Group study background
나만 그런건지는 모르겠지만, 실무를 하다보면 잊어버리는 개념들이 있다.
가끔 FE 뉴비나 novice인분들에게 질문을 받는데, 아리송 할때만큼 쪽팔릴때가 없었다.
인간은 망각의 동물이라고 교수님께서 말씀하셨지만 반복 학습의 힘을 믿는다. React 오픈카톡방에서 모집한 스터디원분들과 함께 "모던 자바스크립트 Deep Dive" 1권 톺아보기를 시작한다!
정보 전달용이 아닌 개인 스터디 레코딩용 포스트입니다.
12.1 함수란
프로그래밍 언어의 함수는 일련의 과정을 문(statement)로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것이다. 함수 내부로 입력을 전달받는 변수를 매개 변수, 입력을 인수, 출력을 반환값이라 한다. 또한 함수는 값이며, 여러 개 존재할 수 있으므로 특정 함수를 구별하기 위해 식별자인 함수 이름을 사용할 수 있다.
[그림 12-01] 함수의 구성 요소 (Reference: 모던 자바스크립트 Deep Dive)
12.3 함수 리터럴
함수 리터럴도 평가되어 값을 생성하며, 이 값은 객체이므로 함수도 객체이다.
함수는 개체지만 일반 객체와는 다르다. 일반 객체는 호출할 수 없지만, 함수는 호출할 수 있다.
[표 12-01] 함수 리터럴의 구성 요소 (Reference: 모던 자바스크립트 Deep Dive)
12.4 함수 정의
[표 12-02] 함수 정의 방식 (Reference: 모던 자바스크립트 Deep Dive)
12.4.1 함수 선언문
함수 선언문은 함수 리터럴과 형태가 동일하다. 단, 함수 리터럴은 함수 이름을 생략할 수 있으나 함수 선언문은 함수 이름을 생략할 수 없다. 함수 선언문은 표현식이 아닌 문(statement)이다. 함수 선언문을 실행하면 완료 값 undefine가 출력된다. 표현식이 아닌 문은 변수에 할당할 수 없다.
자바스크립트의 엔진이 코드의 문맥에 따라 동일한 함수 리터럴을 표현식이 아닌 문인 함수 선언문으로 해석하는 경우와 표현식인 문인 함수 리터럴 표현식으로 해석하는 경우가 있다.
[예제 12-01]
function foo() { console.log('foo') } foo(); (function bar() { cosnole.log('bar') }) bar(); // ReferenceError; bar is not defined
위 예제에서 단독으로 사용된 함수 리터럴(foo)은 함수 선언문으로 해석되지만, 그룹 연산자 () 내에 있는 함수 리터럴(bar)은 함수 선언문으로 해석되지 않고 함수 리터럴 표현식으로 해석된다. 그룹 연산자의 피연산자는 값으로 평가될 수 있는 표현식이어야 하기 때문에, 표현식이 아닌 문인 함수 선언문은 피연산자로 사용할 수 없다.
함수 몸체 외부에서는 함수 이름으로 함수를 참조할 수 없으므로 함수 몸체 외부에서는 함수 이름을 함수를 호출 할 수 없다.
[그림 12-02] 함수 이름 bar는 함수 몸체 내에서만 참조할 수 있는 식별자이므로 호출할 수 없다. (Reference: 모던 자바스크립트 Deep Dive)
자바스크립트 엔진은 함수 선언문을 해석해 함수 객체를 생성한다. 이때 함수 이름은 함수 몸체 내부에서만 유효현 식별자이르모 함수 이름과는 별도로 생성된 함수 객체를 가리키는 식별자가 필요하다. 함수 객체를 가리키는 식별자가 없으면 생성된 함수 객체를 참조할 수 없으므로 호출할 수도 없다. 따라서 자바스크립트 엔진은 생성된 함수를 호출하기 위해 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고, 거기에 함수 객체를 할당한다.
[그림 12-03] foo는 자바스크립트 엔진이 암묵적으로 생성한 식별자이다.(Reference: 모던 자바스크립트 Deep Dive)
[그림 12-04] 함수는 함수 이름으로 호출하는 것이 아니라 함수 객체를 가리키는 식별자로 호출한다.(Reference: 모던 자바스크립트 Deep Dive)
12.4.2 함수 표현식
자바스크립트의 함수는 값처럼 변수에 할당할 수도 있고 프로퍼티 값이 될수도 있으며 배열의 요소가 될 수도 있다. (일급 객체: 함수를 값처럼 자유롭게 사용 가능)
함수 리터럴로 생성한 함수 객체를 변수에 할당할 수 있는데 이를 함수 표현식이라 한다.
[예제 12-02] 기명 함수/익명함수
var add = function(x,y) { return x + y } var add2 = function foo(x,y) {return x + y}
12.4.3 함수 생성 시점과 함수 호이스팅
함수 호이스팅: 함수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징, 런타임 이전에 자바스크립트 엔진에 의해 먼저 실행되어 식별자를 생성한다. var 키워드로 선언된 변수는 undefined로 초기화되지만, 함수 선언문을 통해 암묵적으로 생성된 식별자는 함수 객체로 초기화 된다. 따라서 함수 선언문으로 정의한 함수를 함수 선언문 이전에 호출하면 함수 호이스팅에 의해 호출 가능하다. 따라서 함수 표현시으로 함수를 정의하면 함수 호이스팅이 아니라 변수 호이스팅이 발생한다.
[예제 12-03]
console.log(add(2,5)) console.log(sub(2,5)) //TypeError: sub is not a function // 함수 선언문 function add(x,y) { return x+y } // 함수 표현식 var sub = function(x,y) { return x-y }
[그림 12-05] 함수 표현식에 의한 생성.(Reference: 모던 자바스크립트 Deep Dive)
12.6 참조에 의한 전달과 외부 상태의 변경
객체 타입 인수를 전달받은 매개변수 obj의 경우, 객체는 변경 가능한 값이므로 직접 변결할 수 있기 때문에 재할당 없이 직접 할당된 객체를 변경했다.
원시 타입 인수는 값 자체가 복사되어 매개변수에 전달되기 때문에 함수 몸체에서 그 값을 변경(재할당)해도 원본은 훼손되지 않는다. 하지만 객체타입 인수는 참조 값이 복사되어 매개변수에 전달되기 때문에 함수 몸체에서 참조 값을 통해 객체를 변경할 경우 원본이 훼손된다. 즉, 외부 상태, 함수 외부에서 함수 몸체 내부로 전달한 참조 값에 의해 원본 객체가 변경되는 부수 효과가 발생한다.
[예제 12-04]
function changeVal(primitive, obj) { primitive += 100; obj.name = 'Kim'; } var num = 100 var person = { name: 'Lee' } changeVal(num, person)
현실 세계에서는 이와 같은 케이스로 의도적으로 개발이 된 코드들이 많다. 하지만 상태 변화를 추척하기 어려어져 코드의 복잡성을 증가시키고 가독성을 해체하게 된다. 그렇지 않다면 객체를 deep copy로 불변 객체로 만들어 사용할 필요가 있다.
[그림 12-06] 값에 의한 호추과 참조에 의한 호출.(Reference: 모던 자바스크립트 Deep Dive)
12.7 다양한 함수의 형태
12.7.5 순수 함수와 비순수 함수
함수형 프로그래밍에서는 어떤 외부 상태에 의존하지도 않고 변경하지도 않는, 즉 부수 효과가 없는 함수를 순수 함수(pure functio)라 하고, 외부 상태에 의존하거나 외부 상태를 변경하는, 즉 부수 효과가 있는 함수를 비순수 함수(impure function)fkrh gksek.
순수 함수: 동일한 인수가 전달되면 언제나 동일한 값을 반환하는 함수. 즉, 어떤 외부 상태에도 의존하지 않고 오직 매개변수를 통해 함수 내부로 전달된 인수에게만 의존해 반환. 또한, 함수의 외부 상태를 변경하지 않는다.
[예제 12-05] 순수 함수
var count = 0; function increase() { return ++n; } count = increase(count) count = increase(count)
비순수 함수: 외부 상태에 따라 반환값이 달라지는 함수. 순수 함수와 달리 함수의 외부 상태를 변경하는 부수 효과(slide effect)가 있으며 외부 사태에 의존하거나 외부 상태를 변경
[예제 12-06] 비순수 함수
var count = 0; function increase() { return ++count } increase() increase()
함수형 프로그래밍은 순수 함수와 보조 함수의 조합을 통해 외부 상태를 변경하는 부수 효과를 최소화해서 불변셩을 지향하는 프로그래밍 패러다임이다. 로직 내에 존재하는 조건문과 반복문을 제거해서 복잡성을 해결하며, 변수 사용을 억제하거나 생명주기를 최소화해서 상태 변경을 피해 오류를 최소화 한다.
반응형'Front-end > Javascript' 카테고리의 다른 글
[Group Study, 모던 자바스크립트 Deep Dive] - 14 전역 변수의 문제점 (0) 2022.10.30 [Group Study, 모던 자바스크립트 Deep Dive] - 13 스코프란 (0) 2022.10.26 [Group Study, 모던 자바스크립트 Deep Dive] - 11 원시 값과 객체의 비교 (0) 2022.10.26 [Group Study, 모던 자바스크립트 Deep Dive] - 10 객체 리터럴 (0) 2022.10.25 [Javascript] ES12 ES2021? (0) 2020.12.08