Languages/JavaScript

[HUFS/GnuVil] #5 함수

성중 2022. 9. 20. 15:38

함수

매개변수(parameter) ~ 인수(argument)

// 함수 선언문
function add(x, y) {
  return x + y;
}

함수 선언문은 생성된 함수 이름과 동일한 식별자를 암묵적으로 생성하고 함수 객체를 할당한다

 

// 함수 표현식 (함수 리터럴을 변수에 할당)
var sub = function (x, y) {
  return x - y;
};

자바스크립트 함수는 객체 타입의 값으로, 함수 리터럴로 생성해 변수에 할당할 수도 있다

* 함수 선언문은 표현식이 아닌 문으로 변수에 할당할 수 없다!

 

// 함수 선언문은 함수 이름을 생략할 수 없다.
function (x, y) {
  return x + y;
}
// SyntaxError: Function statements require a function name

함수 선언문은 이름을 생략할 수 없다는 점만 제외하면 형태가 함수 리터럴과 동일하다

 

// 함수 참조
console.dir(add); // ƒ add(x, y)
console.dir(sub); // undefined

// 함수 호출
console.log(add(2, 5)); // 7
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;
};

두 방식은 함수의 생성 시점이 달라 변수 호이스팅에 의한 차이가 있다

 

var add2 = (function () {
  var a = 10;
  return new Function('x', 'y', 'return x + y + a;');
}());

console.log(add2(1, 2)); // ReferenceError: a is not defined

Function 생성자도 있지만 외부 변수를 참조하지 못하기 때문에 바람직하지 않다

 

// 화살표 함수
const add = (x, y) => x + y;
console.log(add(2, 5)); // 7

화살표 함수는 오로지 함수의 기능을 하기 위해 간소화된 형태이다

* 생성자 함수로 사용할 수 없고, 기존 함수와 this 바인딩 방식이 다르고, 프로토타입 프로퍼티가 없으며 arguments 객체를 생성하지 않는다

 

$.ajax({
  method: 'POST',
  url: '/user',
  data: { id: 1, name: 'Lee' },
  cache: false
});

매개변수가 3개를 넘지 않는 것을 권장하기에, 3개 이상부터는 객체로 만들어서 넣어주자

 

값에 의한 호출과 참조에 의한 호출

// 매개변수 primitive는 원시값을 전달받고, 매개변수 obj는 객체를 전달받는다.
function changeVal(primitive, obj) {
  primitive += 100;
  obj.name = 'Kim';
}

// 외부 상태
var num = 100;
var person = { name: 'Lee' };

console.log(num); // 100
console.log(person); // {name: "Lee"}

// 원시값은 값 자체가 복사되어 전달되고 객체는 참조값이 복사되어 전달된다.
changeVal(num, person);

// 원시값은 원본이 훼손되지 않는다.
console.log(num); // 100

// 객체는 원본이 훼손된다.
console.log(person); // {name: "Kim"}

함수에 전달된 원시 값은 원본이 훼손되지 않지만 객체는 원본이 훼손된다

 

// 익명 즉시 실행 함수
(function () {
  var a = 3;
  var b = 5;
  return a * b;
}());

즉시 실행 함수로 함수를 정의와 동시에 1회만 호출할 수도 있다

 

// 외부에서 전달받은 f를 n만큼 반복 호출한다
function repeat(n, f) {
  for (var i = 0; i < n; i++) {
    f(i); // i를 전달하면서 f를 호출
  }
}

var logAll = function (i) {
  console.log(i);
};

// 반복 호출할 함수를 인수로 전달한다.
repeat(5, logAll); // 0 1 2 3 4

var logOdds = function (i) {
  if (i % 2) console.log(i);
};

// 반복 호출할 함수를 인수로 전달한다.
repeat(5, logOdds); // 1 3

다른 함수에 인수로 넘겨주는 함수를 콜백(callback) 함수라고 한다

* 전달받은 함수는 고차(higher-order) 함수

 

// 콜백 함수를 사용하는 고차 함수 map
var res = [1, 2, 3].map(function (item) {
  return item * 2;
});

console.log(res); // [2, 4, 6]

// 콜백 함수를 사용하는 고차 함수 filter
res = [1, 2, 3].filter(function (item) {
  return item % 2;
});

console.log(res); // [1, 3]

// 콜백 함수를 사용하는 고차 함수 reduce
res = [1, 2, 3].reduce(function (acc, cur) {
  return acc + cur;
}, 0);

console.log(res); // 6

배열 고차 함수들은 콜백 함수를 받는다

 

var count = 0; // 현재 카운트를 나타내는 상태

// 순수 함수 increase는 동일한 인수가 전달되면 언제나 동일한 값을 반환한다.
function increase(n) {
  return ++n;
}

// 순수 함수가 반환한 결과값을 변수에 재할당해서 상태를 변경
count = increase(count);
console.log(count); // 1

count = increase(count);
console.log(count); // 2

var count2 = 0; // 현재 카운트를 나타내는 상태: increase 함수에 의해 변화한다.

// 비순수 함수
function increase2() {
  return ++count2; // 외부 상태에 의존하며 외부 상태를 변경한다.
}

// 비순수 함수는 외부 상태(count)를 변경하므로 상태 변화를 추적하기 어려워진다.
increase2();
console.log(count2); // 1

increase2();
console.log(count2); // 2

순수(pure) 함수는 동일한 인수가 전달되면 언제나 동일한 값을 반환하고, 비순수(impure) 함수는 외부 상태에 의존하여 외부 상태를 변경한다

* 비순수 함수는 상태 변화의 추적이 어려워 오류 발생의 원인이 될 수 있다

 

 내용은 위키북스의 '모던 자바스크립트 Deep Dive' 바탕으로 작성되었습니다.