[개발일치 28일차] 함수 function() 이해하기

MSJ·2022년 6월 13일
0

WEB

목록 보기
28/41
post-thumbnail

2022-06-13

도움되는 사이트 :

함수(function)란?

여러 동작을 묶은 하나의 덩어리

함수의 이점?

  • 같은 기능이 필요할 때 마다 함수를 호출할 수 있다.
  • 각 명령의 시작과 끝을 명확히 구별할 수 있다.

함수 선언(함수 정의)

함수가 어떤 명령을 처리해야 할 지 미리 알려주는 것을 함수 선언이라 한다.

  • function 이라는 *예약어를 사용한다.
  • { } 안에 실행할 명령을 작성한다.
*예약어 : 미리 약속된 언어

함수의 가장 기본적인 형태

fuction addNumber(){
var sum = 10+20;
console.log(sum);

함수 호출 (함수 실행)

함수의 이름을 사용하여 실행하는 것.
함수를 만들어도, 함수 호출까지 해야 동작된다.

addNumber();

->30

함수 선언 위치

Js는 함수를 위, 아래 아무곳에나 선언해도 상관없이 호출(실행)할 수 있다.

하지만 좋은 코드의 습관은 순차적으로 아래에서 호출하는 것이다. 다른 언어를 쓸 때 오류가 날 수 있기 때문.

1) 위에서 호출------------------
<script>

addNumber();

