Skip to content
This page has been auto-translated and may contain errors.View in English

변수와 값

docs.scrimba.com

체크아웃 페이지를 만드는데 상품 가격이 세 곳, 즉 상품 항목, 합계, 결제 확인란에 표시된다고 해봅시다. 19.99를 세 곳에 직접 하나씩 입력하면, 세일이 벌어질 때마다 오후 시간을 통째로 찾아 바꾸기에 써야 합니다. 값을 이름 하나에 담아 저장해두면 한 곳만 바꿔도 그 이름을 쓰는 모든 곳이 함께 바뀝니다. 이 이름을 변수라고 하며, 이 장에서는 변수를 만드는 방법, 언제 값을 고정해야 하는지, 그리고 이름을 어떻게 지어야 하는지 다룹니다.

값 저장하기

**변수**는 값을 나중에 다시 쓸 수 있도록 붙여주는 이름입니다. let이라는 단어, 이름, =, 그리고 저장하고 싶은 값을 순서대로 써서 변수를 만듭니다.

js
let userName = "Sam";
console.log(userName); // Sam

이 줄은 ""Sam"이라는 텍스트를 userName이라는 이름으로 기억하라"는 뜻입니다. 이제부터 userName이라고 쓰면 어디서든 자바스크립트가 저장해둔 값을 돌려줍니다.

=는 "이 값을 이 이름으로 저장하라"는 뜻으로 읽으세요. 수학 수업에서 양쪽이 이미 같음을 나타내는 등호와는 다릅니다. =는 하나의 명령어로, 오른쪽에 있는 값을 가져다 왼쪽 이름 아래에 넣으라는 뜻입니다.

저장하라는 명령이기 때문에, 나중에 마음이 바뀌면 값을 바꿀 수 있습니다. 이름과 =를 다시 쓰고 새 값을 적으면, 자바스크립트는 가장 최근 값을 유지합니다.

js
let score = 0;
score = 10;
console.log(score); // 10

첫 줄은 score를 만들고 그 안에 0을 넣습니다. 둘째 줄은 새 값을 넣습니다. let을 두 번 쓰지 않은 이유는 score가 이미 존재하기 때문입니다. 새로 만드는 게 아니라 값을 갱신하는 것입니다.

변수는 값에 묶인(bound) 이름입니다. let으로 선언하고, 대입 연산자 =로 값을 설정합니다.

js
let total = 0;
total = 42;
console.log(total); // 42

=는 대입이며 비교가 아닙니다. 오른쪽 표현식을 평가한 다음, 그 결과를 왼쪽 이름에 저장합니다. 그래서 =는 "이 값을 대입하라"는 뜻이고, "같다"는 뜻은 절대 아닙니다. 연산자 편에서 만날 비교 연산자는 별도의 기호 ===입니다.

let으로 선언하면 이름이 만들어지고, 다시 대입하면 그 이름이 가진 값이 갱신됩니다. let은 변수 하나당 한 번만 씁니다. 그 이후에는 이름만 그대로 쓰면 됩니다.

js
let itemPrice = 19.99;
itemPrice = 24.99;
console.log(itemPrice); // 24.99

오른쪽에 오는 값은 자바스크립트의 데이터 타입 중 무엇이든 될 수 있습니다. 텍스트, 숫자, 불리언 등입니다. 변수는 어떤 타입인지 상관하지 않고, 마지막으로 대입된 값을 그대로 담고 있습니다.

변수는 값에 묶인 식별자(코드 안의 이름)입니다. =는 대입 연산자로, 오른쪽 표현식을 평가한 다음 그 결과를 왼쪽 이름에 묶습니다. =는 결코 같음을 검사하지 않고, 값을 고정된 상자에 복사해 넣는 것도 아닙니다. 이름이 값을 가리키게 하는 것입니다.

js
let total = 0;
total = 42;
console.log(total); // 42

