기본 함수 개념

이 단원에서는 기본적인 함수 정의 및 호출 방법에 대해 설명합니다.

세부 목차

함수 호출
함수 정의
함수 명령문
함수 표현식
명령문과 표현식 간에 선택
함수에서 값 반환
중첩 함수

함수 호출

함수 식별자 뒤에 괄호 연산자(())를 사용하여 함수를 호출합니다. 함수에 전달하려는 모든 매개 변수를 괄호 연산자를 사용하여 둘러쌉니다. 예를 들어, 이 설명서 전체에서 Flash Player API의 최상위 함수인 trace()를 사용합니다.

trace("Use trace to help debug your script");

매개 변수 없이 함수를 호출하려면 비어 있는 괄호를 사용해야 합니다. 예를 들어, 매개 변수를 사용하지 않는 Math.random() 메서드를 사용하여 임의의 숫자를 생성합니다.

var randomNum:Number = Math.random();

함수 정의

ActionScript 3.0에서는 함수 명령문을 사용하거나 함수 표현식을 사용하는 두 가지 방법으로 함수를 정의합니다. 정적 또는 동적인 프로그래밍 스타일 중 선호하는 스타일에 따라 방법을 선택합니다. 정적 또는 Strict 모드의 프로그래밍을 선호하는 경우 함수 명령문을 사용하여 함수를 정의합니다. 특정한 요구에 함수 표현식이 적합하면 함수 표현식을 사용하여 함수를 정의합니다. 함수 표현식은 주로 동적 또는 Standard 모드의 프로그래밍에 사용됩니다.

함수 명령문

함수 명령문은 Strict 모드에서 함수를 정의할 때 주로 이용하는 방법입니다. 함수 명령문은 function 키워드로 시작하며 그 뒤에 다음이 추가됩니다.

예를 들어, 다음 코드에서는 매개 변수가 정의된 함수를 만든 다음 매개 변수 값으로 "hello" 문자열을 사용하여 함수를 호출합니다.

function traceParameter(aParam:String)
{
    trace(aParam);
}

traceParameter("hello"); // hello

함수 표현식

함수를 선언하는 두 번째 방법은 함수 리터럴 또는 익명 함수라고도 하는 함수 표현식이 포함된 대입문을 사용하는 것입니다. 이는 이전 버전의 ActionScript에서 많이 사용했던 방식으로 함수 명령문을 사용하는 방식에 비해 코드가 길어집니다.

함수 표현식이 포함된 대입문은 var 키워드로 시작하며 그 뒤에 다음이 추가됩니다.

예를 들어, 다음 코드는 함수 표현식을 사용하여 traceParameter 함수를 선언합니다.

var traceParameter:Function = function (aParam:String)
{
    trace(aParam);
};
traceParameter("hello"); // hello

함수 명령문에서와는 달리 함수 이름을 지정하지 않습니다. 함수 표현식과 함수 명령문 간의 또 다른 중요한 차이점은 함수 표현식은 명령문이 아닌 표현식이라는 점입니다. 함수 명령문과 달리 함수 표현식은 독립적으로 사용할 수 없습니다. 함수 표현식은 일반적으로 대입문과 같은 명령문의 일부로만 사용할 수 있습니다. 다음 예제에서는 배열 요소에 지정된 함수 표현식을 보여 줍니다.

var traceArray:Array = new Array();
traceArray[0] = function (aParam:String)
{
    trace(aParam);
};
traceArray[0]("hello");

명령문과 표현식 간에 선택

일반적으로 특정 상황에서 표현식이 필요하지 않은 경우 함수 명령문을 사용합니다. 함수 명령문이 상대적으로 간단하며 Strict 모드와 Standard 모드에서 함수 표현식보다 일관성 있게 사용할 수 있습니다.

함수 명령문은 함수 표현식이 포함된 대입문보다 쉽게 읽을 수 있습니다. 함수 명령문은 코드를 더욱 간결하게 만들어 varfunction 키워드를 모두 사용해야 하는 함수 표현식보다 쉽게 사용할 수 있습니다.

