✅함수의 호출에 🔑매개변수와 인수, 반환문이 어떠한 특징을 가진 채 사용되는지 알아보고 🔑매개변수의 값에 의한 전달, 참조에 의한 전달 방식이 어떠한 차이를 가지고 있는지에 대해 살펴보잠!
- WHAT IS❓ 함수 호출이란 '정의된 함수를 실행하기 위해 필요한
인수
를매개변수
를 통해 함수에 전달하여 함수를 실행'시키는 것을 의미한다.- 함수를 호출하면 현재의 실행 흐름을 중단하고 호출된 함수로 실행흐름을 옮겨
매개변수
에인수
를 순서대로 할당하여 함수 몸체의 문들이 실행되는 과정을 시작한다- HOW TO USE❕❓ 함수 호출은 함수를 가리키는 식별자와 한 쌍의 소괄호인 함수 호출 연산자(= ()) 내에 0개 이상의
인수
를 쉼표로 구분해서 나열하여 호출한다.
매개변수(인자)
를 통해 인수
를 전달한다.-인수
1>
인수
는 값으로 평가될 수 있는 표현식이어야한다.
2>인수
는 함수를 호출할 때 지정한다.
3>인수
의 개수와 타입에 제한이 없다.<script> //함수선언문 function add(x,y){ return x+y; } //함수 호출 const result = add(1, 2) //인수 1과 2과 매개변수 x, y에 순서대로 할당되고 함수 몸체의 문들이 실행된다. </script>
-매개변수(인자)
1>
매개변수
는 함수 몸체 내부에서 변수와 동일하게 취급해 매개 변수 선언과 초기화가 이뤄진다.
2>매개변수
는 함수를 정의할 때 선언한다.
3>매개변수
의 스코프(유포범위)는 함수 내부이기에 함수 몸체 내부에서만 참조할 수 있고 외부에서는 참조할 수 없다.
-매개변수
가 인수
보다 개수가 더 많은 경우(매개변수>인수 개수) :
- 함수는
매개변수
의 개수와인수
의 개수가 일치하는지 확인하지 않기 때문에 인수가 할당되지 않은 매개변수의 값은 undefined가 된다.<script> //함수선언문 function add(x,y){ return x+y; } //함수 호출 console.log(add(2)) // NaN //x는 2가 y는 undefined가 전달되어 2+ unefined는 NaN이다. </script>
-인수
가 매개변수
보다 개수가 더 많은 경우(인수>매개변수 개수) :
- 초과된 인수는 무시되지만 버려지는 것이 아닌 암묵적으로 arguments 객체의 프로퍼티로 보관된다.
💡 참고) arguments 객체? 함수 정의시 매개변수 개수를 확정할 수 없는 가변 인자 함수를 구현할 때 유용하다<script> //함수선언문 function add(x,y){ console.log(arguments) // Arguments(3) {2, 5, 10 ...} return x + y; } //함수 호출 console.log(add(2, 5, 10)); // 7 //초과된 인수 10은 arguments 객체의 프로퍼티에 보된다. </script>
- 자바스크립트 함수는
매개변수
와인수
의 개수가 일치하는지 확인하지 않는다.- 자바스크립트는 동적 타입언어로
매개변수
의 타입을 사전에 지정할 수 없다.<script> //함수선언문 function add(x,y){//어떤 타입의 인수를 전달해야하는지 return x + y;//어떤 타입의 값을 반환하는 지 명확하지 않은 함수이다. } //함수 호출 console.log(add(2)); // undefiend console.log(add('a','b')); // 'ab' </script>
예시1> 함수를 정의할 때 적절한
인수
가 전달되었는지 확인할 필요가 있다.<script> function add(x,y){//어떤 타입의 인수를 전달해야하는지 if(typeof x !== 'number' || typeof y !== 'number'){ //매개변수를 통해 전달한 인수의 타입이 부적절한 경우 에러를 발생하도록 설계 throw new TypeError('인수의 값 모두 숫자값으로 넣도록!') } return x + y; } //함수 호출 console.log(add(2)); // TypeError:'인수의 값 모두 숫자값으로 넣도록!' console.log(add('a','b')); // TypeError:'인수의 값 모두 숫자값으로 넣도록!' </script>
- 예시2>
인수
가 전달되지 않은 경우 1)단축 평가 혹은 2)매개변수 기본값을 사용해 매개변수에 기본값을 할당할 수 있다.<script> // 1) 단축평가로 인수를 전달하지 않은 경우엔 값을 0으로 할당 function add(x,y,z){ x = x || 0; // 단축평가 y = y || 0; z = z || 0; return x + y + z; } // 2) 매개변수 기본값으로 인수를 전달하지 않은 경우엔 값을 0으로 할당. function add(x=0,y=0,z=0){ // 매개변수 기본값 return x + y + z; } console.log(add(1,2)); // 3 console.log(add(1)); // 1 console.log(add(); // 0 </script>
매개번수
의 최대 개수를 명시적으로 제한하진 않지만
이상적인 매개변수 개수는 0개이며 적을 수록 좋다.매개변수
는 순서에 의미가 있다. 따라서 함수 호출 시 전달해야할인수
의 순서를 꼭 고려해야한다.매개변수
의 개수는 최대 3개 이상 넘지 않을 것을 권장하고 그 이상의 매개변수가 필요한 경우 하나의 매개변수를 선언하고 객체를 인수로 전달하는 것이 더 유리하다.
- 객체를 인수로 사용? 명시적 인수의 의미를 설명하는 프로퍼티 키만 정확히 지정하면 순서는 신경 쓰지 않아도 되며 가독성도 좋고 실수도 줄어든다.
<script> //Jquery의 ajax메소드에 객체를 인수로 전달한 경우 $ajax({ method: 'POST', url: '/user', data {id: 1, name: kim}, cache: false }) </script>
반환문
은 return 키워드와 표현식(반환값)으로 이루어졌다.- 함수는
반환문
을 사용해 실행 결과를 함수 외부로 반환(return)한다.- 함수 호출은 표현식으로은 함수 호출 표현식은 return 키워드가 반환한 표현식의 평가 결과, 반환값으로 평가된다.
-반환문
은 두 가지 역할을 하는데
반환문
은 함수의 실행을 중단하여 반환문 이후 다른 문이 존재하더라도 실행되지 않고 무시한체 함수 몸체를 빠져나간다.<script> function multyply(x, y){ return x * y; //반환문 이후 다른 문은 실행되지 않고 무시된다. console.log('난 실행되지렁') } console.log(multyply(3, 6)); // 15 </script>
2
반환문
은 return 키워드 뒤에 오는 표현식을 평가하여 반환하기 때문에 표현식을 명시적으로 지정하지 않으면 undefined가온다.<script> function multyply(x, y){ //반환문 생략하면 암묵적으로 undefiend가 반환 } console.log(multyply()); // undefiend </script>
매개변수
도 함수 몸체 내부에서 변수 동일하게 취급되어
매개변수
타입에 따라서
값(값이 담긴 메모리 주소)에 의한 전달과 참조에 의한 전달 방식으로 동작한다.<script> //매개변수로 원시값과 객체를 전달받는다. function changeVal(primitive, obj){ primitive += 100; obj.name = 'kim' } // 외부상태 const num = 100; const person = { name : 'jamie' } //원시값은 값 자체가 객체는 참조 값이 복사되어 전달된다. changeVal(num, person); //원시 값은 원본이 훼손되지 않나는다. console.log(num);// 100 //객체는 원본이 훼손된다. console.log(person) // {name: 'kim'} </script>
- 원시 타입 인수를 전달받은
매개변수
primitive의 경우 원시 값은 변경 불가능한 값(immnutable value)이므로 직접 변경할수 없기 때문에 재할당을 통해 할당된 원시 값을 새로운 원시값으로 교체 했다.- 객체는 변경 가능한 값(mutable value)이기므로 직접 변경할 수 있기 때문에 재할당 없이 직접 할당된 객체를 변경했다.
-원시형 값과 객체의 부수효과의 차이🤷♂️?
- 원시 타입 인수는 값이 담긴 메모리 주소 자체가 복사되어
매개변수
에 전달되기 때문에 함수 몸체에서 그 값을 재할당을 통한 교체(변경)를 해도 원본은 훼손되지 않는다.
-> 따라서 함수 외부에서 함수 내부로 전달한 원시값의 원본을 변경하는 어떠한 부수효과도 발생하지 않는다.- 객체 타입 인수는 참조 값이 복사되어
매개변수
에 전달되어 함수 몸체에서 참조값을 통해 객체를 변경할 경우 원본 객체가 변경되는 부수효과가 발생한다.
-> 따라서 함수 외부에서 함수 내부로 전달한 참조 값에 의해 원본 객체가 변경되는 부수효과가 발생한다.
Q ) 부수효과를 막을 순 없나유🙋♂️?
A ) 부수효과를 막기위해 객체를 불변객체로 만들어 사용🙆♂️!
- 불변객체란 객체를 마치 원시 값처럼 변경 불가능한 값으로 동작하게 만드는 것이다.
- 불변객체를 이용하면 깊은 복사를 통해 아예 새로운 객체를 생성하고 재할당을 통해 교체할 하여 외부 상태가 변경되는 부수효과를 없애준다.
💡 참고) 순수 함수? VS 함수형 프로그래밍?
- 순수함수란 외부 상태를 변경하지 않고 외부 상태에 의존하지도 않는 함수를 의미하고
- 함수형 프로그래밍이란 이러한 순수함수를 통해 보수효과를 억제하여 오류를 피하고 프로그램의 안정성을 높이려는 프로그래밍 패러디임을 의미한다.
- 함수 호출 시 필요한 값을 함수 외부에서 내부로 전달 할 때 매개변수와 인수 그리고 반환문이 어떠한 역할을 하는지 어떠한 특징을 가지고 있는지 잘 알아두자.
- 자바스크립트 함수는 매개변수와 인수의 개수를 화인하지 않으며 동적 타입언어로 매개변수 타입을 사전에 지정할 수 없기에 1>적절한 인수가 전달되지 않은 경우와 2>인수가 전달되지 않은 경우에 대비하여 함수를 정의해야한다.
- 매개변수는 순서에 의미가 있으며 권장하는 이상적인 개수, 3개 이상을 사용하는 경우엔 객체를 인수에 전달하는 것이 더 효율적임을 알아두자.
- 매개변수 역시 변수와 동일하게 취급되어 값에 의한 전달과 참조에의한 전달 방식으로 나누어서 동작해 전달한 인수 변경 시 부수효과의 유무가 발생할 수 있음을 기억하장
- 책 - 딥다이브 자바스크립트