Javascript

함수

하루 2021. 12. 28. 16:28

함수

함수는 특정 코드를 하나의 명령으로 실행할 수 있게 해주는 기능이다. 함수를 만들 때는 function 키워드를 사용하며, 함수에서 어떤 값을 받아올지 정해주는데 이를 파라미터(매개변수) 라고 부른다.

 

차이점: 선언적 함수와 익명함수 변수에 할당

  • 선언적 함수 function hello( ) { }
  • 익명함수를 만들어 변수에 할당 const hello = function ( ) { }

선언적 함수를 통해 호출한 함수는 선언한 함수와 순서 상관없이 호출하면 출력된다.

hello1();

function hello1() {
  console.log('hello1');
}

hello1();  // hello1

 

익명함수를 변수에 할당한 경우에는 var의 hoisting에 의한 문제가 발생한다.

console.log(hello2);     // undefined
hello2();               // TypeError: hello2 is not a function -- var의 hoisting 에 의한 문제
hello3();              // ReferenceError: hello3 is not defined

var hello2 = function() {
  console.log('hello2');
}

const hello3 = function() {
  console.log('hello3');
}

 

생성자 함수로 함수 만들기 (new)

const hello = new Function( )

  • new Function('인자1', '인자2', ..., '함수의 바디');
  • 함수도 객체의 한 종류이기 때문에 객체를 생성하는 생성자 함수 new를 이용해서 함수를 만들 수 있다.
  • Function의 매개변수로 들어가는 인자와 함수의 바디의 경우 문자열로 들어간다.
  • 선언적 방식이 아니므로 console 이 생성자 함수를 만들기 이전에 작성된다면 오류가 난다.
const sum = new Function('a', 'b', 'c', 'return a + b + c');
console.log(sum(1, 2, 3));  // 6

 

function과 new Function의 차이점

new Function의 변수가 같은 블럭 내에 소속되어 있는 지역변수에 접근할 수 없다. (같은 변수 인식X)

대신 global 전역변수를 이용해서 a 를 지정해주면 new Function의 변수 a로 global.a 의 값을 사용한다.

global.a = 0;

// new Function
{
  const a = 1;
  const test = new Function('return a');
  console.log(test());   // 0
}


// 익명의 함수를 변수에 할당
{
  const a = 2;
  const test = function() {
    return a;
  }
  
  console.log(test());   // 2
}

 

화살표 함수

( ) => { } arrow function (es6)

  • 화살표의 좌측에는 함수의 파라미터, 화살표의 우측에는 코드 블럭이 들어온다.
  • 익명함수를 만들어 변수에 할당하는 형태로 선언적 방식을 사용할 수 없다.

 

*화살표 함수와 일반 function으로 만든 함수의 차이점

화살표 함수에서 가르키는 this와 function에서 가르키는 this가 서로 다르다.

const hello1 = () => {
  console.log('hello1');
}
hello1();   // hello1

const hello2 = name => {
  console.log('hello2', name);
}
hello2();   // hello2 undefined

const hello3 = (name, age) => {
  console.log('hello3', name, age);
}
hello3();   // hello3 undefined undefined

const hello4 = name => {
  return `hello4 ${name}`;
}
const hello5 = name => `hello5 ${name}`;

 

생성자 함수를 이용한 새로운 객체 만들기 (Person)

  • Person의 인자로 넣어준 name과 age를 객체가 property로 가질 수 있도록 this.name=name; this.age=age;로 설정
  • Person이라는 틀을 이용해서 여러가지 사람 객체를 만드는 것이다. (붕어빵 틀로 붕어빵을 계속 찍어내는 것처럼)
  • 이렇게 할 수 있는 이유는 this의 역할이 객체가 만들어졌을 때 그 객체를 가리키는 용도로 사용되기 때문이다.
  • 때문에 같은 함수지만 arrow function에서는 함수 안에 this가 생성되지 않아서 새로운 객체를 만들어내는 생성자 함수로 사용할 수 없다.
function Person(name, age) {
  console.log(this);   // Person {}
  this.name = name;
  this.age = age;
}

const p = new Person('Mark', 37);
console.log(p, p.name, p.age);   // Person { name: 'Mark', age: 37 } 'Mark' 37

const a = new Person('Anna', 26);
console.log(a, a.name, a.age);   // Person { name: 'Anna', age: 26 } 'Anan' 26

const Cat = (name, age) => {
  console.log(this);   // Typeerror: Cat is not a constructor
  this.name = name;
  this.age = age;
}

const c = new Cat('냥이', 1);

 

함수 안에서 함수를 만들어 리턴

function plus(base) {
  return function(num) {
    return base + num;
  }
}

const plus5 = plus(5);
console.log(plus5(10));  // 15

const plus7 = plus(7);
console.log(plus7(8));   // 15

 

함수를 호출할 때, 인자로 함수를 사용

function hello(c) {
  console.log('hello');  // hello 출력 후 함수 c() 실행
  c();
}

hello(function() {
    console.log('콜백');   // 콜백
});

hello( ) 함수 선언

hello( function( ) { console.log('콜백'); } ) 의 경우 인자로 함수를 사용하였다.

hello( ) 함수의 파라미터는 c 이므로 c 위치에 함수를 대입하면 된다.

hello( ) 함수가 호출되면 가장 먼저 hello가 출력되고 이후 c( ) 위치에 함수가 실행되어 콜백이 출력된다.