함수 명령문을 사용하여 선언된 메서드를 호출할 때 Strict 모드와 Standard 모드 모두에서 도트 구문을 사용할 수 있다는 점에서 함수 명령문은 두 컴파일러 모드 간의 일관성이 함수 표현식보다 낫습니다. 함수 표현식으로 선언된 메서드의 경우 도트 구문을 사용하여 호출하지 못할 수도 있습니다. 예를 들어, 다음 코드에서는 함수 표현식으로 선언된 methodExpression() 메서드와 함수 명령문으로 선언된 methodStatement() 메서드가 있는 Example 클래스를 정의합니다. Strict 모드에서는 methodExpression() 메서드를 호출하기 위해 도트 구문을 사용할 수 없습니다.

class Example
{
  var methodExpression = function() {}
  function methodStatement() {}
}

var myEx:Example = new Example();
myEx.methodExpression(); // Strict 모드에서는 오류가 발생하고 Standard 모드에서는 오류가 발생하지 않습니다.
myEx.methodStatement(); // Strict 모드와 Standard 모드에서 오류가 발생하지 않습니다.

함수 표현식은 런타임 또는 동적인 비헤이비어에 중점을 두는 프로그래밍에 사용하는 것이 보다 적합합니다. Strict 모드를 사용하려고 하지만 함수 표현식으로 선언된 메서드를 호출해야 하는 경우 다음 두 가지 방법 중 하나를 사용할 수 있습니다. 첫 번째, 도트(.) 연산자 대신 대괄호([])를 사용하여 메서드를 호출할 수 있습니다. Strict 모드와 Standard 모드 모두에서 다음 메서드 호출이 성공했습니다.

myExample["methodLiteral"]();

두 번째, 전체 클래스를 동적 클래스로 선언할 수 있습니다. 이렇게 하면 도트 연산자를 사용하여 메서드를 호출할 수 있지만 해당 클래스의 모든 인스턴스에 대한 Strict 모드 기능의 일부가 제대로 작동하지 않을 수 있습니다. 예를 들어, 동적 클래스의 인스턴스의 정의되지 않은 속성에 액세스하려고 하는 경우 컴파일러에서 오류를 생성하지 않습니다.

함수 표현식을 사용하는 것이 유용한 경우도 있습니다. 함수 표현식은 한 번만 사용하고 폐기할 함수를 정의하는 경우에 일반적으로 사용됩니다. 이보다 사용 빈도는 낮지만 프로토타입 속성에 함수를 연결하는 경우에도 사용됩니다. 자세한 내용은 프로토타입 객체를 참조하십시오.

사용할 방법을 선택할 때는 함수 명령문과 함수 표현식 간의 두 가지 미세한 차이점을 고려해야 합니다. 첫 번째 차이점은 메모리 관리 및 가비지 컬렉션과 관련해서 함수 표현식은 독립된 개체가 아니라는 점입니다. 즉, 배열 요소 또는 객체 속성과 같은 다른 객체에 함수 표현식을 지정할 때는 코드에서 해당 함수 표현식에 대한 참조만 만듭니다. 함수 표현식이 연결된 배열 또는 객체가 범위를 벗어나거나 더 이상 사용할 수 없는 경우 함수 표현식에 더 이상 액세스할 수 없습니다. 배열 또는 객체를 삭제하면 함수 표현식에서 사용하는 메모리가 가비지 컬렉션의 대상이 되므로 해당 메모리를 다른 용도로 이용하거나 재사용할 수 있습니다.

다음 예제에서는 함수 표현식의 경우 표현식이 지정된 속성이 삭제되면 함수를 더 이상 사용할 수 없다는 것을 보여 줍니다. Test 클래스는 동적이므로 함수 표현식이 저장된 functionExp 속성을 추가할 수 있습니다. 도트 연산자를 사용하여 functionExp() 함수를 호출할 수 있지만 functionExp 속성이 삭제되면 더 이상 함수에 액세스할 수 없습니다.

