본문 바로가기

JAVASCRIPT

함수

함수

재사용을 하기 위한 큰 코드 뭉치 단위이며, function 생성자로부터 생성되는 객체. 호출할 수 있음
함수는 정의하는 것만으로 내부 코드 실행이 되지 않기에 반드시 함수를 호출해야함

함수의 구성요소

function add(x, y) { 
     const result = x + y;
     return result;
}
add (2,  3) // 5
// 상단 코드 설명
1. add라는 **이름** 을 갖는 함수
2. x, y **매개변수(parameter)** 
3. return **반환값(return value)**
4. add(2, 3); **호출(function call)**
// 상단 코드 실행 순서
// 1. 함수 정의
function add(x, y) { 
     return x + y; // 3. 함수실행
}

// 2. 함수 호출
const result = add(2,  3); 

// 4. 나머지 코드 실행
console.log(result);

매개변수와 인수

매개변수는 변수의 일종으로, 함수 호출 시마다 인수가 매개변수에 대입. 매개변수는 바깥에서 선언된 변수와는 관계없는 독립적인 변수

function reassign(x) {
     x  = 2;
     return x;
}

const y = 1;
const result = reassign(y);
console.log(y); // 1
console.log(result); // 2

return

return 구문은 함수의 반환값을 결정
return 키워드 바로 다음에 오는 값이 함수 호출의 결과값으로 반환되며, 반환되는 즉시 함수 실행이 끝남
return 뒤에 값이 없거나 return구분을 쓰지 않으면 함수는 undefined 를 반환

function add(x, y) {
     return x + y;
     console.log('이 부분은 실행되지 않습니다.')
}

add(1, 2); // 3 (3 외에 따로 출력되는 내용이 없음)

// return 잘못 쓸 경우
function returnUndefined()  {
     return;
}

function noReturn() {}
return Undefined();  // undefined
noReturn(); // undefined

 

스코프(Scope) & 스코프 연쇄(Scope Chain)

스코프(Scope)

함수의 매개변수를 비롯한 모든 변수들은 특별한 성질을 갖으며, 변수의 코드의 일정 범위 안에서만 유효함

// 매개변수와 같이 함수 안에서 정의된 변수는 함수 바깥에서는 접근할 수 없기 때문에 함수안에서만 사용할 수 있음  
function add(x, y) {
     return x + y;
}

add(2, 3);
console.log(x); // 에러!

스코프 연쇄(Scope Chain)

식별자와같은 이름을 갖는 변수를 현재 스코프에서 찾아보고, 변수가 존재하면 그것을 그대로 사용
만약 현재 스코프에서 변수를 찾지 못하면 바로 바깥쪽 스코프에서 변수를 찾는 과정을 뜻함
가장 바깥에 있는 스코프를 전역 스코프(global scope) 라고 부름

const five = 5; // 전역스코프

function add5(x) {
     function add(y){
          return x + y;
     }
     return add(five);
}

add5(3); // 8

변수 가리기(Vacriable Shadowing)

바깥쪽 스코프에 존재하는 변수와 같은 이름을 같는 변수를 안쪽 스코프에서 재정의 할 수 있으며,
그렇게 되면 안쪽 스코프에서 바깥쪽 스코프에 있는 이름이 무시하는 현상을 뜻함

const x =3;

function add5(x) { // 'x'라는 변수가 다시 정의됨
     function add(x, y) { // 'x'라는 변수가 다시 정의됨
          return x + y;
     }
     return add(x, 5);
}

add5(x);

어휘적 스코핑(Lexical Scoping)

스코프는 코드가 작성된 구조 에 의해서 결정되는 것

function add5(x) {
     const five = 5;
     function add(x) {
          return five + x;
     }
     return add(x);
}

값으로서의 함수

function add(x, y) {
     return x + y;
}

const plus = add;
plus(1, 2); // 3
// 함수를 배열이나 객체에 넣기
function add(x, y) {
     return x +  y;
}

[add];

{addFunc: add};

// 함수를 인수로 넘기기
function isEven(x) {
     return x  % 2 === 0;
}

[1, 2, 3, 4, 5].filter(isEven); // [2, 4]

// 함수에서 함수 반환하기
function createEmptyFunc() {
     function func() {}
     return func;
}

익명함수(Anonymous Function)

익명 함수는 함수를 만든 쪽이 아니라 다른 쪽에서 그 함수를 호출할 때 많이 사용
대표적으로 함수를 인수로 넘겨줄 때

