함수는 문장을 캡슐화하여 어디서든, 언제든 실행할 수 있게 하므로 모든 언어의 핵심입니다.
함수는 function 키워드로 정의하며 그 뒤에 매개변수와 함수 본문을 순서대로 씁니다.
function functionName(arg0, arg1, ... , argN) {
statements
}
예제로 하나의 함수를 만들어 실행해 보겠습니다.
function sayHi(name, message) {
console.log("Hello " + name + " , " + message);
}
sayHi("Nicholas", "how are you today?");
함수를 호출할때 함수의 이름과 매개변수 두 개를 써줘 함수 안의 실행문을 실행합니다.
함수에는 반환할 값을 써서 값을 반환 할 수 있습니다, 하지만 위 처럼 반환하지 않아도 됩니다.
function sum(sum1, sum2) {
return sum1 + sum2;
console.log(sum1 + ", " + sum2); // 실행되지 않습니다.
}
var result = sum(5, 10);
console.log("result = " + result);
sum() 함수는 두 값을 더한 후 값을 반환합니다.
함수는 returnr 문을 만나느 즉시 실행을 멈추고 빠져나옵니다. 따라서 return문 뒤의 코드는 결코 실행 되지 않습니다.
그리고 다음과 같이 함수 하나에 return 문을 여러 깨 쓸 수 있습니다.
function diff(num1, num2) {
if ( num1 < num2 ) {
return num2 - num1;
} else {
return num1 - num2;
}
}
var result = diff(5, 10);
console.log("result = " + result);
return 문 뒤에 반환 값을 쓰지 않아도 됩니다.
이렇게 하면 함수는 return 문을 만나는 즉시 실행을 멈추고 undefined값을 반환합니다.
일반적으로 함수에서 값을 반환할 필요가 없고 함수 실행을 멈추기만 하려 할 때 밑에 처럼 사용하면 된다.
function sayHi(name, message) {
return;
console.log("Hello " + name + " , " + message);
}
sayHi("Nicholas", "how are you today?");
매개변수
자바스크립트 함수 매개변수는 다른 언어의 매개변수와 사뭇 다르게 동작합니다.
매개변수 숫자를 따지지 않으며 데이터 타입도 체크하지 않습니다.
함수에서 매개변수를 두 개 받도록 만들었더라도 반드시 매개변수 두 개를 넘겨야 하는 건 아닙니다.
매개변수를 한 개, 세 개 아예 넘기지 않더라도 인터프리터는 이를 에러로 간주하지 않습니다.
이렇게 되는 이유는 자바스크립트 매개변수가 내부적으로는 배열로 표현되기 때문이다.
이 배열은 항상 함수에 전달되지만 함수는 배열에 어떤 값이 들어 있는지 체크하지 않습니다.
빈 배열이 들어와도 상관없고, 필요한 매개변수보다 더 많이 들어와도 괜찮습니다.
함수는 aguments라는 객체를 하나 갖는데, 이 객체를 통해 매개변수 값에 접근할수 있습니다.
즉 위 예제 중 sayhi를 이렇게 쓸 수 있다.
function sayHi() {
console.log("Hello " + arguments[0] + " , " + arguments[1] )
}
sayHi("Nicholas", "how are you today?");
고쳐 쓴 함수에는 이름 붙은 매개변수가 없습니다. 하지만 함수는 의도대로 동작합니다.
arguments 객체의 length 프로퍼티를 통해 함수에 매개변수가 몇 개 전달되었는지 알 수 있습니다.
function howManyArgs() {
console.log("length = " + arguments.length);
}
howManyArgs("string", 45);
howManyArgs();
howManyArgs(12);
이런 방법을 통해 개발자는 함수가 받는 매개변수 숫자에 제한을 두지 않고 넘겨받은 매개변수 개수에 맞게 반응할 수 있습니다.
function doAdd() {
if(arguments.length == 1) {
console.log(arguments[0] + 10);
} else if(arguments.length == 2) {
console.log(arguments[0] + arguments[1]);
}
}
doAdd(10);
doAdd(30, 20);
이런 방식은 오버로딩만큼 좋지는 않지만 자바스크립트의 제한을 경감하기에는 충분하다.
매개변수에서 또 다른 중요한 점은 다음과 같이 arguments 객체를 이름 붙은 매개변수와 함께 쓸 수 있다는 겁니다.
function doAdd(num1, num2) {
if(arguments.length == 1) {
console.log(num1 + 10);
} else if(arguments.length == 2) {
console.log(num1 + num2);
}
}
doAdd(10);
doAdd(30, 20);
다시 고친 함수에는 매개변수와 argument를 함께 썼습니다.
매개변수 num1은 arguments[0]과 같은 값이므로 둘을 바꿔서 쓸 수 있습니다.
arguments 객체에서 한 가지 더 재미있는 점은 이 객체의 프로퍼티 값을 이에 대응하는 이름 붙은 매개변수에서 자동으로 반영한다는 점이다.
function doAdd(num1, num2) {
arguments[1] = 10;
console.log(arguments[0] + num2);
}
doAdd(30, 20);
바꾼 함수에서 두 번째 매개변수를 10으로 바꿉니다.
이름 붙은 매개변수는 arguments 객체의 프로퍼티를 자동으로 반영하므로 arguments[1] 과 num2 둘다 10이 됩니다.
이 둘은 같은 메모리 공간을 쓰는건 아닙니다.
그런데 동기화가 아니라 단반향 반영입니다.
함수를 정의 할 때 함께 정의한 매개변수를 넘기지 않으면 해당 매개변수에는 자동 undefined가 할당됩니다.
이는 변수를 정의하기만 하고 초기화하지는 않은 것과 비슷합니다.
오버로딩 없음
자바스크립트에서는 다른 언어에서 사용하는 오버로딩이 없습니다.
다른 언어에서는 예를 들어 함수 이름이 같더라도 매개변수(타입, 개수)만 다르면 서로 다르게 동작핟도록 정의할 수 있습니다.
자바스크립트에서는 시그너치가 없는데 매개변수는 그저 배열일 뿐이며 그값에 제한이 없기 때문입니다.
함수 시그너처가 없으면 진정한 의미로 오버로딩은 불가능 합니다.
자바스크립트에서는 같은 이름으로 함수를 여러 번 정의하면 마지막 함수가 해당 이름을 소유합니다.
function addSomeNumber(num) {
return num + 100;
}
function addSomeNumber(num) {
return num + 200;
}
var result = addSomeNumber(100);
console.log("result = " + result);
첫 번째 함수가 두 번째 함수를 덮어썼기 때문에 두번째 함수가 실행이 됩니다.
이미 언급했듯 함수에 넘긴 매개변수의 타입과 숫자를 체크해서 그에 맞게 반응하는 방법으로 오버로딩을 흉내낼 수 있습니다.
'프로그래밍 > 자바스크립트(javascript)' 카테고리의 다른 글
[자바스크립트/javascript] Object타입, Array타입 (0) | 2020.05.08 |
---|---|
[자바스크립트/javascript] 변수, 컨텍스트, 가비지 콜렉션 (0) | 2020.05.04 |
[자바스크립트/javascript] 제어문, 반복문 ( if문, switch문, for문, for-in문, while문, do-while문 ) (0) | 2020.05.02 |
[자바스크립트/javascript] 자바스크립트 연산자 (0) | 2020.05.02 |
[자바스크립트/javascript] 식별자, 주석, 스트릭트 모드, 변수, 데이터 타입 (0) | 2020.04.30 |