재대입은 새 변수를 만드는 것이 아니라 기존 바인딩이 가리키는 대상을 바꾸는 것입니다. 숫자나 문자열 같은 원시값에서는 이 구분이 눈에 보이지 않습니다. 각 값이 독립적이고 자체로 완결되어 있기 때문입니다. 하지만 변수가 객체처럼 공유되는 무언가를 담는 순간부터 이 구분이 중요해집니다. 두 이름이 같은 값을 가리킬 수 있고, 한쪽을 통해 값을 바꾸면 다른 쪽에서도 그 변화가 보이기 때문입니다. 이 내용은 객체를 다룰 때 온전히 다시 살펴볼 것입니다. 지금은 이름이 값을 담고 있는 게 아니라 값을 가리키고 있다는 개념만 기억해두세요.

=가 하지 않는 것이 하나 더 있습니다. 값을 그 자리에 고정하지 않습니다. let score = 0은 "일단 score0을 가리키게 하라"는 뜻이고, 다음 줄에서 얼마든지 다른 값을 가리키게 할 수 있습니다. 바인딩을 다른 값으로 다시 가리킬 수 있는지 여부가 바로 letconst의 차이이며, 다음 절에서 다룹니다.

Juno값 저장하기 변수는 다시 쓰고 싶은 값에 붙이는 이름이며, let name = value 형태로 만듭니다. =는 "이 값을 이 이름으로 저장하라"는 뜻으로 읽으세요, 수학 수업의 등호가 아닙니다. 나중에 값을 바꾸려면 let 없이 이름과 =를 다시 쓰면 되고, 자바스크립트는 가장 최근 값을 유지합니다.
Juno값 저장하기let으로 선언하면 이름이 만들어지고, =로 대입하면 그 이름 아래에 값이 저장됩니다. =는 대입이며 비교가 아니므로 결코 "같다"는 뜻이 아닙니다. let은 변수마다 한 번만 쓰고, 그 뒤에는 이름만 써도 그 값이 갱신됩니다.
Juno값 저장하기=는 이름을 값에 묶는 연산자이며, 상자에 복사해 넣거나 같음을 검사하는 게 아닙니다. 재대입은 새 변수를 만드는 게 아니라 기존 바인딩이 가리키는 대상을 바꾸는 것입니다. 숫자와 문자열에서는 이 차이가 드러나지 않지만, 이름이 공유되는 무언가를 가리키는 순간부터 문제가 될 수 있으니, 객체가 등장하기 전에 "이름은 값을 가리킨다"는 생각을 기억해두세요.

let과 const

변수를 만드는 방법에는 letconst, 두 가지 단어가 있습니다. let은 이미 보았습니다. 값이 설정된 뒤로 절대 바뀌지 않아야 할 때는 const를 씁니다.

js
const taxRate = 0.2;
console.log(taxRate); // 0.2

세율은 고정된 값이므로 const가 어울립니다. "이 값은 정해졌고, 실수로 바뀌길 원하지 않는다"는 뜻을 담고 있습니다. const에 값을 다시 대입하려 하면 자바스크립트가 오류로 막아주는데, 이는 든든한 안전장치입니다.

먼저 const를 써보세요. let은 값이 바뀔 것이 확실할 때만 씁니다. 예를 들어 올라가는 점수나 계속 더해지는 합계 같은 경우입니다. 값이 평생 바뀌지 않는다면 const가 그 사실을 알려주고 지켜줍니다.

js
const currency = "USD";
let itemsInCart = 0;
itemsInCart = 3;
console.log(itemsInCart); // 3

화폐 단위는 바뀌지 않으므로 const입니다. 장바구니 개수는 바뀌므로 let입니다.

자바스크립트는 변수를 선언하는 두 가지 방법을 제공하며, 어느 것을 쓸지는 값을 재대입할 것인지에 달려 있습니다. const상수 바인딩을 선언합니다. 한 번 대입하고 나면 그 이름을 다른 값에 다시 가리키게 할 수 없습니다.

js
const taxRate = 0.2;
taxRate = 0.25; // TypeError: Assignment to constant variable.

