(정리, 함수 생성 시점과 함수 호이스팅, function 생성자 함수랑, 화살표 함수의 비교, 참조의 의한 전달과 외부 상태의 변경, 순수함수와 비순수 함수)
함수 : input을 받아 output을 내보내는 과정을 문으로 구현하고, 하나의 실행단위로 정의한 것
function 함수이름(매개변수){
return 반환값;
}
함수이름(인수);
실행 시점을 개발자가 결정하기 위해
코드의 재사용 측면 : 재사용을 하기 위해
-> 중복된 코드를 억제하고, 재사용성을 높여 유지보수의 편의성을 높이고 코드의 신뢰성을 높인다.
자바스크립트의 함수는 객체 타입의 값이다.
함수는 함수 리터럴(function, 함수이름, 매개변수, 함수몸체로 구성)을 사용하여 생성한다.
일반 객체는 호출할 수 없지만, 정의해둔 함수는 호출할 수 있다
함수 정의 : 함수를 호출하기 이전에 인수를 전달받을 매개변수와 실행할 문자들, 반환할 값을 지정하는 것, 자바스크립트 엔진에 의해 평가되어 함수 객체가 된다.
함수 선언문은 표현식이 아닌 문이기 때문에 변수에 할당할 수 없다.
자바스크립트 엔진은 생성된 함수를 호출하기 위해 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고, 생성된 식별자에 함수 객체를 할당한다.
함수는 함수 객체를 가리키는 식별자로 호출한다.
//함수 표현식
//함수는 값처럼 변수에 할당할 수 있고, 프로퍼티 값이 될 수도 있고, 배열의 요소가 될수도 있는 일급 객체이다.
// 함수 선언문
function add(x,y){
return x+y;
};
//익명 함수
var add = function(x,y){
return x+y;
};
//기명 함수
var add = function plus(x,y){
return x+y;
};
add(1,2) //3
plus(1,2) //에러 발생!!
add(1,2) //3
// 함수 선언문
function add(x,y){
return x+y;
};
plus(1,2) //is not a function
var plus = function(x,y){
return x+y;
};
함수 선언문으로 정의한 함수는 함수 선언문 이전에 호출할 수 있다.
런타임에는 이미 함수 객체가 생성되어, 함수 이름과 동일한 식별자에 할당까지 완료된 상태
함수 선언문이 코드의 최상단에 끌어 올려진 것처럼 동작하는 자바스크립의 특징을 함수 호이스팅이라 한다.
위 코드에서 add는 함수 선언문이라 호이스팅된다.
하지만 plus는 var로 선언 되어 변수 호이스팅 규칙을 따른다.
변수 호이스팅과 함수 호이스팅의 차이
var로 선언된 변수는 undefined로 초기화 되지만, 함수 호이스팅은 암묵적으로 생성된 식별자에 함수 객체로 초기화 된다.
함수 선언문은 함수를 호출하기 전에 반드시 함수를 선언해야 한다는 규칙을 무시한다. JSON을 창안한 더글라스 크락포드는 함수 표현식을 사용할 것을 권장한다.
function 생성자 함수에 매개변수 목록과 함수몸체를 문자열로 전달하면서 new연산자와 함께 호출하면 함수객체를 생성해서 반환한다. (new 없어도 동일하게 작동한다.)
var add = new Function('x', 'y', 'return x + y');
var add = Fuction ('x', 'y', 'return x + y');
함수 선언문이나 함수 표현식으로 생성한 함수와 Fuction 생성자 함수로 생성한 함수가 동일하게 동작하지 않는다.
Fuction 생성자 함수는 클로저를 생성하지 않는다.
렉시컬 환경(Lexical environment) : 자신이 생성될때의 환경
클로저 : 반환된 내부함수가 자신이 선언됐을 때의 렉시컬 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 스코프 밖에서 호출되어도 그 스코프에 접근할 수 있는 함수를 말한다. 이를 조금 더 간단히 말하면 클로저는 자신이 생성될 때의 렉시컬 환경(Lexical environment)을 기억하는 함수다
Function 생성자 함수로 함수를 생성하는 방식은 일반적이지 않으며 바람직하지도 않다.
ES6에서 도입된 화살표 함수는 => 를 사용해 좀 더 쉽게 함수를 선언할 수 있다.
화살표 함수는 무조건 익명 함수로 정의한다.
문법의 차이 말고도 동작에서의 차이점이 있다.
this바인딩
화살표 함수는 외부 스코프의 this를 상속한다.
콜백함수에서 유용
const obj = {
name: "화살표 함수",
log: function () {
const inner = () => {
console.log(this.name); // obj의 this를 사용
};
inner();
},
};
obj.log(); // "화살표 함수"
function은 this가 전역객체를 가리킴
// 전역 객체 정의
globalThis.name = "전역 객체 이름";
// 객체 정의
const obj = {
name: "객체 내부",
log: function () {
function inner() {
console.log(this.name); // 전역 객체의 this를 출력
}
inner(); // 기본적으로 전역 객체를 참조
},
};
obj.log(); // "전역 객체 이름"
생성자 함수 사용 가능 여부
화살표 함수는 생성자 new 사용 불가능
const ArrowFunc = () => {};
const instance = new ArrowFunc(); // 오류 발생
function 은 new 사용 가능
function Func() {
this.name = "생성자 함수";
}
const instance = new Func();
console.log(instance.name); // "생성자 함수"
객체 타입의 인수는 참조값이 복사되어 매개변수에 전달되기 때문에 외부에서 함수 몸체 내부로 전달한 참조값에 의해 원본 객체가 변경된다.
원본 객체가 훼손되는 것을 막는 법 : 객체를 불변 객체로 만들어사용, 마치 원시값처럼 변경 불가능한 값으로 동작하게 만드는 것이다.
불변 객체
Object.freeze()
const obj = Object.freeze({ a: 1, b: 2 });
// 객체 변경 시도
obj.a = 3; // 무시됨 (엄격 모드에서는 TypeError 발생)
obj.c = 4; // 무시됨
console.log(obj); // { a: 1, b: 2 }
const original = { a: 1, b: 2 };
const updated = { ...original, b: 3 };
console.log(original); // { a: 1, b: 2 }
console.log(updated); // { a: 1, b: 3 }
const updated = Object.assign({}, original, { b: 3 });
즉시 실행 함수
함수 정의와 동시에 즉시 호출되는 함수, 재호출 불가능
즉시 실행 함수는 반드시 ()로 감싸야 한다.
일반 함수처럼 값을 반환하거나, 인수를 전달할 수 있다.
// 익명 즉시 실행 함수
(function () {
var a = 3;
var b = 5;
return a * b;
}());
재귀함수
반복되는 처리를 위해 사용한다.
function countdown(n) {
if (n < 0) return ; //재귀함수 탈출 조건
console. log(n);
countdown(n - 1); 1/ 재귀 호출
}
countdown (10);
중첩함수(내부 함수)
함수 내부에 정의된 함수, 일반적으로 외부함수를 돕는 헬퍼함수의 역할을 한다.
외부 함수 : 중첩함수를 감싸는 함수
function outer() {
var x = 1;
// 중첩 함수
function inner() {
var y = 2;
// 외부 함수의 변수를 참조할 수 있다.
console. log(x + y); // 3
}
inner();
}
outer();
콜백함수
어떤 일을 반복 수행하는 repeat 함수를 정의
다른 함수의 인자로 전달되어, 특정 조건이나 시점에서 호출되는 함수
function greet(name, callback) {
console.log(`Hello, ${name}!`);
callback(); // 전달된 콜백 함수 호출
}
greet("Alice", () => {
console.log("Nice to meet you!");
});
// 출력:
// Hello, Alice!
// Nice to meet you!
const numbers = [1, 2, 3];
numbers.forEach(num => {
console.log(num * 2);
});
// 출력:
// 2
// 4
// 6
함수형 프로그래밍에서 어떤 외부 상태에 의존하지 않고, 변경하지도 않는, 부수효과가 없는 함수를 순수함수라 한다.
매개변수를 통해 함수 내부로 전달된 인수에게만 의존해 값을 생성해 반환한다.
외부 상태: 전여변수, 서버데이터, 파일, console, DOM 등
순수함수를 통해 부수 효과를 억제해 오류를 피하고 프로그램의 안정성을 높이려는 노력의 일환