[day-26] 변수, 함수

Joohyung Park·2024년 2월 2일
0

[모두연] 오름캠프

목록 보기
38/95

변수

변할 수 있는 수, 변할 수 있는 정보라는 뜻으로 파이썬에서의 변수와 같다. 차이점이라고 한다면 키워드를 앞에 붙여줘야 한다.

scope

변수를 공부하기 전에 자바스크립트의 스코프에 대해 알아야 한다. 스코프는 범위라는 뜻인데 여기서는 코드가 변수에 접근할 수 있는 범위를 뜻한다.

스코프의 종류는 3가지가 있는데 var키워드는 함수 스코프에 속하고 let키워드는 블록 스코프, 최상위 함수 외부에 선언된 변수라면 글로벌 스코프를 갖게 된다.

함수 scope


위의 그림처럼 x라는 변수는 main 함수 스코프를 갖기에 함수 외부의 출력문은 x를 이용할 수 없다.


위 그림에서도 보다시피 x가 var로 선언되어(함수 scope) if 블록 안의 x도 if 바깥의 x와 같은 스코프를 갖는다. 따라서 hi가 출력된다. var는 변수의 중복 선언을 허용하기에 값이 덮어 씌워진 것이다.

이처럼 헷갈리는 var대신 let을 쓰는 이유가 이것말고도 여러가지 존재한다.

다른 이유로는 var 키워드를 사용하면 환경 변수에 있는 값이 덮어 씌워질 수도 있다. 또한, 같은 이름의 변수를 중복 사용할 수 있기에 팀프로젝트에서 다른 사람의 변수가 덮어 씌워질 수도 있다.

마지막 이유는 변수 호이스팅이라는 이유가 있다. 변수 호이스팅이란 프로그램이 실행되기 이전에 변수의 선언과 초기화를 분리하여 변수의 선언부분만 프로그램 맨위로 끌어 올려지는 것을 말한다. 즉, 자바스크립트 콘솔에게 사용할 변수(값은 제외)를 미리 알려주는 행위이다.

위의 코드는 사실 아래와 같이 실행된 것이다.

실행 결과를 보면 첫 번째 콘솔의 출력은 undefined인데 이 var키워드는 위로 끌어올려지면 자동으로 undefined로 초기화를 해준다. 선언문 이전에 접근을 하는 이상한 짓을 한다는 얘기다. let키워드는 이러한 상황에서 에러를 발생시킨다.

let도 똑같이 호이스팅 하지만 변수의 초기화를 하지 않는다. 근데 왜 에러가 나는 것일까?

이것은 TDZ(일시적 사각지대)라는 것 때문인데 let호이스팅으로 끌어올려지긴 하지만 선언문이 실행될때까지 이 TDZ에 들어간다. 자바스크립트는 이 TDZ에 들어가있는 변수에 접근을 허용하지 않아 에러를 발생시킨다.

따라서 var대신 let을 사용하도록 하자.

블록 scope

if라는 블록 안에 x가 정의되어 있는데 값이 제대로 나오는 이유가 무엇일까? var키워드가 함수 스코프(함수 안에서만 작용) 이기 때문이다! 반면에 var 대신 let 키워드를 사용하면 에러가 난다.


let키워드는 if 같은 블록 안에서만 작용하는 블록 스코프 이기 때문이다! 파이썬의 일반적인 변수선언과 같다고 생각하면 된다.

const

constlet과 매우 유사한데 1가지 다른점은 변수가 아니라 상수이다. 따라서 한번 사용한 변수를 재할당 할 수 없다는 차이점이 있다.

그렇지만 상황에 따라서 재할당 되는 것 같은 경우가 있다. const 변수를 문자나 상수같은 원시타입이 아니라 리스트 같은 객체타입이면 내용물의 값은 변할 수 있기 때문이다.

var, let, const 최종 정리

  • var

    • 함수 스코프
    • 변수 선언시 사용
    • 초기화 필요 없음
    • 재선언 / 업데이트 가능
    • 안쓰는게 좋다
  • let

    • 블록 스코프
    • 변수 선언시 사용
    • 재선언 불가 / 업데이트만 가능
  • const

    • 블록 스코프
    • 상수 선언시 사용
    • 재선언 / 업데이트 불가
    • 초기화 필수
