JavaScript - 함수의 호출을 파헤치자!

김민재·2021년 7월 31일
1

TIL, Deep Javascript

목록 보기
10/22
post-thumbnail

*🔐Study Keyword :

✅함수의 호출🔑매개변수와 인수, 반환문어떠한 특징을 가진 채 사용되는지 알아보고 🔑매개변수의 값에 의한 전달, 참조에 의한 전달 방식어떠한 차이를 가지고 있는지에 대해 살펴보잠!

1. 함수 호출

  • 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 키워드가 반환한 표현식의 평가 결과, 반환값으로 평가된다.

-반환문은 두 가지 역할을 하는데

  1. 반환문함수의 실행을 중단하여 반환문 이후 다른 문이 존재하더라도 실행되지 않고 무시한체 함수 몸체를 빠져나간다.
<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>

2. 참조에 의한 전달과 외부 상태의 변경

  • 매개변수도 함수 몸체 내부에서 변수 동일하게 취급되어
    매개변수 타입에 따라서
    값(값이 담긴 메모리 주소)에 의한 전달참조에 의한 전달 방식으로 동작
    한다.
<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 함수형 프로그래밍?

  • 순수함수외부 상태를 변경하지 않고 외부 상태에 의존하지도 않는 함수를 의미하고
  • 함수형 프로그래밍이란 이러한 순수함수를 통해 보수효과를 억제하여 오류를 피하고 프로그램의 안정성을 높이려는 프로그래밍 패러디임을 의미한다.

*💡conclusion

  • 함수 호출 시 필요한 값을 함수 외부에서 내부로 전달 할 때 매개변수와 인수 그리고 반환문이 어떠한 역할을 하는지 어떠한 특징을 가지고 있는지 잘 알아두자.
  • 자바스크립트 함수는 매개변수와 인수의 개수를 화인하지 않으며 동적 타입언어로 매개변수 타입을 사전에 지정할 수 없기에 1>적절한 인수가 전달되지 않은 경우와 2>인수가 전달되지 않은 경우에 대비하여 함수를 정의해야한다.
  • 매개변수는 순서에 의미가 있으며 권장하는 이상적인 개수, 3개 이상을 사용하는 경우엔 객체를 인수에 전달하는 것이 더 효율적임을 알아두자.
  • 매개변수 역시 변수와 동일하게 취급되어 값에 의한 전달과 참조에의한 전달 방식으로 나누어서 동작해 전달한 인수 변경 시 부수효과의 유무가 발생할 수 있음을 기억하장

#📑Study Source

  1. 책 - 딥다이브 자바스크립트
profile
자기 신뢰의 힘을 믿고 실천하는 개발자가 되고자합니다.

0개의 댓글