[js] js Learn_함수

20210305

자바스크립트

자바스크립트 함수

  • 자바스크립트는 함수형 언어
  • 함수는 자바의 메서드와 같은 동작을 한다.

자바스크립트에서는 함수도 하나의 타입(datatype)입니다.

따라서 함수를 변수에 대입하거나, 함수에 프로퍼티를 지정하는 것도 가능합니다.

또한, 자바스크립트 함수는 다른 함수 내에 중첩되어 정의될 수도 있습니다.

  • 함수(function)란? 함수(function)란 하나의 특별한 목적의 작업을 수행하도록 설계된 독립적인 블록을 의미합니다.

이러한 함수는 필요할 때마다 호출하여 해당 작업을 반복해서 수행할 수 있습니다. (자바스크립트에서 블록이란 함수나 실행문의 중괄호({})로 묶여진 부분을 가리킵니다. )

함수의 정의

자바스크립트에서 함수의 정의는 function 키워드로 시작되며, 다음과 같은 구성요소를 가집니다.

  1. 함수의 이름

  2. 괄호 안에 쉼표(,)로 구분되는 함수의 매개변수(parameter)

  3. 중괄호({})로 둘러싸인 자바스크립트 실행문

20210115_222743

값의로서의 함수

  • 자바스크립트에서 함수는 문법적 구문일뿐만 아니라 값(value)이기도 합니다.

  • 따라서 함수가 변수에 대입될 수도 있으며, 다른 함수의 인수로 전달될 수도 있습니다.

다음 예제는 함수를 변수에 저장하여 사용하는 예제입니다.

function sqr(x) {                // 제곱의 값을 구하는 함수 sqr를 정의함.

    return x * x;

}

var sqrNum = sqr;                // 변수 sqrNum에 함수 sqr을 대입함.

document.write(sqr(4) + "<br>"); // 함수 sqr을 호출함.

document.write(sqrNum(4));       // 변수 sqrNum를 함수처럼 호출함.

함수 유효범위(function scope)

  • 대부분의 프로그래밍 언어에서는 블록 내에서 정의된 변수를 블록 외부에서는 접근할 수 없습니다.

  • 블록(block)이란 코드 내에서 중괄호({})로 둘러싸인 부분을 가리킵니다.

이러한 블록을 기준으로 하는 유효 범위를 블록 단위의 유효 범위라고 합니다.
  • 하지만 자바스크립트는 다른 언어와는 달리 함수를 블록 대신 사용합니다.

  • 자바스크립트에서 함수는 자신이 정의된 범위 안에서 정의된 모든 변수 및 함수에 접근할 수 있습니다.

  • ‘전역 함수’는 모든 전역 변수와 전역 함수에 접근할 수 있습니다.

  • 반면, 다른 함수 내에 정의된 ‘내부 함수’는 그 함수의 부모 함수(parent function)에서 정의된 모든 변수 및 부모 함수가 접근할 수 있는 모든 다른 변수까지도 접근할 수 있습니다.

// x, y, name을 전역 변수로 선언함.

var x = 10, y = 20;

// sub()를 전역 함수로 선언함.

function sub() {

    return x - y;     // 전역 변수인 x, y에 접근함.

}

document.write(sub() + "<br>");

// parentFunc()을 전역 함수로 선언함.

function parentFunc() {

    var x = 1, y = 2; // 전역 변수와 같은 이름으로 선언하여 전역 변수의 범위를 제한함.

    function add() {  // add() 함수는 내부 함수로 선언됨.

        return x + y; // 전역 변수가 아닌 지역 변수 x, y에 접근함.

    }

    return add();

}

document.write(parentFunc());

함수 호이스팅(hoisting)

자바스크립트에서 함수의 유효 범위라는 것은 함수 안에서 선언된 모든 변수는 함수 전체에 걸쳐 유효하다는 의미입니다.

그런데 이 유효 범위의 적용이 변수가 선언되기 전에도 똑같이 적용됩니다.

이러한 자바스크립트의 특징을 함수 호이스팅(hoisting)이라고 합니다.
즉, 자바스크립트 함수 안에 있는 모든 변수의 선언은 함수의 맨 처음으로 이동된 것처럼 동작합니다.
var globalNum = 10;     // globalNum을 전역 변수로 선언함.

function printNum() {

    document.write("지역 변수 globalNum 선언 전의 globalNum의 값은 " + globalNum + "입니다.<br>"); // ①

    var globalNum = 20; // globalNum을 지역 변수로 선언함. // ②

    document.write("지역 변수 globalNum 선언 후의 globalNum의 값은 " + globalNum + "입니다.<br>");

}

printNum();

위의 예제 ①의 시점에서는 변수 globalNum가 전역 변수를 가리킨다고 생각하기 쉽습니다.

하지만 자바스크립트 내부에서는 함수 호이스팅에 의해 다음과 같이 코드가 변경되어 처리됩니다.

var globalNum = 10;

function printNum() {

    var globalNum; // 함수 호이스팅에 의해 변수의 선언 부분이 함수의 맨 처음 부분으로 이동됨.

    document.write("지역 변수 globalNum 선언 전의 globalNum의 값은 " + globalNum + "입니다.<br>");

    globalNum = 20;

    document.write("지역 변수 globalNum 선언 후의 globalNum의 값은 " + globalNum + "입니다.<br>");

}

printNum();

위의 예제 ①의 시점에서는 globalNum라는 지역 변수가 선언만 되어 있고, 아직 초기화만 안 된 상태입니다.

따라서 이때 globalNum 변수에 접근하면 아직 초기화되지 않은 변수에 접근했으므로, undefined 값을 반환하게 됩니다.

