Variable 변수

Yeonn·2023년 4월 26일
0

JavaScript

목록 보기
2/22
post-thumbnail

01 Variable 변수

  • 변수(Variable) : 값의 위치를 가리키는 상징적인 이름
    ( 하나의 값을 저장하기 위해 할당된 메모리 공간, 그 공간을 식별하기 위한 이름 )

  • 변수 이름(변수명) : 저장된 값을 식별 할 수 있는 이름

  • 변수 값 : 변수에 저장 된 값

  • 할당(assignment) : 변수에 값을 저장, 기억시키는 것

  • 참조(reference) : 변수에서 저장된 값을 불러오는 것

식별자(identifier)는 어떤 값을 구별해서 식별할 수 있는 고유한 이름을 의미한다. 즉, 변수, 함수, 클래스 등 모든 선언에 의한 존재들의 '이름'은 식별자(identifier)이다.

02 변수 선언과 값의 할당

var hello;  // undefined 출력
hello = 'hello!'; // 'hello!' 출력

변수를 사용하려면 반드시 선언이 필요하다. 이 때 var, let, const 키워드가 사용된다.
변수의 선언은 선언을 통해 자바스크립트에 변수의 존재를 알리고, 초기화를 통해 변수의 값을 저장할 공간을 확보한 뒤 undefined를 할당한다.
만약 선언하지 않은 식별자를 호출 할 경우 ReferenceError(참조 에러)가 발생한다.

이렇게 선언을 통한 초기화를 한 뒤 변수명에 값을 할당해 주면 된다.
그러나 위의 두줄로 나뉘어 진 선언문을 다음과 같이 한 줄로 표현할 수 있고 동일하게 작동한다.

var hello = 'hello!'; // 'hello!' 출력

03 변수 호이스팅

console.log(hello); //undefined
var hello; 

아직 선언되지 않은 변수가 호출 되고, 그 다음에 변수가 선언되었다. 이 경우 ReferenceError를 예상 할 수도 있지만 undefined가 출력된다.

그 이유는 소스코드가 실행되는 시점(런타임) 이전에 소스코드 평가 과정에서 자바스크립트 엔진이 모든 선언문을 찾아 먼저 실행하기 때문이다.
하지만 이 때, 변수 선언과 값이 모두 먼저 일어나는 것이 아니라 선언만 먼저 이루어지고 아직 값은 할당되지 않은 상태이다. 즉 위에서 부터 아래로 한 줄씩 순차적으로 실행하는 것이 기본 순서이나 이 런타임 이전의 평가 과정에서 선언문만 먼저 찾아내 실행 한 뒤, 다시 위에서 부터 아래로 순차적으로 실행해 나가면서 값이 할당된다는 것이다.

이처럼 변수 선언문이 코드의 가장 위에 작성된 것 처럼 동작하는 자바스크립트의 특징을 변수 호이스팅이라고 한다. 호이스팅은 변수에만 이루어 지는 것이 아니라 모든 선언문이 해당한다.


var

ES5까지는 유일한 변수 선언 방법이었다. 하지만 몇 가지 문제가 있어 이를 보완하기 위해 ES6에서 다음에 설명할 letconst가 도입되었다. 이후 letconst의 사용이 권장되나 ES6 이전 코드는 var키워드를 통해 구현되어 있을 것이므로 알아두는 것이 좋다.

01 변수 중복 선언 가능

var로 선언한 변수는 중복 선언이 가능하다.

var hello = 'hello';
var hello = 'hello!!!';

var 키워드로 hello 가 중복 선언 되었다. 위와 같은 경우 재선언 되어 'hello!!!'가 오류없이 출력되어 나온다. 이 때 만약 값의 재할당을 원한 것이 아니라 두가지의 다른 변수선언을 원했다면 변수 하나가 사라져 버리므로 문제가 된다.

02 함수레벨 스코프(function scoped)

var number = 10;
if(true) {
//함수의 내용
var number = 100;
}

선언된 함수 하나의 안에서만 사용 될 수 있다. 함수 외부 에서는 접근이 불가하다.

그런데 이 때, 위의 예시처럼 함수 안의 변수가 선언되기 전에 전역 변수로 number가 선언되었다. 전역 변수 number가 가지고 있는 값은 10이다. 그 아래에 if문 안에 동일한 이름의 number 변수가 선언되었고 할당된 값은 100이다.
var로 선언된 변수는 코드 블록 안에서 재선언 하는 경우 모두 전역변수가 된다. 즉 함수레벨 스코프는 전역 변수의 남발의 가능성을 높여 스코프오염의 위험성을 높인다.