let은 재대입을 허용하고, const는 금지합니다. 코드를 깔끔하게 유지하는 규칙은 기본적으로 const를 쓰고, 재대입이 꼭 필요할 때만 let을 쓰는 것입니다. 대부분의 변수는 한 번 설정되고 여러 번 읽히므로, 대부분은 const여야 합니다.

js
const currency = "USD";
let runningTotal = 0;
runningTotal = 19.99;
console.log(runningTotal); // 19.99

const는 값이 특별하다는 뜻이 아니라, 코드를 읽는 사람에게(다음 주의 나 자신을 포함해서) 이 이름은 움직이지 않을 것이라는 신호입니다. 이 신호는 프로그램을 읽기 쉽게 만듭니다. 믿고 그 자리에 그대로 있으리라 여길 수 있는 const가 있기 때문입니다.

letconst 둘 다 바인딩(이름과 값을 잇는 연결)을 선언합니다. 차이는 그 바인딩을 재대입할 수 있는지입니다. const는 바인딩을 고정합니다. 최초 대입 이후 그 이름을 새 값에 다시 가리키게 하려 하면 TypeError가 발생합니다.

js
const taxRate = 0.2;
taxRate = 0.25; // TypeError: Assignment to constant variable.

기본값은 const로 두고, 재대입이 실제로 필요한 곳에서만 let으로 내려가세요. 이는 형식을 따지는 결벽증이 아닙니다. const는 코드를 읽으면서 믿고 의지할 수 있는 사실이고, 바뀔 가능성이 있는 이름을 하나 줄여주며, 그만큼 버그가 숨을 수 있는 자리를 줄여줍니다.

일찍 짚어둘 만한 미묘한 지점이 있습니다. const는 바인딩을 고정할 뿐, 내용물을 고정하지는 않습니다. 이름을 다른 대상으로 다시 가리키는 것은 막지만, 값이 내부 구성 요소를 가진 것이라면 그 구성 요소는 여전히 바뀔 수 있습니다. 숫자나 문자열은 바뀔 만한 내부 구성 요소가 없으므로, 이런 값에는 const가 정확히 "이 값은 고정되어 있다"처럼 동작합니다. 반면 객체의 경우, const는 오직 그 이름이 같은 객체를 계속 가리킨다는 것만 보장할 뿐, 객체 자체의 내용물은 여전히 수정할 수 있습니다. 이 차이는 많은 사람을 놀라게 하는데, 디버깅 중에 겪기보다 지금 미리 받아들이는 게 낫습니다. 그래서 객체 편에서 이 내용을 바로 다시 다룹니다.

js
const currency = "USD";
let runningTotal = 0;
runningTotal = 19.99;
console.log(runningTotal); // 19.99

기존 코드에서 마주치게 될 세 번째, 더 오래된 키워드가 있습니다. var입니다. 쓰지 마세요. varlet과 두 가지 면에서 다르고, 둘 다 버그를 일으킵니다. 첫째, var함수 스코프를 가집니다. letconst가 존중하는 { } 블록을 무시하기 때문에, 블록 안에서 선언한 var도 그 블록을 감싸는 함수 전체로 새어 나갑니다. 반면 letconst블록 스코프를 가지며 가장 가까운 { } 안에 머무릅니다. 둘째, var호이스팅됩니다. 선언이 마치 자신의 스코프 맨 위로 옮겨진 것처럼 처리되어서, 선언된 줄에 도달하기 전에도 var 이름이 (undefined 값을 가진 채) 존재합니다. 이는 실수를 잡아내는 대신 숨겨버립니다.

letconst도 호이스팅되지만, 선언 줄 이전에 접근하면 조용히 undefined를 주는 게 아니라 오류를 던집니다. 이 이른 구간을 temporal dead zone이라고 부르는데, 여기서 발생하는 오류는 오히려 장점입니다. 조용한 버그를 시끄러운 버그로 바꿔주기 때문입니다. 요약하면, 기본적으로 const를 쓰고, 재대입이 필요할 때만 let을 쓰고, var는 예전 코드를 유지보수할 때 필요한 지식으로만 알아두면 됩니다.