fuction addNumber(){
var sum = 10+20;
console.log(sum);

2) 아래에서 호출-----------------
fuction addNumber(){
var sum = 10+20;
console.log(sum);

addNumber();

</script>

var VS let, const

var는 오래전부터 쓰였던 변수 선언 예약어이고 let, const는 ES6 버전 이후에 등장한 변수를 선언하는 예약어이다.

먼저 var의 특징을 알아보자.

1. var 변수 특징 : Scope(영역)

var은 두 가지 스코프 특징이 있는데 지역변수가 될 수 있고, 전역변수가 될 수도 있다.

지역변수 : 변수 이름 앞에 var을 붙이면 된다. 함수 안에서만 사용할 수 있는 변수다.
전역변수 : var가 없을 경우 프로그램 전체에서 사용할 수 있는 변수다.

2. var 변수 특징 : Hoisting(호이스팅) 현상

Hoisting이란?

모든 선언문이 해당 Scope의 선두로 옮겨진 것처럼 동작하는 특성을 말한다. 즉, Js는 모든 선언문이 선언되기 이전에 참조 가능하다.

실제로 선언되진 않았지만 선언된 것처럼 끌어올려서 값을 내는 것이다.

그런데 var 변수는 최상단에 변수를 쓰지 않아도 오류가 발생하지 않는다.

이게 무슨 소리인가?
예를 들어보자.

<script>

var x = 100;

test();
function test(){
document.write("x is " + x + ", y is " + y);
var y = 200;
}

</script>

위 함수를 보면, var y 변수가 해당 함수 최상단에 있는 것이 아니라, 함수 내부에 있는 것을 볼 수 있다.

그렇다면 결과는 어떻게 될까?

오류는 나지도 않고, y is undefined라고 출력까지 된다.
undefined는 왜 나는 것일까? var y에서 변수를 지정해주지 않는데 실행문장에서 y변수를 써버렸으니, var 변수에 미리 저장된 값을 불러온 것이다. 그 저장된 값이 뭐였다? undefined라는 값이였던 것이다.

호이스팅이 이루어지는 순서는
1. 선언 2. 초기화(메모리에 등록된 변수를 할당하면서 undefined로 초기화됨) 3. 할당 (실제 값을 할당)
인데, 선언 단계와 초기화 단계가 한번에 이루어지기 때문에 선언 없이 변수를 쓰기만 해도 undefined라는 값이 주어져있는 셈이다.

이때, 오류가 나지 않는 것. 이것이 가장 큰 문제점이다.
오류가 나야 어디서 작동이 꼬였는지 발견할 수가 있는데, 그것을 쉽게 발견할 수가 없다는 말이 된다. 마치 사막에서 바늘찾기 처럼...

3. var 변수 특징 : 중복선언

이미 존재하는 변수를 다시 선언할 수 있다.
서로 다른 위치에서 같은 변수를 선언할 때, 앞쪽 변수를 덮어버리므로 예상치 못한 오류가 발생할 수 있다. 원하는 값이 나오지 않거나 등.

let, const 의 특징

var 변수가 가지는 한계점을 보완하여 등장한 것이 바로 let과 const인데.

let : 프로그램 안에서 값이 변하는 변수
const : 프로그램 안에서 값이 변하지 않는 변수

  • 변수의 scope : let, const 변수는 블록 영역의 스코프를 가진다
  • hoisting 없음 : 변수를 선언하지 않고 사용하면 에러를 띄워준다
  • 변수 재선언 불가 : 중복된 변수를 선언할 경우 에러를 띄워준다

변수는 이렇게 사용하자

  • 전역 변수는 최소한으로 사용한다.
    -> 전역 변수를 사용할 때 컴퓨터의 메모리를 할당받아 사용하게 되는데, 무분별하게 쓸 경우 속도가 느려질 수 있다
  • var 변수는 함수의 시작 부분에서 선언한다.
    -> 호이스팅 방지
  • for문의 카운터 변수는 블록 변수(let)를 사용하는게 좋다
  • ES6를 사용한 프로그램이라면 var보다 let을 사용한다

재사용 가능한 함수

특정 수 하나만을 계산하는 함수는 재사용을 할 필요가 없는 함수이다. 1회만 쓰면 되니까. (함수로 만들 필요가 없음)

매개변수에 인수를 넣어 함수를 동작시킬 수 있다면, 재사용이 가능한 함수다.

매개변수 : 함수를 실행하기 위해 지정한 값. ( 함수의 이름 바로 옆 괄호()에 넣는다.
인수 : 함수를 실행할 때 매개변수로 넘겨주는 값.

function addNumber(a, b){ //매개변수
	var sum + a + b;
    console.log(sum);
    }
    
    addNumber(2, 3) // 2, 3은 인수

return문

함수를 실행하여 나온 결과값을 함수 밖으로 넘기는 문장을 말한다.
반환된 값은 함수를 실행한 소스 위치로 넘겨진다.

함수 표현식

익명 함수

이름이 주어져있지 않은 함수를 뜻한다.
함수 자체가 '식(Expression)'이기 때문에, 함수를 변수에 할당하거나 다른 함수의 매개변수로 사용할 수도 있다.

var add = function(a,b){ //함수 선언 후 변수 add에 할당
	return a + b;
}

-----

var sum = add(10, 20); //익명 함수 실행 후 결괏값을 변수 sum에 저장
sum // 변수 sum 값 확인
-> 30

즉시 실행 함수

함수를 정의함과 동시에 실행하는 함수를 말한다.
즉시 실행 함수는 변수에 할당할 수 있고, 함수에서 반환하는 값을 변수에 할당할 수도 있다.

자주 사용하는 함수는 아니나, 형태는 익혀두자.

//괄호로 시작
(function() {
	...
})(); 

//또는

(function() {
	...
}()) ;

매개변수와 인수를 사용할 때는?
매개변수는 function() 괄호 안에, 인수는 함수 끝에 있는 괄호 안에 넣는다.

var result = *gunction(){
	return 10 + 20;
}());
console.log(result);
->30

//-----

var result = (function(a,b) {
	return a + b;
} (10, 20));
console.log(result);
->30

화살표 함수

ES6 이후 버전에는 => 표기법을 사용해 함수 선언을 간단하게 작성할 수 있다

매개 변수가 없을 때

const hi = function(){
	return "안녕하세요?";
}

//

const hi = () => {"안녕하세요?"};

//

const hi = () => "안녕하세요?";

매개 변수가 있을 때

let hi = function(user){
	document.write(user + "님, 안녕하세요?");
}

//

let hi = user => document.write(user + "님, 안녕하세요?");

//

let sum = function(a,b){
	return a + b;
]

//

let sum=(a,b) => {return a+b}

//

let sum=(a,b) => a+b;

수업시간 예제문

예제1) 최소값, 최대값을 구하는 함수 프로그램 만들어보기

