변수는 값을 담기 위해 이름을 붙인 상자입니다. 변수는 컴퓨터의 메모리에 일정한 크기의 영역으로 생성됩니다. 일반적인 프로그램은 변수 값을 알고리즘에 따라 변화시켜서 프로그램이 의도한 목적을 달성.
var joke;
메모리에 joke라는 이름이 붙은 영역이 생성됩니다. var은 변수를 선언하기 위한 선언자입니다. joke는 변수 이름이라고 부릅니다. 이 변수 이름을 활용하여 값을 읽거나 사용할 수 있습니다.
// 쉼표를 사용하여 여러개의 변수 선언 가능
var sum, a;
// 변수를 선언하기만 하면 변수안에 정의 하지않았기에 undefined값이 출력
var a;
console.log(a);
// 변수를 여러개 선언하고 초깃값 설정을 쉼표로 구분하여 한 문장만 사용하여 표현이 가능합니다.
var a = 1, b = 2, c = 3;
프로그램은 작성한 순서에 따라 윗줄부터 차례대로 실행됩니다. 하지만 변수 선언은 이 원칙을 따르지 않습니다.
console.log(x);
var x;
이 코드에서 변수x가 선언되지 않았기에 에러가 발생할 것 같지만, 실제로는 undefined가 출력됩니다. 이는 프로그램 중간에서 변수를 선언하더라도 변수가 프로그램 첫 머리에 선언된 것 처럼 다른 문장 앞에 생성되기 떄문입니다. 이를 변수 선언의 끌어올림 호이스팅(hoisting) 이라고 합니다.
console.log(x) // undefined
var x = 5;
console.log(x); // 5
단, 위의 코드 처럼 선언과 동시에 대입하는 코드는 끌어올리지 않습니다.
변수 선언의 끌어올림 호이스팅은 다른 언어에 없는 자바스크립트만의 고유한 특징입니다. 그래서 다른 프로그램의 언어 사용자도 이해하기 쉽도록, 변수 선언을 시작 부분에 하는 것이 좋습니다.
데이터 타입이란 숫자나 문자열 처럼 변수에 저장하는 데이터 종류를 뜻합니다. C/Java 등 프로그래밍 언어에는 정수 타입 변수, 부동 소수점 타입 변수 등이 있어 타입이 일치하는 변수만 저장할 수 있습니다. 이러한 언어들을 정적 타입 언어(static typed language)라고 부릅니다. 하지만 JS에는 변수에 타입이 없으므로 모든 타입의 데이터를 저장할 수 있습니다. 다음 코드에서 확인해보겠습니다.
let randomNumber = 3.2342344
console.log(randomNumber) // 3.2342344
let randomNumber = "문자열도 입력가능"
console.log(randomNumber); // 문자열도 입력가능
위에서 실수형 데이터값에서 문자열 값으로 변형된 것 처럼 다양한 타입의 데이터를 대입할 수 있습니다. JS에서는 같은 변수에 숫자나 문자열과 같은 다양한 타입의 데이터를 대입할 수 있습니다. 이처럼 실행할 떄 변수에 저장된 데이터 타입을 동적으로 바꿀 수 있는 언어를 가리켜 동적 타입 언어(dynamic typed language)라고 부릅니다. 자바스크립트 프로그램을 실행할 떄 발생하는 타입 변환에 주의하여 변수에 어떤 타입의 데이터가 저장되는지 잘 확인해야 합니다.
자바스크립트가 처리할 수 있는 데이터 타입은 크게 2가지 바로 원시 타입, 객체 타입입니다.
원시타입데이터는 데이터를 구성하는 가장 기본적인 요소로 불변 값(값을 바꿀 수 없는 데이터)으로 정의.
원시타입 : 숫자, 문자열, 논리값, 특수한 값(undefined, null), 심벌(Symbol)
원시 타입의 속하지 않는 자바스크립트의 값은 객체라고 합니다. 객체는 변수 여러 개가 모여서 만들어진 복합 데이터 타입입니다. 객체 안에 저장된 값은 바꿀 수 있습니다. 객체는 참조 타입입니다. 따라서 객체 타입의 값을 변수에 대입하면 변수에는 그 객체에 대한 참조(메모리에서의 위치 정보)가 할당됩니다.
객체타입 : 배열, 함수, 정규표현식 등...
대다수의 프로그래밍 언어에는 정수 타입과, 부동소수점 타입이 따로 있지만 자바스크립트에는 타입이 없으므로 숫자를 모두 64비트 부동소수점으로 표현합니다. 이는 C/Java 에서의 double 타입에 해당합니다. 단, 배열 인덱스와 비트 연산 만큼은 32비트 정수로 처리합니다.
프로그램에 직접 작성할 수 있는 상수 값은 리터럴(literal)이라고 합니다. 숫자를 표현하는 리터럴에는 정수 리터럴과 부동소수점 리터럴이 있습니다.
책 81pg 참조.
자바스크립트의 문자열은 길이가 16비트인 유니코드 문자(UTF-16)를 나열한 것으로 전 세계에서 사용하는 문자를 대부분 표현이 가능합니다. 문자열 리터럴은 작은따옴표, 큰따옴표를 문자열의 앞뒤에 붙여서 표현합니다.
"" 를 사용한다면 이는 공백 즉, 빈 문자열입니다.
줄 바꿈 문자, 탭 문자 등은 문자열에 그대로 추가할 수 없습니다. 이러한 특수 문자는 이스케이프 시퀀스로 표현해야 합니다. 역슬래시() 뒤에 특정 문자를 뜻하는 기호를 넣어 표기하면 됩니다.
논리값은 조건식이 참인지 거짓인지 표현하기 위해 사용하는 값 입니다. 논리값에는 true/false 두 가지 종류가 있습니다. true는 참을 뜻하고 false는 거짓을 뜻합니다.
==은 좌변값과 우변값이 같은지 판단하는 관계연산자입니다. 즉, x == 7 이라고 할 경우 x값이 7이 맞다면 true 아니라면 false가 출력됩니다.
자바스크립트에서는 주로 논리값을 제어 구문(if/else문, while문, do/while문, for문)에 사용합니다.
값이 없음을 표현하기 위한 특수 값에는 null / undefined 가 있습니다.
undefined는 말그대로 정의가 되지않은 상태를 의미합니다.
즉, 값을 아직 할당하지 않은 변수의 값, 없는 객체의 프로퍼티를 읽으려고 시도했을 떄의 값, 없는 배열의 요소를 읽으려고 시도했을 때의 값, 아무것도 반환하지 않는 함수가 반환하는 값, 함수를 호출했을떄 전달받지 못한 인수의 값이 주된 예시다.
null은 아무것도 없음을 값으로 표현한 리터럴입니다. null은 주로 프로그램에서 무언가를 검색했지만 찾지 못했을 떄 아무것도 없음을 전달하기 위한 값으로 사용됩니다. 따라서 값을 읽을 떄 값이 null인지 아닌지 확인해야 하는 상황이 자주 발생합니다.
심벌은 ECMAScript 6부터 추가된 원시 값입니다. 심벌은 자기 자신을 제외한 그 어떤 값과도 다른 유일무이한 값입니다.
무슨소린가 싶을텐데 아래 예제 코드를 한번 보면 이해가 쉽습니다.
var sym1 = symbol();
var sym2 = symbol();
console.log(sym1 == sym2); // false
Symbol()은 호출할 떄마다 새로운 값을 만듭니다. 또한 Symbol()에 인수를 전달하면 생성된 심벌의 설명을 덧붙일 수 있습니다.
var HEART = Symbol("하트");
심벌의 설명은 toString() 메서드를 사용해서 확인할 수 있습니다.
console.log(HEART.toString()); // Symbol(하트)
Symbol() 활용 예제!
오셀로 게임을 만든다고 가정했을떄 칸의 상태를 값으로 표현하는 코드를 작성한다고 해보자.
var NONE = 0; // 칸에 돌이 놓여져있지 않은상태
var BLACK = -1; // 칸에 검은 돌이 놓여있는 상태
var WHITE = 1; // 칸에 흰 돌이 놓여있는 상태
위의 코드에서 숫자 자체에는 큰 의미가 없습니다. 칸의 상태를 cell 변수에 저장한다고 가정했을때, cell 값을 확인할려면 cell == white라고 작성해야 프로그램이 읽기 쉬어질 것입니다. 게다가 cell == 1 이라 작성해도 아무런 문제없이 동작합니다. 아래와 같이 코드를 symbol()을 사용해 작성하는 것이 좋습니다.
var NONE = Symbol("none");
var BLACK = Symbol("black");
var WHITE = Symbol("white");
심벌은 유일무이한 값이다. 이렇게 수정하면 변수 cell 값을 확인할 떄 NONE, BLACK, WHITE만 사용하도록 제한 가능하다.
Symbol.for()를 활용하여 문자열과 연결된 심벌을 생성할 수 있다.
var sym1 = Symbol.for("club");
이렇게 하면 전역 레지스트리에 심벌이 만들어집니다. 전역 레지스트리에서 이 심벌을 위에 지정한 문자열로 불러올 수 있습니다.
var sym2 = Symbol.for("club");
console.log(sym1 === syme); // => true
이 기능을 활용하면 코드의 어떠한 부분이라도 같은 symbol을 공유할 수 있다. symbol과 연결된 문자열은 symbol.keyFor()로 구할 수 있다.
var sym1 = symbol.for("club");
var sym2 = symbol("club");
console.log(Symbol.keyFor(sym1)); // club
console.log(Symbol.keyFor(sym2)); // undefined
템플릿 리터럴은 ECMAScript 6부터 추가된 문자열 표현 구문입니다. 템플릿이란 일부만 변경해서 반복하거나 재사용할 수 있는 틀을 말합니다. 템플릿 리터럴을 사용하면 표현식의 값을 문자열에 추가하거나 여러 줄의 문자열을 표현할 수 있습니다.
기본적인 사용법
템플릿 리터럴은 역따옴표()로 묶은 문자열입니다. 간단한 템플릿 리터럴은 큰따옴표 또는 작은 따옴표로 묶은 문자열과 모습이 같습니다. I'm going to learn Javascript`
문자열 리터럴에서 줄바꿈 문자를 표현할 떄는 이스케이프 시퀀스(\n)을 사용했지만, 템플릿 리터럴을 사용하면 일반적인 줄 바꿈 문자를 사용할 수 있습니다.
var t = `Man errs as long as
he strives.`;
이 문자열은 문자열 리터럴로 표현하면 다음과 같은 모습이 됩니다.
var t = "Man errs as long as\n he strives."
/*
Man errs as long as
he strives.
*/
물론 템플릿 리터럴에서도 이스케이프 시퀀스를 사용할 수 있습니다.
var t = `Man errs as long as\nhe strives.`;
/*
Man errs as long as
he strives.
*/
이스케이프 시퀀스 문자를 그대로 출력하려면 템플릿 리터럴 앞에 Stirng.raw를 붙입니다.
var t = String.raw`Man errs as long as\n he strives.`;
/*
Man errs as long as\n he strives.
*/
이 문자열을 문자열 리터럴로 표현하면 다음과 같은 모습이 됩니다.
var t = "Man errs as long as\\nhe strives.";
/*
Man errs as long as\nhe strives.
*/
템플릿 리터럴 앞에 붙은 String.raw는 태그 함수라 부른다.
템플릿 리터럴 안에는 place holder를 넣을 수 있습니다. ${...}로 표기합니다. 자바스크립트 엔진은 place holder 안에 든 ... 부분을 표현식으로 간주하여 평가합니다. 이를 활용하여 문자열 안에 변수나 표현식의 결괏값을 삽입을 할 수 있습니다.
var a = 2, b = 3;
console.log(`${a} + ${b} = ${a+b}`); // 2 + 3 = 5
var now = new Date();
console.log(`오늘은 ${now.getMonth() + 1} 월 ${now.getDate()} 일입니다.`);