dynamic class Test {}
var myTest:Test = new Test();

// 함수 표현식
myTest.functionExp = function () { trace("function expression") };
myTest.functionExp();   // 함수 표현식
delete myTest.functionExp;
myTest.functionExp();   // 오류

반면에 먼저 함수 명령문으로 함수를 정의하면 이 함수는 독립된 객체로 존재하며 함수가 연결된 속성을 삭제한 후에도 계속해서 사용할 수 있습니다. delete 연산자는 객체의 속성에 대해서만 작동하므로 stateFunc() 함수 자체를 삭제하도록 호출해도 작동하지 않습니다.

dynamic class Test {}
var myTest:Test = new Test();

// 함수 명령문
function stateFunc() { trace("Function statement") }
myTest.statement = stateFunc;
myTest.statement(); // 함수 명령문
delete myTest.statement;
delete stateFunc;   // 영향 없음
stateFunc();        // 함수 명령문
myTest.statement(); // 오류

함수 명령문과 함수 표현식 간의 두 번째 차이점은 함수 명령문은 함수 명령문 앞에 나오는 명령문을 포함하여 함수 명령문이 정의된 범위 전체에서 사용된다는 점입니다. 반면에 함수 표현식은 후속 명령문에 대해서만 정의됩니다. 예를 들어 다음 코드에서는 scopeTest() 함수를 정의하기 전에 해당 함수를 성공적으로 호출합니다.

statementTest(); // statementTest

function statementTest():void
{
    trace("statementTest");
}

함수 표현식은 정의하기 전에 사용할 수 없기 때문에 다음 코드에서 런타임 오류가 발생합니다.

expressionTest(); // 런타임 오류

var expressionTest:Function = function ()
{
    trace("expressionTest");
}

함수에서 값 반환

함수에서 값을 반환하려면 return 문 다음에 반환할 표현식 또는 리터럴 값을 지정합니다. 예를 들어, 다음 코드는 매개 변수를 나타내는 표현식을 반환합니다.

function doubleNum(baseNum:int):int
{
    return (baseNum * 2);
}

return 문은 함수를 종료하므로 다음과 같이 return 문 아래의 명령문이 모두 실행되지 않습니다.

function doubleNum(baseNum:int):int {
    return (baseNum * 2);
    trace("after return"); // 이 trace 문은 실행되지 않습니다.
}

반환 유형을 지정하기로 결정한 경우 Strict 모드에서는 적절한 유형의 값을 반환해야 합니다. 예를 들어 다음 코드에서는 올바른 값을 반환하지 않기 때문에 Strict 모드에서 오류가 발생합니다.

function doubleNum(baseNum:int):int
{
    trace("after return");
}

중첩 함수

함수를 중첩할 수 있으므로 다른 함수 내에 함수를 선언할 수 있습니다. 함수에 대한 참조가 외부 코드로 전달되지 않으면 중첩 함수는 부모 함수 내에서만 사용할 수 있습니다. 예를 들어, 다음 코드는 getNameAndVersion() 함수 내에 두 개의 중첩 함수를 선언합니다.

function getNameAndVersion():String
{
    function getVersion():String
    {
        return "9";
    }
    function getProductName():String
    {
        return "Flash Player";
    }
    return (getProductName() + " " + getVersion());
}
trace(getNameAndVersion()); // Flash Player 9

중첩 함수가 외부 코드로 전달되면 해당 함수는 함수 클로저로 전달되므로 함수가 정의될 때 범위에 있는 모든 정의가 함수에 그대로 유지됩니다. 자세한 내용은 함수 클로저를 참조하십시오.


Flash CS3

 

이 페이지에 의견 추가되면 전자 메일 알림 받기 | 의견 보고서

현재 페이지: http://livedocs.adobe.com/flash/9.0_kr/main/00000054.html