실제로 변수가 초기화되는 시점은 원래 코드에서 변수가 선언된 ②의 시점입니다.

  • 자바스크립트에서는 함수 호이스팅이 자동으로 수행되지만, 항상 함수 블록의 첫 부분에 변수를 선언하는 것이 좋습니다.

### 매개변수와 인수

  • 자바스크립트는 함수 정의시 매개변수 정의시 따로 타입 명시 하지 않습니다.
  • 함수 호출시에도 인수(argument)로 전달된 값에 대해 어떠한 타입 검사도 하지 않습니다.

  • 함수를 호출할 때 함수의 정의보다 적은 수의 인수가 전달되더라도, 다른 언어와는 달리 오류를 발생시키지 않습니다.

  • 이 같은 경우 자바스크립트는 전달되지 않은 나머지 매개변수에 자동으로 undefined 값을 설정합니다.
매개변수(parameter)란 함수의 정의에서 전달받은 인수를 함수 내부로 전달하기 위해 사용하는 변수를 의미합니다.
인수(argument)란 함수가 호출될 때 함수로 값을 전달해주는 값을 말합니다.
function addNum(x, y, z) { // x, y, z라는 3개의 매개변수를 가지는 함수 addNum()을 정의함.

    return x + y + z;

}


addNum(1, 2, 3); // 인수로 1, 2, 3을 전달하여 함수를 호출함. -> 6
addNum(1, 2);    // 인수로 1, 2을 전달하여 함수를 호출함. -> NaN
addNum(1);       // 인수로 1을 전달하여 함수를 호출함. -> NaN
addNum();        // 인수로 아무것도 전달하지 않고 함수를 호출함. -> NaN

arguments 객체

  • 만약 함수의 정의보다 더 많은 수의 인수가 전달되면, 매개변수에 대입되지 못한 인수들은 참조할 방법이 없게 됩니다.

  • 하지만 arguments 객체를 이용하면, 함수로 전달된 인수의 총 개수를 확인하거나, 각각의 인수에도 바로 접근할 수 있습니다.

  • arguments 객체는 함수가 호출될 때 전달된 인수를 배열의 형태로 저장하고 있습니다.

  • 첫 번째 인수는 arguments[0]에 저장되며, 다음 인수는 arguments[1]에 저장됩니다.

  • 또한, 인수의 총 개수는 arguments 객체의 length 프로퍼티에 저장됩니다.

다음 예제의 addNum() 함수는 전달받는 인수의 개수에 상관없이 언제나 정상적인 계산을 수행합니다.

function addNum() {
    var sum = 0;                                // 합을 저장할 변수 sum을 선언함.
    for(var i = 0; i < arguments.length; i++) { // 전달받은 인수의 총 수만큼 반복함.
        sum += arguments[i];                    // 전달받은 각각의 인수를 sum에 더함.
    }
    return sum;
}

addNum(1, 2, 3); // 6
addNum(1, 2);    // 3
addNum(1);       // 1
addNum();        // 0
addNum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 55
  • arguments 객체는 배열과 비슷할 뿐, 실제로 Array 객체는 아닙니다.

숫자로 된 인덱스와 length 프로퍼티만을 가지고 있을 뿐, 모든 것을 배열처럼 다룰 수는 없습니다.

디폴트 매개변수와 나머지 매개변수

디폴트 매개변수(default parameter)

디폴트 매개변수란 함수를 호출할 때 명시된 인수를 전달하지 않았을 경우에 사용하게 될 기본값을 의미합니다.

자바스크립트에서 매개변수의 기본값은 undefined 값으로 설정되어 있습니다.

function mul(a, b) {

    // 인수가 한 개만 전달되었을 때 나머지 매개변수의 값을 undefined 값이 아닌 1로 설정함.

    b = (typeof b !== 'undefined')  ? b : 1;

    return a * b;

}
mul(3, 4); // 12
mul(3);    // 3

에서 디폴트 매개변수 사용시

function mul(a, b = 1) { // 인수가 한 개만 전달되면 나머지 매개변수의 값을 언제나 1로 설정해 줌.
    return a * b;
}
mul(3, 4); // 12
mul(3);    // 3

나머지 매개변수(rest parameter)

  • 나머지 매개변수는 생략 접두사(…)를 사용하여 특정 위치의 인수부터 마지막 인수까지를 한 번에 지정할 수 있습니다.

  • 다음 예제는 첫 번째 인수에서 두 번째 인수부터 마지막 인수까지를 뺀 후 그 결과를 반환하는 예제입니다.

function sub() {
    var firstNum = arguments[0];                  // 첫 번째 인수에서
    for(var i = 0; i < arguments.length-1; i++) { // 두 번째부터 마지막 인수까지를
        firstNum -= arguments[i+1];               // 뺌.
    }
    return firstNum;
}

sub(10, 2, 3);    // 10 - 2 - 3 = 5
sub(10, 1, 5, 8); // 10 - 1 - 5 - 8 = -4

여기서 나머지 매개변수 사용시 직관적으로 정의가 가능하다.

// 첫 번째 인수를 변수 firstNum에 저장하고 나머지 인수들은 배열 restArgs에 저장함.

function sub(firstNum, ...restArgs) {
    for(var i = 0; i < restArgs.length; i++) {
        firstNum -= restArgs[i];
    }
    return firstNum;
}
sub(10, 2, 3);    // 10 - 2 - 3 = 5
sub(10, 1, 5, 8); // 10 - 1 - 5 - 8 = -4
참조한 곳

http://www.tcpschool.com/javascript/js_function_parameterArgument

https://www.w3schools.com/js/default.asp

기타 미리 정의된 전역함수 보려면 : http://www.tcpschool.com/javascript/js_function_predefinedFunction





© 2021.03. by yacho

Powered by github