매개변수를 이용한 함수 프로그램

<script>
    //parseInt 는 숫자로 바꿔주는 내장 함수의 이름이다...
        var num1 = parseInt(prompt('첫 번째 숫자 : '));
        var num2 = parseInt(prompt('두 번째 숫자 : '));

        function compareNumber(num1, num2){
            if(num1 == num2){
                alert(`${num1} 와(과) ${num2} 은(는) 같은 숫자입니다.`)
            } else if(num1 > num2){
                alert(`${num1} 은(는) ${num2} 보다 큰 숫자입니다.`)
            } else if(num1 < num2){
                alert(`${num1} 은(는) ${num2} 보다 작은 숫자입니다.`)
            }
        }
        compareNumber(num1, num2);
</script>

예제2) 홀수, 짝수 구하는 함수 프로그램 만들어보기

<script>
 // 1) 짝수 홀수 구분하기 even(짝수) odd(홀수)

            var num = parseInt(prompt('판별할 수를 입력하세요'));
            function evenodd(num){
                if(num % 2===0){
                    alert(`${num}은(는) 짝수`);
                } else {
                    alert(`${num}은(는) 홀수`);
                }
            }

            evenodd(num);
</script>

예제3 중첩 for 문 복습하기

구구단 프로그램을 만들어보자

<script>
// 2) 구구단 display gugudan

var dan = parseInt(prompt('출력할 단을 입력하세요'));

            function displaygugudan(todan){
                for (let i = 2; i <=todan; i++){ //(let i = 2; i <=todan && todan<=9; i++) 9단까지만
                    for(let j = 1; j<=9; j++){
                        document.write(i + "*" + j + "=" + i*j+"<br>");
                    } // 요기를 벗어나면 다시 첫번째 for문으로 .
                }             
            } 
            
            //밖에 있는 for문 보다 안쪽에 있는 for문이 더 바쁘다. 바깥->안쪽에서 안쪽이 다 수행되어야 다시 바깥으로 가기 때문.
            displaygugudan(dan);
</script>

어려운 점

hoisting, let, var, 지역변수, 전역변수 등등에 대한 개념을 좀더 정확히 잡고 싶다

해결 방법

hoisting
변수는 3단계에 걸쳐 생성되는데,
1) 선언 단계

  • 변수 객체에 변수를 등혹한다. 이 변수 객체는 스코프가 참조하는 대상이 된다.

2) 초기화 단계

  • 변수 객체에 등록된 변수를 메모리에 할당한다. 이 단계에서 변수는 undefined로 초기화된다.

3) 할당 단계

  • undefined로 초기화된 변수에 실제 값을 할당한다.

var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어진다. 즉, 스코프에 변수가 등록되고 변수는 메모리에 공간을 확보한 후 undefined라는 값으로 초기화된다. 따라서 변수 선언문 이전에 변수에 접근하여도 Variable Object에 변수가 존재하기 때문에 에러가 발생하지 않는다. undefined를 반환할 뿐.
이러한 현상을 Hoisting이라 한다.

let? var?
let과 var은 함수 안에 쓰면 지역변수가 되고, 함수 바깥에 쓰면 전역변수가 된다.
하지만 let은 함수 내부의 에러를 잡거나, 중복을 막는 역할을 가지기 때문에 굳이 전역변수일 필요가 없다... 굳이?
전역변수는 var로 선언해서 쓰면 된다.

소감

저번 시간보다 개념 정리가 더 잘 된 느낌이다.

profile
제로부터 시작하는 프로그래밍&코딩

0개의 댓글