Junolet과 const 절대 바뀌지 않아야 할 값에는 const를, 바뀔 값에는 let을 쓰세요. 먼저 const를 시도해보고, 값이 바뀌어야 한다는 걸 알 때만 let으로 바꾸세요. const에 재대입하면 오류가 나는데, 이는 안전장치가 제 역할을 하고 있는 것입니다.
Junolet과 constconst는 재대입을 금지하고, let은 허용합니다. 기본값은 const로 두고, 값이 정말 바뀌어야 할 때만 let을 쓰세요. const는 다음에 코드를 읽는 사람에게 이 이름이 움직이지 않을 것이라 알려줍니다. 대부분의 변수는 한 번 설정되고 여러 번 읽히므로, 대부분 const여야 합니다.
Junolet과 constconst는 바인딩을 고정할 뿐 내용물을 고정하지 않으므로, 이름을 재대입하면 TypeError가 나지만 그것이 가리키는 객체는 여전히 수정할 수 있습니다. 기본값은 const로 두고, 진짜 재대입이 필요할 때만 let을 쓰고, 오래된 var는 알아두기만 하세요. 함수 스코프와 호이스팅 방식이 버그를 숨기기 때문입니다. 바인딩과 내용물의 차이는 많은 사람을 놀라게 하니, 객체가 등장할 때를 대비해 기억해두세요.

변수 이름 짓기

변수 이름에는 몇 가지 규칙이 있습니다. 글자, 숫자, _, $를 쓸 수 있지만, 숫자로 시작할 수 없고, 공백을 포함할 수 없습니다.

js
let firstName = "Sam";
let item2 = "book";

이름은 대소문자를 구분합니다. 즉 firstNamefirstname은 서로 다른 변수입니다. 대문자를 잘못 쓰는 것은 초보자들이 흔히 겪는 실수이니, 이름을 일관되게 유지하는 게 도움이 됩니다.

자바스크립트 개발자들이 쓰는 표기법을 **camelCase**라고 부릅니다. 첫 글자는 소문자로 시작하고, 그 뒤에 오는 각 단어의 첫 글자를 대문자로 쓰며, 공백은 넣지 않습니다. 그래서 firstName, itemPrice, isLoggedIn처럼 씁니다.

js
let itemPrice = 19.99;
let isLoggedIn = true;

규칙을 넘어서, 담고 있는 내용을 그대로 드러내는 이름을 지향하세요. pricep보다 낫고, userNamex보다 낫습니다. 코드를 쓰는 시간보다 읽는 시간이 훨�다 길기 때문에, 명확한 이름이 코드를 읽기 쉽게 만듭니다.

유효한 이름의 규칙은 이렇습니다. 글자, 숫자, _, $를 포함할 수 있고, 숫자로 시작할 수 없으며, 공백이나 let 같은 예약어를 포함할 수 없습니다. 이름은 대소문자를 구분하므로, totalTotal은 서로 다른 변수입니다.

이 규칙 안에서 관례로 쓰이는 표기법이 **camelCase**입니다. 첫 단어는 소문자로 시작하고, 뒤이어 오는 단어들은 첫 글자를 대문자로 쓰며, 구분자를 넣지 않습니다.

js
let firstName = "Sam";
let itemPrice = 19.99;
let isLoggedIn = true;

이 관례는 언어 차원에서 강제되지 않지만, 여러분이 앞으로 참여할 모든 코드베이스가 강제하므로 처음부터 따르는 게 좋습니다. 불리언 값은 ishas 접두사를 붙이면(isLoggedIn, hasDiscount) 대체로 읽기 좋고, 값이 참/거짓이라는 것을 한눈에 알려줍니다.

이름은 곧 문서입니다. daysUntilExpiry는 이 값이 무엇을 뜻하는지 다음에 읽는 사람에게 알려주지만, d는 그 사람을 뒤지게 만듭니다. 설명적인 이름은 키 몇 번 더 누르는 비용을 들이는 대신 실제 시간을 아껴주니, 그 비용을 쓸 만합니다.

