[JavaScript] 변수?

박준석·2024년 4월 3일

JavaScript

목록 보기
1/10
post-thumbnail

자바스크립트 변수

변수란?

변수는 하나의 값을 저장하기 위해 확보한 메모리 공간이며, 메모리 공간을 식별하기 위해 붙인 이름이다.
변수의 특별한 점은 문자열과 숫자뿐 아니라 무엇이든 포함할 수 있다는 것이다.

변수는 값을 포함하기 때문에 값을 담는 박스와 같다고도 생각하면 된다.

변수

자바스크립트에서는 선언되지 않은 변수를 사용하려고 하거나 접근하려면 오류가 발생한다.
오류

변수 선언

변수를 사용하기 위해서는 먼저 변수를 만들어야 한다. 이를 변수 선언이라고 한다. 변수 선언은 크게 세가지 종류가 있다. let, const, var가 있다.

let color;
const color2;
var color3;

위와 같이 변수를 선언할 수 있다. 변수를 선언할 때 자바스크립트 엔진은 변수 선언을 3단계에 걸쳐 수행한다.

즉, 위 코드는 메모리 공간은 확보를 했지만 할당은 되지 않았다. 그렇다면 확보된 메모리 공간은 비어있을까? 그건 아니다. 확보된 메모리 공간에는 자바스크립트 엔진에 의해 undefined가 암묵적으로 할당되어 있어 초기화된다.

  1. 선언단계 : 변수 이름을 등록하여 JavaScript 엔진에 변수 존재를 알린다.
  2. 초기화 단계 : 값을 저장하기 위한 메모리 공간을 확보하고 undefined를 할당하여 초기화 한다.
  3. 할당 단계 : 사용자가 undefined로 초기화된 메모리의 다른 값을 할당하는 단계이다.

💡 초기화 : 변수가 생성되고 최초로 값을 할당하는 것을 말한다.

초기화를 하는 이유는 초기화를 하지 않는다면 이전에 사용했던 값이 남아 있을 수 있다. 이것을 쓰레기 값이라고 부른다.

💡 초기화 방법

🚫 var
JavaScript가 처음 만들어졌을 때 변수를 선언하는 유일한 방법이었다. var는 오류를 발생하기 쉬웠다. var 재선언과 재할당이 가능했기 때문에 코드르 작성하다보면 혼란을 일으켰다.

var a = 1;
console.log(a);
var a = 2;
console.log(a);

변수의 이름

자바스크립트에서 변수는 이름을 가지고 식별하므로, 변수의 이름은 식별자라고 한다. 변수의 이름은 영문자(대소문자), 숫자, 언더스코어(_) 또는 달러($)로만 구성된다.

단, 숫자와의 구분을 빠르게 하려고 숫자로 시작할 수 없다. 이러한 변수의 이름은 대소문자를 구분하며, 자바스크립트 언어에서 예약된 키워드는 이름으로 사용할 수 없다.

const mathScore = 100;const math_score = 100;const 1_mathScore = 100;

var, let, const 차이

var

var는 재선언과 재할당이 가능하다.

var a = 1;
console.log(a);

var a = 2;
console.log(a);

var는 변수의 이름이 중복이 되어도 오류가 뜨지 않는다. 또 전역변수와 지역변수의 개념이 확실하지 않다. var같은 경우에는 함수만 지역변수로 호이스팅되고 나머지는 전역변수로 다 올려버린다.

  • var 문제점
var greeter = "hey hi";
var times = 4;

if (times > 3) {
   var greeter = "say Hello instead"; 
}
    
console.log(greeter) // "say Hello instead"

times > 3true로 반환하기 때문에 greeter는 "say Hello instead"로 재정의 된다. 이것이 의도적으로 정의한 것이라면 문제가 없는 코드이지만 var greeter = "hey hi"; 로 이미 정의를 한 사실을 인식하지 못한 경우에는 문제가 된다.

let

let은 재할당은 되지만, 재선언은 불가능하다.

let greeting = "say Hi";
    greeting = "say Hello instead";
 // 재할당 가능
 
let greeting = "say Hi";
let greeting = "say Hello instead"; // error: Identifier 'greeting' has already been declared
// 재선언 불가능

하지만 동일한 변수가 다른 범위 내에서 정의가 될 수 있다.

  let greeting = "say Hi";
    if (true) {
        let greeting = "say Hello instead";
        console.log(greeting); // "say Hello instead"
    }
    console.log(greeting); // "say Hi"

letvar에 문제점을 보완하기 위해 만들어진 키워드이다.

const

const는 재선언, 재할당이 불가능하다.

const greeting = "say Hi";
greeting = "say Hello instead";// error: Assignment to constant variable. 
const greeting = "say Hi";
const greeting = "say Hello instead";// error: Identifier 'greeting' has alread

따라서 모든 const는 선언과 초기화가 동시에 일어나야한다.

const도 재할당이 가능한 경우가 있다. 객체의 경우 const 객체는 업데이트 할 수 없지만, 객체의 속성은 재할당이 가능하다. 아래 코드로 예시를 살펴보자.

    const greeting = {
        message: "say Hi",
        times: 4
    }

