해당 글의 내용은 poiemaweb 을 읽고 요약하여 재정리한 내용입니다.
이번에는 JavaScript lesson 5, 6에 해당되는 자바스크립트의 기본 문법, 데이터 타입과 변수에 대해 알아보겠습니다.
5. 자바스크립트의 기본 문법(Syntax Basics)
변수(Variable)
변수는 값(value)을 할당(저장)하고, 할당된 값을 참조하기 위해 사용됩니다.
유지(캐싱)할 필요가 있는 값은 변수에 담아 사용합니다.
또, 위치(주소)를 기억하는 저장소인데 여기서 위치란 메모리 상의 주소를 의미합니다.
즉, 메모리 주소(Memory address)에 접근하기 위해 사람이 이해할 수 있는 언어로 지정한 식별자(identifier)입니다.
변수를 선언할 때 var
키워드를 사용하며, 할당 연산자 =
은 값을 변수에 할당하기 위해 사용합니다.
var x; // 변수 선언
x = 7; // 값 할당
값(value)
값은 프로그램에 의해 조작될 수 있는 대상을 말합니다.
다양한 방법으로 생성할 수 있으며, 가장 간단한 방법은 리터럴 표기법(literal notation)을 사용하는 것입니다.
- 리터럴? 소스코드 안에서 직접 만들어 낸 상수 값 자체를 말하며 값을 구성하는 최소 단위
다음은 리터럴 예시 입니다.
// 숫자 리터럴
10.50
1001
// 문자열 리터럴
'Hello'
"World"
// 불리언 리터럴
true
false
// null 리터럴
null
// undefined 리터럴
undefined
// 객체 리터럴
{ name: 'Lee', gender: 'male' }
// 배열 리터럴
[ 1, 2, 3 ]
// 정규표현식 리터럴
/ab+c/
// 함수 리터럴
function() {}
자바스크립트의 모든 값은 데이터 타입을 가지며, 총 7가지 데이터 타입이 있습니다.
원시 타입 (primitive data type) :
number
,string
,boolean
,null
,undefined
,symbol
(New in ECMAScript 6)객체 타입 (Object data type) :
object
다른 언어와는 다르게 변수 선언할 때 데이터 타입을 미리 지정하지 않습니다.
할당된 값의 타입에 의해 동적으로 변수의 타입이 결정되며, 이를 동적 타이핑이라고 합니다.
// Number
var num1 = 1024;
var num2 = 10.50;
// String
var string1 = 'Hello';
var string2 = "JS";
// Boolean
var bool = true;
// null
var foo = null;
// undefined
var bar;
// Object
var obj = { name: 'Kim', gender: 'male' };
// Array
var array = [ 1, 2, 3 ];
// function
var foo = function() {};
연산자(Operator)
하나 이상의 표현식을 대상으로 산술, 할당, 비교, 논리, 타입 연산 등을 수행해 하나의 값을 만듭니다. (연산의 대상 : 피연산자)
// 산술 연산자
var area = 5 * 4; // 20
// 문자열 연결 연산자
var str = 'My name is ' + 'Lee'; // "My name is Lee"
// 할당 연산자
var color = 'red'; // "red"
// 비교 연산자
var foo = 3 > 5; // false
// 논리 연산자
var bar = (5 > 3) && (2 < 4); // true
// 타입 연산자
var type = typeof 'Hi'; // "string"
// 인스턴스 생성 연산자
var today = new Date(); // Sat Dec 01 2018 00:57:19 GMT+0900 (한국 표준시)
피연산자의 타입은 반드시 일치할 필요는 없으며, 이 때 암묵적 타입 강제 변환을 통해 연산을 수행합니다.
키워드(keyword)
수행할 동작을 규정한 것입니다.
예를 들어 var
키워드는 새로운 변수를 생성할 것을 지시합니다.
// 변수의 선언
var x = 5 + 6;
// 함수의 선언
function foo (arg) {
// 함수 종료 및 값의 반환
return ++arg;
}
var i = 0;
// 반복문
while (1) {
if (i > 5) {
// 반복문 탈출
break;
}
console.log(i);
i++;
}
주석(Comment)
작성된 코드의 의미를 설명하기 위해 사용하며, 무시되어 실행되지 않습니다.
한 줄 주석은 //
다음에 작성하며, 여러 줄 주석은 /*
과 */
의 사이에 작성합니다.
문(statement)
각각의 명령을 문이라고 하며 문이 실행되면 어떠한 동작이 일어나게 됩니다.
문은 리터럴, 연산자, 표현식, 키워드 등으로 구성되며 세미콜론 ;
으로 끝나야 합니다.
코드 블록 {...}
으로 그룹화할 수 있으며, 그룹화의 목적은 함께 실행되어져야 하는 문을 정의하기 위함입니다.
일반적으로 위 → 아래 순서로 실행 되며, 이런 순서는 조건문(if, switch)이나 반복문(while, for)의 사용으로 제어할 수 있으며 이를 흐름 제어라고 합니다.
또는 함수 호출로 변경될 수 있습니다.
다른 언어와 달리 함수 단위의 유효 범위(Function-level scope)만이 생성됩니다.
표현식(Expression)
하나의 값으로 평가 됩니다.
리터럴, 변수, 객체의 프로퍼티, 배열의 요소, 함수 호출, 메소드 호출, 피연산자와 연산자의 조합은 모두 표현식입니다.
문 vs 표현식 비교
문이 마침표로 끝나는 하나의 완전한 문장이면 표현식은 문을 구성하는 요소 입니다.
표현식은 그 자체로도 하나의 문이 될 수 있어 구별이 어려울 수 있습니다.
표현식을 통해 평가한 값을 통해 실제로 컴퓨터에게 명령을 하여 무언가를 하는 것은 문이라고 생각하면 됩니다.
// 선언문(Declaration statement)
var x = 5 * 10; // 표현식 x = 5 * 10를 포함하는 문이다.
// 할당문(Assignment statement)
x = 100; // 이 자체가 표현식이지만 완전한 문이기도 하다.
함수
어떤 작업을 수행하기 위해 문들의 집합을 정의한 코드 블록입니다.
이름과 매개변수를 갖고, 필요한 때에 호출하여 코드 블록에 담긴 문들을 일괄적으로 실행할 수 있습니다.
// 함수의 정의(함수 선언문)
function square(number) {
return number * number;
}
또한, 한 번만 호출하는 것이 아닌 여러 번 호출할 수 있습니다.
동일한 작업을 반복적으로 수행해야 하면 미리 정의된 함수를 재사용하는 것이 효율적입니다.
객체(object)
자바스크립트를 이루고 있는 거의 모든 것이 객체 입니다.
원시 타입(Primitives)을 제외한 나머지 값들(함수, 배열, 정규표현식 등)은 모두 객체입니다.
프로퍼티 값으로 함수를 사용할 수도 있으며 프로퍼티 값이 함수일 경우, 일반 함수와 구분하기 위해 메소드라고 부릅니다.
var person = {
name: 'Kim',
gender: 'male',
sayHello: function () {
console.log('Hi! My name is ' + this.name);
}
};
console.log(typeof person); // object
console.log(person); // { name: 'Kim', gender: 'male', sayHello: [Function: sayHello] }
person.sayHello(); // Hi! My name is Kim
객체는 데이터를 의미하는 프로퍼티(property)와 데이터를 참조하고 조작할 수 있는 동작(behavior)을 의미하는 메소드(method)로 구성된 집합 입니다.
객체지향의 상속을 구현하기 위해 프로토타입이라고 불리는 객체의 프로퍼티와 메소드를 상속받을 수 있으며, 타 언어와 구별되는 중요한 개념 입니다.
배열(array)
1개의 변수에 여러 개의 값을 순차적으로 저장할 때 사용합니다.
배열은 객체이며 유용한 내장 메소드를 포함하고 있습니다.
var arr = [1, 2, 3, 4, 5]
6. 데이터 타입과 변수(Data type & Variable)
변수는 앞서 말했듯이 메모리 주소에 접근하기 위해 사람이 이해할 수 있는 언어로 명명한 식별자 입니다.
이 메모리 값을 저장하기 위해서는 메모리의 크기인 byte
를 알아야 합니다.
값의 종류(데이터 타입)에 따라 확보해야 할 메모리의 크기가 다르기 때문입니다.
자바스크립트는 동적 타입으로 값이 할당되는 과정에서 자동으로 변수의 타입이 결정(타입 추론, Type Inference)됩니다.
var foo = 'string';
console.log(typeof foo); // string
foo = 1;
console.log(typeof foo); // number
자바스크립트에는 어떠한 데이터 타입이 있고, 변수는 어떻게 사용하는지 알아봅시다.
데이터 타입(Data Type)
프로그래밍 언어에서 사용할 수 있는 데이터(숫자, 문자열, 불리언 등)의 종류를 말합니다.
데이터를 메모리에 저장할 때 확보해야 하는 메모리 공간의 크기, 할당할 수 있는 유효한 값에 대한 정보, 그리고 메모리에 저장되어 있는 2진수 데이터를 어떻게 해석할 지에 대한 정보를 컴퓨터와 개발자에게 제공합니다.
자바스크립트에서 제공하는 7개의 데이터 타입은 크게 원시 타입(primitive data type)과 객체 타입(object/reference type)으로 구분할 수 있습니다.
원시 타입 (Primitive Data Type)
원시 타입의 값은 변경 불가능한 값이며, pass-by-value(값에 의한 전달)입니다.
number
숫자 타입의 값은 배정밀도 64비트 부동소수점 형에 따릅니다.
하나의 숫자 타입만 존재합니다.
모든 수를 실수로 처리하며 정수만을 표현하기 위한 특별한 데이터 타입 없습니다. → 정수로 표시 되어도 실수
특별한 값들도 표현 가능 합니다.
Infinity
: 양의 무한대 /-Infinity
: 음의 무한대 /NaN
: 산술 연산 불가
string
텍스트 데이터를 나타내는데 사용합니다.
문자열은 0개 이상의 16bit 유니코드 문자(UTF-16) 들의 집합으로 대부분의 전세계의 문자를 표현할 수 있습니다.
작은 따옴표 or 큰 따옴표 안에 넣어 생성하며, 일반적인 표기법은 작은 따옴표를 사용합니다.
원시 타입이기에 한 번 문자열이 생성되면 그 문자열을 변경할 수 없습니다.
문자열을 재할당 하는 것은 가능합니다. (기존 문자열 변경이 아니기 때문)
문자열은 배열처럼 인덱스를 통해 접근할 수 있습니다.
boolean
논리적 참, 거짓을 나타내는 true와 false 만 있습니다.
조건문에서 자주 사용되며 비어있는 문자열과
null
,undefined
, 숫자 0은false
로 간주됩니다.
undefined
해당 타입의 값은
undefined
가 유일합니다.선언은 되었지만 값을 할당하지 않은 변수에 접근하거나 존재하지 않는 객체 프로퍼티에 접근할 경우
undefined
가 반환됩니다.값이 없다는 것을 명시하고 싶은 경우
null
을 할당합니다.
null
해당 타입의 값은 null이 유일합니다.
자바스크립트는 대소문자를 구별(case-sensitive)하므로
null
은 Null, NULL등과 다릅니다.프로그래밍 언어에서
null
은 의도적으로 변수에 값이 없다는 것을 명시할 때 사용합니다. → 메모리 주소 참조 정보 제거(가비지 콜렉션 수행)함수가 호출됐으나 유효한 값을 반환할 수 없는 경우, 명시적으로
null
을 반환합니다.타입을 나타내는 문자열을 반환하는
typeof
연산자로null
값을 연산해 보면null
이 아닌object
가 나옵니다. ⇒ 자바스크립트의 설계상의 오류따라서 타입을 확인할 때
typeof
연산자를 사용하면 안되고 일치 연산자(===)를 사용해야 합니다.
symbol
ES6에서 새롭게 추가된 7번째 타입으로 변경 불가능한 원시 타입의 값입니다.
이름의 충돌 위험이 없는 유일한 객체의 프로퍼티 키(property key)를 만들기 위해 사용합니다.
이때 생성된 심볼 값은 다른 심볼 값들과 다른 유일한 심볼 값입니다.
// 심볼 key는 이름의 충돌 위험이 없는 유일한 객체의 프로퍼티 키
var key = Symbol('key');
console.log(typeof key); // symbol
var obj = {};
obj[key] = 'value';
console.log(obj[key]); // value
객체 타입 (Object type, Reference type)
객체는 이름과 값을 가지는 데이터를 의미하는 프로퍼티(property)와 동작을 의미하는 메소드(method)를 포함할 수 있는 독립적 주체입니다.
원시 타입을 제외한 나머지 값들 모두 객체이며, pass-by-reference(참조에 의한 전달) 방식으로 전달됩니다.
변수
변수는 var
, let
, const
키워드를 사용하여 선언하고 할당 연산자를 사용해 값을 할당 합니다.
또한, 식별자인 변수명을 사용해 변수에 저장된 값을 참조합니다.
선언
var PI = 3.141592653589793; // 상수
var radius = 2; // 변수
var circleArea = PI * radius * radius;
var cylinderHeight = 5;
var cylinderVolume = circleArea * cylinderHeight;
상수를 별도 지원하지 않으므로 변수 이름을 대문자로 하여 상수임을 암시할 수 있습니다.
이처럼 변수는 애플리케이션에서 한번 쓰고 버리는 값이 아닌 값이 아닌 일정 기간 유지할 필요가 있는 값에 사용합니다.
변수의 존재 목적을 쉽게 이해할 수 있도록 의미있는 변수명을 지정해야 하며, 다음과 같은 명명 규칙이 존재합니다.
반드시 영문자(특수문자 제외), underscore ( _ ), 또는 달러 기호($)로 시작하여야 합니다.
이어지는 문자에는 숫자(0~9)도 사용할 수 있습니다.
대/소문자를 구별하므로 사용할 수 있는 문자는 “A” ~ “Z” (대문자)와 “a” ~ “z” (소문자)입니다.
선언만 되어 있는 변수는 undefined
로 초기 값을 갖고 있어 선언하지 않은 변수에 접근하면 ReferenceError
가 발생합니다.
- 변수의 중복 선언
var
키워드로 선언한 변수는 중복 선언이 가능합니다.
var x = 1;
console.log(x); // 1
// 변수의 중복 선언
var x = 100;
console.log(x); // 100
동일한 변수명이 선언되어 있는 것을 모르고 변수를 중복 선언했다면 의도치 않게 변수의 값을 변경하게 되기 때문에 중복 선언은 사용하지 않는 것이 좋습니다.
- 동적 타이핑 (Dynamic Typing)
동적 타입(dynamic/weak type) 언어이기 때문에 같은 변수에 여러 타입의 값을 할당할 수 있습니다.
이를 동적 타이핑(Dynamic Typing)이라고 합니다.
- 변수 호이스팅(Variable Hoisting)
자바스크립트의 특징으로 모든 선언문은 호이스팅(Hoisting) 됩니다.
호이스팅이란 var
선언문이나 function
선언문 등 모든 선언문이 해당 Scope의 선두로 옮겨진 것처럼 동작하는 특성을 말합니다.
즉, 자바스크립트는 모든 선언문이 선언되기 이전에 참조 가능합니다.
변수는 3단계에 걸쳐 생성됩니다.
선언 단계(Declaration phase)
변수 객체(Variable Object)에 변수 등록
이 변수 객체는 스코프가 참조하는 대상이 됨
초기화 단계(Initialization phase)
변수 객체(Variable Object)에 등록된 변수를 메모리에 할당
해당 단계에서 변수는
undefined
로 초기화
할당 단계(Assignment phase)
undefined
로 초기화된 변수에 실제값 할당
var
키워드로 선언된 변수는 선언 단계와 초기화 단계가 한 번에 이루어집니다.
변수 선언문 이전에 변수에 접근해도 Variable Object에 변수가 존재하기 때문에 에러가 발생하지 않지 않고, undefined
를 반환합니다.
이런 현상을 변수 호이스팅이라고 합니다.
console.log(foo); // ① undefined
var foo = 123;
console.log(foo); // ② 123
{
var foo = 456;
}
console.log(foo); // ③ 456
①이 실행되기 이전에 var foo = 123;
이 호이스팅 되어 ①구문 앞에 var foo;
가 옮겨지게 됩니다. (undefined
로 초기화)
②에서는 변수에 값이 할당 되었기 때문에 123이 출력됩니다.
자바스크립트는 타 언어와 달리 블록 레벨 스코프(block-level scope)를 가지지 않고 함수 레벨 스코프(function-level scope)를 갖습니다.
ECMAScript 6에서 도입된 let
, const
키워드를 사용하면 블록 레벨 스코프를 사용할 수 있습니다. (자세한 내용은 추후 다룰 예정)
함수 레벨 스코프(Function-level scope)
함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 X
즉, 함수 내부에서 선언한 변수는 지역 변수이며 함수 외부에서 선언한 변수는 모두 전역 변수임
블록 레벨 스코프(Block-level scope)
코드 블록 내에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 X
코드 블록 내의 변수 foo는 전역 변수이므로 전역에 선언된 변수 foo에 할당된 값을 재할당하기 때문에 ③의 결과는 456이 됩니다.
var
키워드로 선언된 변수의 문제점
- 함수 레벨 스코프(Function-level scope) → 전역 변수의 남발,
for loop
초기화식에서 사용한 변수를for loop
외부 또는 전역에서 참조할 수 O var
키워드 생략 허용 → 의도하지 않은 변수의 전역화- 중복 선언 허용 → 의도하지 않은 변수 값 변경
- 변수 호이스팅 → 변수를 선언하기 전에 참조 가능
전역 변수는 유효 범위(scope)가 넓어서 어디에서 어떻게 사용될 지 파악하기 힘들기 때문에 이러한 var
의 단점을 보완하기 위해 let
, const
키워드가 나오게 되었습니다.
여기까지 JavaScript lesson 5, 6에 해당되는 자바스크립트의 기본 문법, 데이터 타입과 변수에 대해 알아보았습니다.