본문 바로가기

Kakao Cloud School/카카오클라우드스쿨 수업

[Javascript] 함수

Javascript의 함수는 객체이다


function(함수)

일련의 과정을 수행하기 위한 statement를 { }(중괄호)를 이용해서 하나의 실행 단위로 만들어 놓은 것이다.

함수를 사용하려면 함수를 정의하고 호출(call, invoke)해서 사용한다.

함수 사용 목적

반복적인 코드를 함수화 시키면

1. 유지보수가 좋다.
2. 오류 발생률이 적어지고 그에따라 신뢰도가 높아진다.

함수의 정의(definition)


이름이 있는 함수는 named function (기명함수)

이름이 없는 함수는 anonymous function (익명함수) - literal로 변수에 저장할 때 많이 사용한다.

기명함수(이름 있는 함수)

function add(x, y){ // 함수이름과 파라미터(매개변수)
	return x + y; // 리턴값
}
add(3, 5); // 인수(인자)(argument)

함수 literal

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

함수 이름은 식별자다

함수 이름은 식별자(identify)이다. 따라서 식별자 명령 규칙(naming rule)을 따라야 한다.

함수 이름은 함수 내부에서만 사용이 가능하다

함수 이름은 함수 내부에서만 사용이 가능하다. (외부로 노출되지 않는다.)

 

var myFunc = function add(x, y){
    return x + y;
}
console.log(add(3,5)); // add is not defined
console.log(myFunc(3,5));

※ 함수를 정의하는 방법

1. 함수 선언문
2. 함수 표현식
3. Function 생성자 함수
4. ES6에서 생긴 화살표 함수(Arrow function)

함수 선언문

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

함수 표현식

var myFunc = function(x, y) {
	return x + y;
}

Function 생성자 함수 (권장하지 않음)

var add = new Function('x', 'y', 'return x+y');

화살표 함수 (Arrow function)

var add = (x, y) => x + y;

함수 선언문 vs 함수 표현식 hoisting


// 함수 선언문
function foo(){
    console.log('foo 함수');
}

// 함수 리터럴(표현)
(function bar(){
    console.log('bar 함수');
})

foo(); // foo 함수 출력
bar(); // 에러 발생

 

함수 foo는 함수 선언문이다. 코드가 실행될 때 스크립트 엔진이 코드를 한 번 훑는다.

그 과정에서 식별자를 판단한다. 스크립트 엔진은 함수 선언문을 발견하면 함수이름과 동일한 묵시적 변수를 만든다. 

foo( )는 foo라는 보이지 않은 묵시적 변수를 호출하기 때문에 foo 실행 결과가 나타나게 된다.

 

함수 bar 부분을 보면 ( )에 감싸져 있다. 이는 (3+5)*2와 같은 의미를 가지는 ( )와 같다.

함수를 계산하라는 뜻이며, 자바스크립트 엔진은 함수를 수행한 결과를 값으로 평가하게 된다.

따라서 bar( )는 에러가 발생하게 된다.

 

// 함수 선언문
function foo(){
    console.log('foo 함수');
}

// 함수 리터럴(표현)
add = function bar(){
    console.log('bar 함수');
}

foo(); // foo 함수 출력
bar(); // 에러 발생

 

선언적 함수는 런타임 이전에 만들어지고, 함수 표현식의 경우는 코드가 런타임 이후에 만들어진다.

 

foo(); // 호출된다.
add(); // Error, 아예 함수가 아니다 - 왜? add는 undefined 값을 가지고 있음

// 함수 선언문
function foo(){
    console.log('foo 함수');
}

// 함수 리터럴(표현)
var add = function bar(){
    console.log('bar 함수');
}

 

함수 표현식은 순서를 잡기 때문에 표현식 자체를 위로 올려 함수를 지정해 사용하는 것이 더 맞는 표현이라 할 수 있다.

 

1. 코드를 읽으면서 함수 선언문을 보고 함수 이름과 똑같은 변수를 하나 만든다.

    (묵시적 - script engine에 의해 자동으로 만들어진다.)

    함수 이름과 똑같은 변수가 특정 메모리를 가리킨다.

2. 특정 메모리에 foo 함수 내용을 넣고, 1번에서 변수가 가르키는 메모리에 함수 내용이 적히 주소를 넣는다.

3. 코드를 읽으면서 add 식별자를 특정 메모리를 가리키게 하고 undefined를 넣는다.