아래와 같은 작업은 불가능하다.

greeting = {
        words: "Hello",
        number: "five"
    } // error:  Assignment to constant variable.

하지만 다음 코드는 정상 작동한다.

greeting.message = "say Hello instead";

지역변수와 전역변수

지역변수

지역 변수는 특정 함수 내에서 정의되거나 블록({}) 내에서 정의된다. 이러한 변수는 해당 함수나 블록 내에서만 유효하며 외부에서 접근할 수 없다.

function calculateSum() {
    // 지역 변수 num1과 num2를 정의
    let num1 = 5;
    let num2 = 10;
    
    // num1과 num2를 더한 값을 반환
    return num1 + num2;
}

// calculateSum 함수 호출
console.log(calculateSum()); // 출력: 15

// console.log(num1); // 에러: num1은 calculateSum 함수 내에서 정의된 지역 변수이므로 외부에서 접근할 수 없다

전역변수

전역 변수는 전체에서 접근할 수 있는 변수를 말한다. 즉, 어떤 함수나 블록 안에서 정의되지 않고 스크립트의 최상의 레벨에서 선언된 변수이다. 전역 변수는 어디서든지 접근이 가능하기 때문에 주의해서 사용해야 한다.

전역변수를 남발하면 코드를 이해하기 어렵고, 변수명끼리 충돌이 발생할 수 있다.

let globalVariable = 100;

function printGlobalVariable() {
    console.log(globalVariable); // 전역 변수에 접근
}

printGlobalVariable(); // 출력: 100

// 다른 함수나 블록에서도 globalVariable에 접근 가능
function updateGlobalVariable() {
    globalVariable = 200;
}

updateGlobalVariable();
console.log(globalVariable); // 출력: 200

호이스팅

JavaScript는 인터프리터 방식이기 때문에 코드를 순차적으로 읽어나간다.

myName = "Chris";

function logName() {
  console.log(myName);
}

logName();

var myName;

위 코드를 보면 변수를 선언하기 전에 myName = "Chris";로 할당한 것이 보인다. 이러면 에러가 날 것 같지만 var는 에러가 나지 않는다. 그 이유는 호이스팅 때문이다.

호이스팅은 코드를 실행하기 전 변수선언/함수선언이 해당 스코프의 최상단으로 끌어 올려진 것 같은 현상을 말한다. 다시말해 끌어올려진 것이 아니라 끌어 올려진 것 같은 현상이다. 소스를 실행하기 전 소스 실행 준비를 하는데 이 때 변수 선언을 포함한 모든 선언문을 소스코드에서 먼저 실행한다.(실행컨텍스트에 가져다 둠)

let, const 호이스팅?

console.log(score); //ReferenceError
let score = 'red';

letconst로 변수가 선언되기 전에 변수를 출력을 하게 되면 참조오류가 발생되는 것을 볼 수 있다. 그렇다면 letconst는 호이스팅이 되지 않는 것 일까? 아니다. letconst로 선언된 변수는 TDZ(Temporal Dead Zone)에 영향을 받기 때문에 TDZ에 있는 변수들을 사용할 수 없는 것이다.

TDZ에 대해서 알아보기 위해 변수의 생성과정을 먼저 알아야 한다.

변수 생성 3단계

위에서 잠깐 설명한 것 처럼 JavaScript에서 변수는 3가지 단계를 걸쳐 생성된다.
1. 선언 단계
2. 초기화 단계
3. 할당단계

var

var 변수 생성 단계
var 키워드는 변수 선언과 초기화가 동시에 진행되는데 할당하기 전에 호출을 하면 error가 발생하지 않고 undefined를 반환한다.

var x // 선언 단계 및 초기화 단계까 동시에 진행
console.log(x); // 선언, 초기화 단계가 진행되었기 때문에 undefined 반환
x = 1; // 할당

let

let 변수 생성 단계
let 키워드는 변수 선언과 초기화가 나누어서 진행된다. 스코프에 변수를 등록하지만 초기화 단계는 변수 선언문에 도달했을 때 이루어진다. 그렇기 때문에 초기화 이전에 변수에 접근하면 참조 에러가 발생한다.

console.log(x); // Reference Error, TDZ구간

let x; // 초기화 단계
console.log(x); // undefined

x = 13 // 할당 단계
console.log(x); // 13
let y = 10; // 전역 변수

{
  console.log(y); // Reference Error
  let y = 29; // 지역 변수
}

let 키워드는 호이스팅이 되는 것을 알려주고 있다. 코드 블록의 시작점 부터, 초기화가 이루어지는 지점까지의 TDZ에 빠지기 때문에 에러를 발생한다.

const

const 키워드는 재할당 및 재선언이 금지된다. 그렇기 때문에 선언 및 할당을 동시에 해야한다.

profile
느리지만 탄탄한 개발자 1명 빠른 개발자 10명 안부럽다.

0개의 댓글