03 호이스팅

위에서 설명한 호이스팅을 그대로 보여준다. 값 할당 전에 출력 키워드를 만나면 undefined를 출력하고 이 후 값 할당 후 출력 키워드를 만나면 할당된 값을 출력한다.


위에서 본 var에는 전역 변수가 남발될 가능성과, 재선언으로 인한 문제가 있었다. 이러한 문제들을 보완하기 위해 나온 키워드가 letconst이다. 둘은 비슷하지만 차이가 있다.


const / let

01 중복 선언 금지

const hello = 'hello';
const hello = 'hello!'; 
// SyntaxError: Identifier 'hello' has already been declared

constlet으로 선언한 변수는 중복 선언 할 수 없다. 위의 var에서 의도치 않게 같은 변수명을 재선언하게 되어 먼저 선언된 변수까지 값이 재할당 되는 부작용을 막기 위한 부분이다. 중복 선언이 될 경우 SyntaxError: Identifier 'hello' has already been declared 라는 에러가 나온다.

02 블록 레벨 스코프(block-level scope)

constlet은 모든 코드 블록을 각각의 지역 스코프로 분리한다. 이는 함수, if문, for문{}로 감싸지는 공간 모두 각각의 지역으로 분리한다는 것이다.

하나의 함수 안에서도 {}로 분리된 지역이라면 같은 이름의 변수를 새롭게 생성할 수 있으며, 각 지역에서의 변수는 각각의 역할을 한다.

03 변수 호이스팅

console.log(hello); 
//caught ReferenceError: hello is not defined
let hello; 

constlet은 마치 호이스팅이 일어나지 않는 것처럼 동작한다. varundefined를 출력했던 것과 달리 constletreferenceError가 발생한다.

하지만 그렇다고 해서 호이스팅이 일어나지 않는다는 의미는 아니다. 호이스팅은 동일하게 일어나지만 '스코프의 시작 지점' 부터 '변수 선언문(초기화)' 단계까지 해당 변수를 참조할 수 없다. 이러한 참조 불가한 구간을 일시적 사각지대(Temporal Dead Zone) 이라고 한다.

04 const vs. let

01 선언과 값의 할당

const 키워드는 선언과 값의 할당이 동시에 이루어 져야 한다.
그렇지 않으면 SyntaxError: Missing initializer in const declaration 에러가 발생한다.
let 키워드는 선언과 값의 할당을 각각 분리하여 할 수 있다.

02 재할당

const로 선언한 변수는 값을 재할당 할 수 없다. 그래서 상수의 개념으로 쓰이기도 한다. 이는 상태 유지와 가독성, 유지보수 등을 위해 적극적으로 사용하면 좋다.

예를 들어 세율 같이 쉽게 바뀌지 않는 숫자이면서 코드 전체에 동일하게 적용되는 값 등은 매번 퍼센트를 작성하기 보다 const로 선언 후 변수를 사용하면 이 후 값이 변경 되어 코드를 수정하게 되어도 변수 선언문을 찾아 한번만 값을 변경하면 되므로 유지보수에 매우 효율적이다.

그러나 let은 재할당이 가능하다. 이때 var와의 차이점은 스코프 영역에 있다.


05 식별자 네이밍 규칙

  • 식별자는 특수문자를 제외한 문자, 숫자, 언더스코어(_), 달러기호($)를 포함할 수 있다.
  • 식별자는 문자, 언더스코어(_), 달러기호($) 로 시작해야 한다. 숫자로는 시작할 수 없다.
  • 예약어는 식별자로 사용할 수 없다.

변수의 이름은 자유롭게 설정할 수 있으나 해당 변수의 목적이 무엇인지를 명확히 담을 수 있도록 해야한다. 이는 코드의 가독성을 높여 유지보수에 도움을 준다.

let sayHello; // 카멜 케이스(camelCase)
let say_hello // 스네이크 케이스(snake_case)
let SayHello; // 파스칼 케이스(PascalCase)

일관성을 유지하여 작성한다면, 어느 케이스를 사용해도 무방하다. 하지만 일반적으로 변수나 함수의 이름에는 카멜 케이스를 사용하고 생성자 함수, 클래스의 이름에는 파스칼 케이스가 사용되므로 이를 따르는 것이 가독성을 높이는 데 유리하다.

코드를 작성하다 보면 변수가 많아지고 이러한 변수들에게 매번 명확한 이름을 부여하기는 매우 어렵다. 다음은 변수명을 짓는데 도움을 주는 사이트이다.

https://www.curioustore.com/#!/util/naming

0개의 댓글