4. 코드가 실행되면 bar 함수 내용을 특정 메모리에 넣고 add 식별자가 가르키는 메모리 값을 bar 함수 내용이 적힌 메모리 주소로 바꾼다.

 

※ 선언적 함수는 런타임 이전에 만들어지고, 함수 표현식의 경우는 코드가 런타임 이후에 만들어진다.

 

함수 호출 (call, invoke)


함수는 함수 이름으로 호출하지 않는다. 함수는 함수에 대한 식별자(identifier)를 이용해서 호출한다.

자바스크립트의 함수 호출 특징

1. Javascript의 함수는 Overloading이 발생하지 않는다.

    - 인자의 개수가 틀려도 호출이 가능하다.

 

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

console.log(add(2)); // NaN
console.log(add(2, 3, 4)); // 5
// 함수 선언문
function add(){
	// arguments [2, 3, 4]
    let sum = 0;
    // arguments는 유사배열객체(Array-like-Object)
    // length property를 가지고 배열처럼 index를 이용해서
    // access 가능, 당연히 순환 가능
    for (let i = 0; i < arguments.length; i++) {
        sum += arguments[i];
    }
    return sum;
}

console.log(add(2)); // 2
console.log(add(2, 3, 4)); // 9

 

2. 함수에 return이 없는 경우라면 암묵적으로 undefined가 return 된다.

IIFE (Immediatly Invoked Function Expression) - 즉시 실행 함수

함수를 선언함과 동시에 call(invoke)하는 것이다. 함수의 재사용이 안된다.

한 번 수행하고 버릴것이기 때문에, 일반적으로 익명함수로 사용한다.

 

// IIFE(즉시 실행 함수)
(function (){
    let x = 10;
    let y = 20;

    console.log(x + y);
}());

 

왜 사용하나요?

가장 대표적인 예로, 전역변수를 지역변수화 할 수 있다.

중첩함수 (내부함수)


중첩함수( nested function ) 내부함수( inner function )

중첩함수를 가지고 있는 바깥쪽 함수는 외부 함수( outer function )

 

스코프 체인(Scope-chain)

변수를 찾기 위해 스코프에서 상단 스코프로 그리고 그 상단 스코프로 올라가면서 최상단인 전역 스코프까지 올라가서 찾아야한다. 따라서, 우리가 코드를 짤 때 전역 스코프를 많이 사용하면 찾는 시간이 느려지게 된다.

 

var x = 100; // global scope (전역변수)
var y = 100; // global scope (전역변수)

// outer function
function outer(){
    let x = 0; // function level scope(지역변수)

    // inner function
    function inner(){
        let x = 10; // function level scope(지역변수)
        console.log(y);
    }
}

// 모든 스코프는 체인으로 연결되어 있다.

Javascript의 함수는 일급객체이다


first-class citizen(Object) 일급객체의 조건

1. 익명의 literal로 생성이 가능하다 - 동적으로 생성이 가능하다

2. 객체가 변수나 자료구조에 저장이 가능하다

3. 객체를 다른 함수의 인자로 전달이 될 수 있다. 

4. 함수의 리턴값으로 객체를 사용할 수 있다.

 

// 잘 만든 함수가 존재
// 그런데 이 함수의 기능을 변경(추가)

// 1. 원래 있는 함수를 수정한다.
// 2. 함수를 새로 추가해서 만든다.
// 3. 함수를 추상화 시켜서 인자로 받아서 사용한다.

// 고차함수(Higher-Ordered Function)
// n은 숫자고, f는 특정 일을 하는 함수를 받는 인자
function repeat(n, f) {
    for (var i = 0; i < n; i++){
            f(i);
    }
}

// 콜백함수(callback function)
let logAll = function(i){
    console.log(i);
}

// 콜백함수(callback function)
let logOdd = function(i){
    if (i % 2){
        console.log(i);
    }
}

repeat(5, logAll);
repeat(5, logOdd);

콜백함수(callback function)

콜백함수는 함수 내에서 함수를 호출할 때 사용되는 함수를 의미한다.

고차함수(Higher-ordered function)는 그런 콜백함수를 묶어서 실행시킬 수 있는 함수를 말한다.

'Kakao Cloud School > 카카오클라우드스쿨 수업' 카테고리의 다른 글

[Javascript] 데이터 타입  (0) 2022.07.05
[Javascript] History of Javascript, ES6  (0) 2022.07.05
[Javascript] 객체(2)  (0) 2022.07.05
[Javascript] 스코프  (0) 2022.07.05
[Javascript] 객체  (0) 2022.07.05