6. 함수
함수는 JavaScript의 기본적인 구성 요소 중 하나입니다. 또한 함수는 JavaScript 절차입니다. 즉, 작업 및 값 계산을 수행하는 문장의 집합입니다. 함수를 사용하려면 그것을 호출 할 범위의 어딘가에서 정의해야 합니다.
함수의 정의
함수의 정의 ( 함수의 선언 이라고 표현하기도 합니다)은 function 키워드와 다음 내용으로 구성됩니다.
- 함수의 이름.
- 함수의 인수 목록. 괄호로 묶어 쉼표로 구분합니다.
- 함수를
정의하는 JavaScript 구문은. 중괄호 {} 로 묶어야 합니다.
예를 들어 다음 코드는 square 라는 간단한 함수를 정의합니다 :
function square (number) { return number * number; }
함수 square 인수를 하나 취하고 그 이름은 number 입니다. 이 함수는 인수 (즉 number )의 제곱을 반환하라는 하나의 문장으로 구성됩니다. return 문은 함수의 반환 값을 지정합니다.
return number * number;
프리미티브 타입(primitive type)의 매개 변수(숫자 같은)는 값으로 함수에 전달됩니다. 즉, 값은 함수에 전달되지만, 함수가 매개 변수 값을 변경해도 이 변경은 글로벌 (매개 변수 값)과 함수 호출 (매개 변수 값)에는 영향을 주지 않습니다 .
객체 (즉 넌 프리미티브(non primitive)값, 예를 들어 배열 과 사용자 정의 개체 등)을 매개 변수로 전달하면 함수가 객체의 속성을 변경 한 경우 그 변경이 함수 밖에서도 유효합니다. 다음 예를 참조하십시오 :
function myFunc (theObject) { theObject.make = "Toyota" ; } var mycar = {make : "Honda" , model : "Accord" , year : 1998}, x, y; x = mycar.make; // x는 "Honda"값을 얻을 myFunc (mycar); y = mycar.make; // y는 "Toyota"값을 얻을 // (속성이 함수에서 변경되는)
매개 변수에 새로운 객체를 대입해도, 함수의 외부에 영향을 미치지 않는 점에 유의하십시오. 그것은 개체의 속성 중 하나의 값이 아니라 매개 변수의 값을 변경하기 때문이다.
function myFunc (theObject) { theObject = {make : "Ford" , model : "Focus" , year : 2006}; } var mycar = {make : "Honda" , model : "Accord" , year : 1998}, x, y; x = mycar.make; // x는 "Honda"값을 얻을 myFunc (mycar); y = mycar.make; // y는 역시 "Honda"값을 얻을
첫 번째 예에서는 개체 mycar 이 함수 myFunc 에 전달, 수정됩니다. 두 번째 예에서는 함수는 전달 된 개체를 변경하지 않습니다. 대신 전달 된 전역 개체와 우연히 이름이 같은 새로운 지역 변수를 만들기 때문에 전달 된 전역 개체에는 영향이 없습니다.
JavaScript는 조건에 따라 함수를 정의 할 수 있습니다. 예를 들어 다음 함수의 정의는 변수 num 이 0 인 경우에만 myFunc 함수를 정의합니다 :
if (num == 0) { function myFunc (theObject) { theObject.make = "Toyota" } }
num 이 0 같지 않으면 함수가 정의되지 않고, 함수를 실행하려고 해도 실패합니다.
ECMAScript 는 이러한 컨텍스트에서 함수가 나타나는 것을 인정하지 않고 다른 함수 또는 프로그램의 최상위 만합니다. 따라서 이 예제는 ECMAScript 표준은 아닙니다.
경고 : 이 비 표준 구조는 다른 JavaScript 구현에서는 다르게 수핼 될 수 있기 때문에 가급적 피해야 합니다. 그렇지 않으면 특정 엔진을 사용하는 브라우저에서 작동하지만 다른 브라우저에서 작동하지 않을 수 있습니다. 지금까지 설명한 함수의 정의뿐만 아니라 Function 생성자 를 eval() 처럼 문자열에서 함수 작성에 이용할 수 있습니다.
<<링크>>메서드는 개체의 속성 함수입니다. 개체 및 메서드에 대한 자세한 내용은 <<링크>>7. Working with Objects 를 참조하십시오.
지금까지의 함수 선언은 모든 구문적인 글 이었지만, 함수는 함수 식 으로 만들 수 있습니다. 이러한 함수는 익명 함수도 가능합니다. 예를 들어, 함수 square 는 다음과 같이 정의 할 수 있습니다 :
var square = function (number) { return number * number };
그러나 함수 식 이름을 붙이면 함수에서 자신을 참조하거나 디버거의 스택 추적 함수를 식별하는 데 사용할 수 있습니다 :
var factorial = function fac (n) { return n <2 ? 1 : n * fac (n-1) }; print (factorial (3));
함수식은 함수를 다른 함수의 인수로 전달할 때 유용합니다. 다음 예제에서는 map 함수를 정의하고 첫 번째 매개 변수로 익명 함수를 사용하여 호출합니다 :
function map (f, a) { var result = [], // 새로운 배열을 작성 i; for (i = 0; i != a.length; i++) result [i] = f (a [i]); return result; }
예를 들어, 다음과 같이 호출합니다 :
map (function (x) { return x * x * x }, [0, 1, 2, 5, 10]);이것은 [0, 1, 8, 125, 1000]을 반환합니다.
함수 호출
함수를 정의하면 함수가 자동으로 실행되는 것은 아닙니다. 함수를 정의한다는 것은 단순히 함수에 이름을 붙이고, 그 함수가 호출 될 때 무엇을 할 것인지 지정하는 것입니다. 함수 호출 은 실제로는 지정된 매개 변수를 사용하여 지정된 작업을 수행하는 것입니다. 예를 들어, 함수 square() 를 정의하면 다음과 같이 그것을 호출 할 수 있습니다 :
square (5);
이 글은 5 인자와 함께 함수를 호출합니다. 함수는 자신의 문을 실행하고 25라는 값을 돌려줍니다.
함수는 호출되는 범위 내에 있어야 합니다. 다음 예제와 같이 호출하는 구문 뒤에 정의할 수 있습니다.
print (square (5)); / * ... * / function square (n) { return n * n }
함수의 범위는 최상위에 선언되었다면 전체 프로그램이며, 함수 내에서 선언되었다면 자신이 선언된 함수입니다. 이 동작은 위의 구문 (즉 function funcName () {} )를 사용하여 함수를 정의 할 때임을 주의 하세요. 예를 들어 다음 코드는 작동하지 않습니다.
print (square (5)); square = function (n) { return n * n; }
함수의 인자는 문자열이나 숫자 같은 타입 제한은 없습니다. 전체 개체를 함수에 전달할 수 있습니다. show_props 함수 ( <<링크>>객체 및 속성 정의)는 오브젝트를 인자로 전달하는 함수의 예입니다.
함수는 재귀적으로 호출 할 수 있습니다. 즉, 함수가 함수 자신을 호출 할 수 있다는 것입니다. 예를 들어, factorial을 계산하는 함수입니다 :
function factorial (n) { if ((n == 0) || (n == 1)) return 1; else return (n * factorial (n - 1)); }
1에서 5까지의 계승의 계산은 다음과 같습니다 :
var a, b, c, d, e; a = factorial (1); // a는 값 1을 얻는다 b = factorial (2); // b는 값 2를 얻기 c = factorial (3); // c는 값 6을 얻을 d = factorial (4); // d는 값 24을 얻는다 e = factorial (5); // e 값 120를 얻을
함수를 호출하는 다른 여러 방법이 있습니다. 함수를 동적으로 호출할 필요가 있을 때, 혹은 함수의 인자가 가변적일 때, 혹은 함수 호출의 컨텍스트상에서 런타임에 특정 객체를 결정해야 하는 경우에 드물게 사용됩니다. 함수는 함수이자 객체이며, 또 결과적으로 그 개체는 메소드 입니다 ( function 객체 참조). 그 방법의 하나로, apply() 메소드를 사용함으로써 이 목적을 달성 할 수 있습니다.
함수의 범위
함수 내부에서 선언 된 변수는 함수 외부에서 접근 할 수 없습니다. 이것은 변수가 함수 내에서만 유효하기 때문입니다. 그러나 함수는 자신이 정의 된 범위 내에서 정의 된 모든 변수와 함수에 액세스 할 수 있습니다. 즉, 전역으로 정의 된 함수는 전역 범위에 정의 된 모든 변수에 액세스 할 수 있습니다. 함수의 내부에서 선언 된 함수는 자신의 부모의 함수에서 정의 된 모든 변수, 부모 함수가 액세스 할 수 있는 다른 변수에 액세스 할 수 있습니다.
// 다음 변수는 전역으로 정의 var num1 = 20, num2 = 3, name = "Chamahk"; //이 함수는 전역 범위에 정의 function multiply () { return num1 * num2; } multiply (); // 60를 반환 // 중첩 된 함수의 예 function getScore () { var num1 = 2, num2 = 3; function add () { return name + "scored" + (num1 + num2); } return add (); } getScore (); // "Chamahk scored 5"를 반환
클로저
클로저는 JavaScript에서 가장 강력한 기능 중 하나입니다. JavaScript에서는 함수의 중첩이 가능하며 이 중첩된 내부 함수가 외부 함수에 정의 된 모든 변수와 함수에 자유롭게 액세스 할 수 있습니다 (또한 외부 함수가 액세스 할 수 있는 다른 변수와 함수 모두에 액세스 할 수 있습니다). 그러나 외부 함수는 내부 함수 내에서 정의 된 변수 나 함수를 사용할 수 없습니다. 이것은 내부의 함수의 변수에 대한 일종의 보안입니다. 또한 내부 함수는 외부 함수의 변수 액세스 할 수 있습니다. 그래서 내부 함수가 GC되지 않는다면 내부함수가 참조하는 외부 함수의 변수는 GC되지 않습니다. 클로저는 안쪽 함수가 처리하고 외부 함수 외부 범위를 사용 할 때 만들어집니다.
var pet = function (name) { // 외부 함수는 변수 "name"을 정의 var getName = function () { return name; // 내부 함수는 외부 함수의 변수 "name"에 액세스 가능 } return getName; // 내부 함수를 돌려주는 것으로, 외부 함수에 공개 } myPet = pet ( "Vivie" ); myPet (); // "Vivie"를 반환
(역주: 위 코드는 pet이라는 함수를 통해 getName이라는 내부함수를 외부로 리턴하여 myPet이라는 이름으로 저장하고 있습니다. 따라서 myPet 이 GC되지 않으면, getName도 GC되지 않고 getName함수 내부에서 사용하는 name 도 GC되지 않습니다.)
위의 코드보다 복잡한 코드 할 수 있습니다. 외부 함수 내부에 있는 변수를 조작하는 메소드를 포함한 객체를 반환 할 수 있습니다.
var createPet = function (name) { var sex; return { setName : function (newName) { name = newName; } getName : function () { return name; } getSex : function () { return sex; } setSex : function (newSex) { if ( typeof newSex == "string" && (newSex.toLowerCase () == "male" | | newSex.toLowerCase () == "female" )) { sex = newSex; } } } } var pet = createPet ( "Vivie" ); pet.getName (); // Vivie pet.setName ( "Oliver" ); pet.setSex ( "male" ); pet.getSex (); // male pet.getName (); // Oliver
위의 예에서 외부 함수의 변수 name 은 내부 함수에서 액세스 할 수 있으며 내부 함수를 통하지 않고 내부 변수에 액세스하는 다른 방법은 없습니다. 내부 함수의 내부 변수는 내부 함수의 안전한 저장 영역으로 동작합니다. 그들은 내부 함수 위해 협동하는 데이터를 "영구"안전하게 유지합니다. 함수는 변수를 할당하지 않으며 이름을 가질 필요도 없습니다.
var getCode = ( function () { var SecureCode = "0] Eal (eh & 2" ; // 외부 함수가 변경하지 못하도록 하는 코드 return function () { return SecureCode; }; }) (); getCode (); // 비밀 코드를 반환
그러나 클로저를 사용할 때 주의해야 할 함정이 몇 가지 있습니다. 둘러싸여있는 함수 외부 범위에 있는 변수와 같은 이름의 변수를 정의하면 외부 범위의 변수를 다시 참조할 방법이 없습니다.
var createPet = function (name) { // 외부 함수에서 변수 "name"을 정의 return { setName : function (name) { // 내부 함수에서 변수 "name"을 정의 name = name; //?? 외부 함수에 정의 된 "name"에 어떻게 접근 할 것인가?? } } }
마법 같은 변수 this 는 클로저에서 매우 서두른 것입니다. this 참조는 함수가
정의 된 위치가 아닌 함수를 호출 한 위치에 전적으로 의존하기 때문에
주의해서 사용해야 합니다. 클로저에 대한 경이롭고 정교한 기사가 여기 에
있습니다.
http://jibbering.com/faq/notes/closures/
클로저는 뒤에서 하나의 챕터로 더 자세히 설명합니다. 이 항목을 참고하세요.<<링크>>
arguments 객체 사용
함수의 인수는 배열과 같은 객체로 관리됩니다. 함수에서 다음과 같이 전달 된 인수를 가리킬 수 있습니다 :
arguments [i]
여기서 i 는 인수의 순서를 나타내는 숫자입니다. 이것은
0에서 시작됩니다. 함수에 전달 된 첫 번째 인수는 arguments [0] 입니다.
인수의 총 수는 arguments.length 로 표시됩니다.
arguments 객체를 사용하면, 선언시의 가인 수보다 많은 인수를 사용하여 함수를 호출 할 수 있습니다. 이것은 함수에 전달할 인수의 수를 미리 알 수 없는 경우에 유용합니다. arguments.length 를 사용하면 실제로 함수에 전달 된 인수의 수를 확인할 수 있습니다. 또한 arguments 객체를 사용하여 각 인수를 처리 할 수 있습니다.
예를 들어, 여러 문자열을 연결하는 함수를 생각합니다. 이 함수의 가인은 연결 항목을 구분하는 데 사용 문자열뿐입니다. 이 함수는 다음과 같이 정의되어 있습니다 :
function myConcat (separator) { var result = "" , // 목록을 초기화 i; // 인수에 대해 반복 for (i = 1; i < arguments.length; i + +) { result + = arguments [i] + separator; } return result; }
이 함수에 인수를 여러 전달할 수 있습니다. 그리고 각 인수를 문자열 "목록"에 연결합니다 :
// "red, orange, blue"를 반환 myConcat ( "" , "red" , "orange" , "blue" ); // "elephant; giraffe; lion; cheetah;"를 반환 myConcat ( ";" , "elephant" , "giraffe" , "lion" , "cheetah" ); // "sage. basil. oregano. pepper. parsley"를 반환 myConcat ( "" , "sage" , "basil" , "oregano" , "pepper" , "parsley" );
변수 arguments 는 "배열 같은 변수"이며, 배열이 아닌 것에 주의하십시오. 이것은 숫자 인덱스와 length 속성이 있어 배열과 같아 보입니다. 그러나 배열 작업 방법은 전혀 가지고 있지 않습니다.
더 자세한 정보는, JavaScript 참조 Function 개체<<링크>> 를 참조하십시오.
미리 정의 된 함수
JavaScript에 정의 된 최상위 함수가 몇 가지 있습니다 :
- eval
- isFinite
- isNaN
- parseInt와 parseFloat
- Number 및 String
- encodeURI, decodeURI, encodeURIComponent,
decodeURIComponent (모든 Javascript 1.5 이상에서 사용 가능)
다음 장에서는 이러한 함수를 설명합니다. 또한 모든 함수에 대한 자세한 내용은 JavaScript 참조 를 참조하십시오.
eval 함수
eval 함수는 JavaScript 코드 문자열을 특정 개체를 참조하지 않고 평가합니다. eval 구문은 다음과 같습니다 :
eval (expr);
여기서 expr 은 평가되는 문자열입니다.
문자열이 식을 나타내는 경우 eval 은 식을 계산합니다. 또한 하나 이상의 JavaScript 문장을 나타내는 경우, eval은 식을 실행합니다. eval 코드의 범위는 호출 코드의 범위와 동일합니다. 연산 식을 평가하기 위해 eval 을 호출하지 마십시오. JavaScript는 자동으로 연산 식을 평가합니다.
isFinite 함수
isFinite 함수는 인수를 평가하고 그것이 유한 수인지를 판단합니다. isFinite 구문은 다음과 같습니다 :
isFinite (number);
여기서 number 는 평가하는 수치입니다.
인수가 NaN , 무한대 또는 부의 무한대 인 경우,이 메소드는 false 를 돌려주고, 그렇지 않은 경우는 true 를 돌려줍니다.
다음 코드는 클라이언트의 입력을 확인하고 그것이 유한 수인지를 판단합니다.
if (isFinite (ClientInput)) { /* 적절한 처리 */ }
isNaN 함수
isNaN 함수는 인수를 평가하고 그것이 "NaN"(not a number; 비수)인지 확인합니다. isNaN 의 구문은 다음과 같습니다 :
isNaN (testValue);
여기서 testValue 는 평가하고자 하는 값입니다.
parseFloat 및 parseInt 함수는 비수를 통과 할 때 "NaN"를 돌려줍니다. isNaN 는 "NaN"가 전달 된 경우 trne를, 그렇지 않은 경우는 false를 각각 돌려줍니다.
다음 코드는 floatValue 을 평가하고 이 숫자인지 확인하고 그 결과에 따라 프로시저를 호출합니다 :
var floatValue = parseFloat (toFloat); if (isNaN (floatValue)) { notFloat (); } else { isFloat (); }
parseInt 함수 및 parseFloat 함수
2 개의 "parse"함수 parseInt 와 parseFloat 는 인수 문자열이 주어진 때 숫자를 반환합니다.
parseFloat 의 구문은 다음과 같습니다 :
parseFloat (str);
parseFloat 는 인수 인 문자열 str 을 해석하여 부동 소수점 수를 리턴 합니다. 부호 (+ 또는 -), 숫자 (0-9), 소수점 또는 지수가 아닌 문자에 만나면, 거기까지의 값을 리턴하여 문자 및 후속 모든 문자를 무시합니다. 첫 번째 문자가 숫자로 변환 할 수 없는 경우, "NaN"(not a number; 비수)를 돌려줍니다.
parseInt 의 구문은 다음과 같습니다 :
parseInt (str [, radix);
parseInt 는 제 1 인자 인 문자열 str 을 해석하여 지정된 radix (기수)의 정수를 리턴 합니다. radix 는 선택적 2 인자입니다. 예를 들어, 10이라는 기수는 10 진수로 변환, 8은 8 진수, 16는 16 진수와 같이 변환합니다. 10보다 큰 기수는 알파벳 9보다 큰 수를 나타냅니다. 예를 들어 16 진수 (기수 16)는 A에서 F가 사용됩니다.
parseInt 는 지정된 기수의 숫자가 아닌 문자를 만나면, 그 문자 이후의 모든 문자를 무시하고 지금까지 parse 한 정수 값을 리턴 합니다. 첫 글자를 지정된 기수 값으로 변환 할 수 없는 경우, "NaN"를 돌려줍니다. parseInt 문자열을 버리고 정수 값만 연산합니다.
Number 함수 및 String 함수
Number 및 String 함수는 개체를 숫자 나 문자열로 변환합니다. 이 함수의 구문은 다음과 같습니다 :
var objRef; objRef = Number (objRef); objRef = String (objRef);
여기서 objRef 는 객체 참조를 나타냅니다. Number 함수는 객체의 valueOf () 메소드를 사용합니다. String 함수는 객체의 toString () 메소드를 사용합니다.
다음 예제에서는 Date 객체를 이해할 수 문자열로 변환합니다.
var d = new Date (430054663215), x; x = String (d); / / x는 "Thu Aug 18 04:37:43 GMT-0700 (Pacific Daylight Time) 1983"와 동일한
다음 예제에서는 String 객체를 Number 객체로 변환합니다.
var str = "12" , num; num = Number (str);
이 결과를 확인할 수 있습니다. DOM의 write () 메소드와 JavaScript의 typeof 연산자를 사용하십시오.
var str = "12", num; document.write (typeof str); document.write ("
"); num = Number (str); document.write (typeof num);
escape 함수와 unescape 함수
escape 와 unescape 함수는 비 ASCII 문자에 대해 제대로 작동하지 않고 비 추천되었습니다. JavaScript 1.5 이상에서는 encodeURI , decodeURI , encodeURIComponent 와 decodeURIComponent 를 사용하십시오.
escape 와 unescape 함수는 문자열의 인코딩 및 디코딩합니다. escape 함수는 ISO Latin 문자 세트로 표현 된 인수의 16 진수 인코딩을 반환합니다. unescape 함수는 지정된 16 진수 인코딩 값에 대한 ASCII 문자열을 반환합니다.
이 함수의 구문은 다음과 같습니다 :
escape (string); unescape (string);
이 함수는 주로 서버 측 JavaScript에서 URL의 이름과 값 쌍의 인코딩과 디코딩에 사용됩니다.
저작권 공지
이 문서의 모든 저작권은 Mozilla.org에 있습니다. 이 문서는 "모질라
기여자"들에 의해 작성 되었습니다.
원문 보기
저희가 한글로 번역한 2차적저작물에 대한 저작권 역시 Mozilla.org에
있습니다.