어휘 규칙은 이렇습니다. 유효한 식별자(코드 안의 이름)는 글자, 숫자, _, $를 포함할 수 있고, 숫자로 시작할 수 없으며, let, const, return 같은 예약어일 수 없습니다. 식별자는 대소문자를 구분하므로, totalTotal은 서로 다릅니다.

그 위에 얹힌 관례가 변수에 대한 camelCase이며, 언어가 강제하지 않아도 협상 불가능한 규칙으로 여겨도 무방합니다. 도구, 동료, 그리고 유명한 스타일 가이드 대부분이 이를 전제로 하므로, 벗어나면 얻는 것 없이 마찰만 늘어납니다.

js
const firstName = "Sam";
const itemPrice = 19.99;
const isLoggedIn = true;

더 값어치 있는 습관은 의미를 담아 이름을 짓는 것입니다. 이름은 여러분이 가진 가장 값싼 문서이면서, 값을 설명한다는 그 위치 덕분에 정확성이 가장 오래 유지될 문서입니다. remainingCredits는 리팩터링을 거쳐도 살아남지만, "남은 크레딧"이라고 적어둔 주석은 그렇지 않을 수 있습니다. 불리언은 예/아니오 질문처럼 읽히는 이름이 가장 좋습니다(isActive, hasAccess). 그리고 변경 이후에도 거짓을 말하게 되는 이름을 피하세요. 예를 들어 개념상 계속 더해지고 있는데도 const total이라 부르는 경우처럼요. 의미가 어긋나면 이름을 바꾸세요. 명확한 이름 짓기는 이 장에서 가장 효과가 큰 습관이며, 게다가 공짜입니다.

Juno변수 이름 짓기 이름에는 글자, 숫자, _, $를 쓸 수 있지만, 숫자로 시작하거나 공백을 포함할 수는 없습니다. 이름은 대소문자를 구분하므로 firstNamefirstname은 서로 다릅니다. itemPrice처럼 camelCase를 쓰고, 담고 있는 내용을 드러내는 이름을 골라 p 대신 price를 쓰세요.
Juno변수 이름 짓기 유효한 이름은 글자, 숫자, _, $를 쓰고, 숫자로 시작하지 않으며, 대소문자를 구분합니다. 관례는 camelCase이며, 언어가 강제하지 않아도 모든 코드베이스가 강제하니 처음부터 따르세요. 설명적인 이름은 정확성을 오래 유지하는 문서이니, d 대신 daysUntilExpiry에 키 몇 번 더 쓰는 값어치를 하세요.
Juno변수 이름 짓기 식별자는 글자, 숫자, _, $를 허용하고, 숫자로 시작할 수 없고, 예약어일 수 없고, 대소문자를 구분합니다. camelCase를 쓰세요. 언어가 강제하지 않아도 모든 도구와 동료가 이를 전제로 합니다. 의미를 담아 이름 짓기는 여기서 가장 효과가 큰 습관이며 비용이 전혀 들지 않으니, r 대신 remainingCredits를 기본으로 삼으세요.

변수, 그다음은

변수는 그 위에 나머지 모든 것이 올라서는 토대입니다. 값은 그것을 가리킬 이름이 있기 전까지는 쓸모가 없습니다. 이제 여러분은 중요한 세 가지 동작, 즉 let으로 값을 저장하고, const로 값을 고정하고, 이름을 잘 짓는 법을 익혔고, 앞으로 작성할 모든 프로그램에서 이 셋을 계속 쓰게 될 것입니다.

다음으로는 데이터 타입 편에서 지금까지 저장해온 텍스트, 숫자, 불리언 같은 값 자체를 살펴보고, 각 타입이 그렇게 동작하는 이유를 알아봅니다. 그다음 연산자 편에서는 이 값들을 조합하는 방법을 보여주고, 함수 편에서는 변수가 값에 이름을 붙이듯 작업 하나에 이름을 붙이는 방법을 배웁니다.