// 두 수를 더해서 반환하는 익명함수
function(x, y) {
     return x + y;
}
// 위의 익명 함수는 이름이 없어서 이름을 가지고 호출을 할 수 없음
// 호출을 하려면 변수에 저장한 후에 변수의 이름을 통해 호출해야 함

const add = function(x, y) {
     return x + y;
} 
add(1, 2); // 3
[1, 2, 3, 4, 5].filter(function (x) {
      return x % 2 === 0;
}); // [2, 4]

화살표 함수(Arrow Function)

ES2015에서 도입된 새로운 유형의 함수, 화살표 함수는 (매개변수 목록) => {함수 내용}과 같은 문법을 통해 정의.

  • 화살표 함수의 매개변수가 하나라면 괄호 생략
  • 화살표 함수의 내부가 하나의 구문으로 이루어졌다면, 중괄호 생략. 구문의 결과값이 곧 함수의 반환값이 됨
  • 생성자로 사용될 수 없음
  • 스스로의 this, arguments, super를 가지지 않음
  • 화살표 함수 내부에서 yield 키워드를 사용할 수 없음
// 여기에서 x + y 는 바로 반환
const add = (x, y) => x + y;

// 바로 반환시키지 않고 function 키워드를 통한 함수 정의처럼 여러 구문을 사용하려면 curly braces({...}) 로 둘러싸주어야함
// '=>' 다음 부분을 중괄호로 둘러싸면, 명시적으로 'return' 하지 않는 한 아무것도 반환되지 않음

const add = (x, y)  => {
     const result = x + y;
     return result;
}
// 매개변수와 하나밖에 없다면, 매개변수 부분의 괄호를 쓰지 않아도 무방
const negate = x => !x;
// 화살표 함수는 표기법이 간단하기 때문에 익명 함수를 다른 함수의 인수로 넘길 때 주로 사용
[1, 2, 3, 4, 5].filter(x => x % 2 === 0);

arguments와 나머지 매개변수 (Rest Parameters)

arguments

function 구문을 통해 생성된 함수가 호출될 때는, arguments라는 변수가 함수 내에 자동 생성
arguments는 유사 배열 객체(array-like object)이자 반복 가능한 객체(iterable object)
ES2015에서 도입된 나머지 매개변수(rest parameters) 문법으로 인해 사용하지 않음
인수의 개수에 제한이 없는 함수를 정의하는 데에 사용

function add(x, y) {
    console.log(arguments[0], arguments[1])
    return x + y;
}
add (1,2); // 12

나머지 매개변수 (Rest Parameters)

...을 붙여주면, 해당 매개변수에 모든 인수가 저장
실제 배열이기 때문에, 배열의 메소드를 활용할 수 있음
마지막 매개변수에만 사용할 수 있음

function sum(...ns) {
  // `for...of` 루프 대신에 `reduce` 메소드를 사용해서 합계를 구할 수 있음
  return ns.reduce((acc, item) => acc + item, 0);
}

sum(1, 2, 3, 4); // 10

매개변수의 기본값 (Default Parameter)

기본 함수 매개변수를 사용하면 값이 없거나 undefined가 전달될 경우 매개변수를 기본값으로 초기화 할 수 있음

// 'Mary'가 `name` 매개변수의 기본값
function hello(name = 'Mary') {
  // 코드가 훨신 더 깔끔해졌습니다!
  console.log(`Hello, ${name}!`);
}

hello('John'); // Hello, John!
hello(); // Hello, Mary!
hello(undefined); // Hello, Mary!

this

this는 생성자 혹은 메소드에서 객체를 가리킬 때 사용하는 키워드, 때에 따라 다른 값을 가리킴

// 전역 객체를 가리키는 this
function printThis() {
  console.log(this);
}

printThis(); // Window { ... }

this 바뀌치기

우리가 원하는 값을 가리키게 만들 수도 있는데, 함수 객체의 bind, call, apply 메소드를 사용하면 됨

  • bind : 메소드의 인수로 넘겨준 값이 this가 되는 새로운함수를 반환
  • call & apply : 새로운 함수를 만들지 않고도 임시적으로 this를 바꿔버릴 수 있음
function printGrade(grade) {
  console.log(`${this.name} 님의 점수는 ${grade}점입니다.`);
}

const student = {name: 'Mary'};
const printGradeForMary = printGrade.bind(student);

printGradeForMary(100); // Mary 님의 점수는 100점입니다.

'JAVASCRIPT' 카테고리의 다른 글

제어 구문  (0) 2019.07.23
배열  (0) 2019.07.23
null과 undefined  (0) 2019.07.19
boolean 타입  (0) 2019.07.18
string 타입  (0) 2019.03.20