valueA = 1; // var가 생략되었음
const my_name ="WADE";

if(true){ // -- 코드블록의 시작입니다. -- //

	let valueB = 'Hello!';
	const my_name ="WADE";       // 코드블록 밖의 my_name과 별개의 상수입니다.

} // -- 코드블록의 끝입니다. -- //

valueB = 'nice to meet you!';  // 변수 정의 이전에 값을 할당 할 수 없습니다!
let valueB = 'Hi!';            // 코드블록 안의 valueB와 별개의 변수입니다.

함수

파이썬과 의미는 같다. 반복적으로 필요한 코드를 하나의 덩어리로 묶어서 필요할 때마다 꺼내 쓸 수 있도록 한 것을 함수라 한다.

기본 구조는 다음과 같다.

function 함수이름(parameter1, parameter2...) { // 함수의 선언
    // 실행코드...
    return 반환값
}

함수이름(argument1, argument2...) // 함수의 호출

파선아실 : 파라미터(매개변수)는 선언할때, 아규먼트(인자)는 실행할 때

console.log

콘솔 창에 표시되는 단순 출력이다.

function 안녕(파라미터){
    console.log(파라미터);
    console.log('hello');
    return 100;
}

안녕()	// undefined, hello, 100

return

함수 내부에서 return 구문을 만나면 함수는 즉시 종료되며 값을 반환한다.

function 안녕(){
    console.log('hello')
    console.log('hello')
    console.log('hello')
    return
    console.log('hello')
    console.log('hello')
    console.log('hello')
}

안녕()	// `hello` * 3

자바스크립트의 함수는 특이하게 아규먼트(인자)는 매개변수(파라미터)보다 적거나 많아도 에러가 발생하지 않는다.

존재하지 않는 값을 출력하면 undefined가 출력된다. 함수에 return이 없어도 undefiend

함수의 선언

  • 함수 선언문(구문)과 함수 표현식
    함수는 함수의 기본 형태인 구문으로 선언할 수도 있고, 제목 없이 선언하여 값으로 할당하는 표현식으로도 선언이 가능하다.
// 함수 선언문
function sum(x, y){
  return x + y;
}

// 함수 표현식
let sumXY = function(x, y){
  return x + y;
};
console.log(sum(10, 20));
console.log(sumXY(10, 20));

여기서 구문은 자바스크립트 명령문으로, 어떤 작업을 수행하기 위한 코드 블록이다. if, switch, for문 등이 해당된다.

표현식은 값으로 평가될 수 있는 것이다. 숫자나 문자열 같은 값 자체나 5<3과 같은 비교 연산자 등이 해당된다.

  • 화살표함수
    function 키워드를 화살표 기호로 대체해 표현할 수 있다. 화살표 함수는 제목을 정할 수 없기에 표현식으로 사용한다. 파이썬의 람다식과 비슷하다.
function 함수1(x, y) {
    return x + y
}
// 위 함수를 화살표 함수로 작성하면 아래와 같습니다.
let 함수1 = (x, y) => x + y

// 만악 함수 실행시 전달하는 인자가 한 개라면 소괄호를 생략할 수 있습니다.
let 함수2 = x => x + 10

// 화살표 함수 내부에서 한 줄 표현식만 반환한다면 return 키워드를 생략해도 됩니다.
let 함수3 = x => x + 10

let 결과 = 함수3(2);

console.log(결과); // 12
  • 즉시실행함수
    함수를 정의함과 동시에 실행하는 방법이다.
(function() {
  console.log('이 함수는 만들어지자마자 바로 실행됩니다!');
})();


(function() {
	document.querySelector(".btn").addEventListener("click", function(){ 
	console.log('click!')
	});
})();

이는 함수 내부 변수가 전역으로 저장되지 않기에 필요없는 전역 변수의 생성을 줄일 수 있다. 또한, 파이썬의 클로저와 비슷하게 내부 변수를 외부로부터 private하게 보호할 수 있다는 장점이 있다.


출처

유튜브
함수
호이스팅

profile
익숙해지기 위해 기록합니다

0개의 댓글