본문 바로가기

프로그래밍/js

lessons 6. 데이터 타입과 변수

2023.02.01

자바스크립트 스터디 2회차

공부 사이트: https://poiemaweb.com/

 

6. 데이터 타입과 변수

1) 프로그래밍

- 변수 통해 값을 저장

- 연산자로 값을 연산, 평가

- 조건문과 반복문의 흐름제어 통해 데이터 흐름 제어

- 재사용할 구문은 함수 통해 집합 만들기

- 객체, 배열 등으로 자료를 구조화

 

변수 선언 > 할당

 

메모리에 값을 저장하기 위해서는 확보할 메모리의 크기를 알아야 함.

값의 종류에 따라 메모리 크기가 다르기 때문이다.

  • 1Byte로 표현할 수 있는 값의 총 개수는 256개(2^8)
  • 4Byte로 표현할 수 있는 값의 총 개수는 4,294,967,296개(2^32).
    -2,147,483,648 ~ 2,147,483,647의 정수 표현 가능

그러나 자바스크립트는 동적 타입 언어임.

변수의 타입 지정 없이, 값이 할당되는 과정에서 자동으로 변수의 타입이 결정된다.

▶ 타입 추론(Type Inference)

 

같은 변수에 여러 타입의 값을 자유롭게 할당 가능함.

var t1 = 'Hello';
console.log(t1);     //type=String
t1 = 23;
console.log(t1);     //type=number



// C언어의 경우, int형 변수 선언 시 4Byte 메모리 영역을 확보.
// int형 변수에 값을 할당할 때는 계속 int형 값을 할당해야 함.
int num = 123;
num = "String" //불가능

 

 

2) 데이터 타입

원시 타입 number string boolean
null undefined symbol (New in ECAScript 6)
객체 타입 object

데이터 타입은 한장된 메모리 공간을 효율적으로 사용하기 위해,

2진수 데이터로 메모리에 저장된 데이터를 다양한 형태로 사용하기 위해 존재함.

 

#원시 타입 :변경 불가능한 값. pass-by-value(값에 의한 전달)

#객체 타입: pass-by-reference(참조에 의한 전달) 방식으로 전달

 

 

3) 데이터 타입 - 원시 타입

변경 불가능한 값의 의미는 다음과 같다.

var str = 'test';
str = 'Hello Javascript";

위와 같은 구문 실행 시, str 내 'test'가 수정되는 것이 아니라 새로운 문자열 'Hello Javascript"를 메모리에 생성하고, 식별자 str가 그것을 가리킨다. 즉, 메모리 내에는 'test'와 'Hello Javascript' 가 모두 존재함. 식별자가 가리키는 대상이 변경되었을 뿐이다.

 

 

number

  • 자바스크립트는 하나의 숫자 타입만 존재. 정수, 실수, 음의 정수, 2진수, 8진수, 16진수...
  • 0x41, 0o101, 0b01000001은 모두 같은 값. (값 참조 시 모두 10진수로 해석)
  • 모든 수를 실수로 처리하기에, 정수로 표시되는 수 끼리 연산 시 실수가 나올 수 있음.
  • 양의 무한대(Infinity), 음의 무한대(-Infinity), 산술 연산 불가(NaN) 값 표현 가능

var pInf = 10 / 0;  // 양의 무한대
console.log('pInt: '+ pInf);  

var nInf = 10 / -0; // 음의 무한대
console.log('nInf: '+ nInf);  

var nan = 1 * 'string'; // 산술 연산 불가
console.log('nan: ' + nan);

결과

 

② String

  • 문자열은 작은 따옴표 또는 큰 따옴표 안에 텍스트 넣어 생성. 백틱도 가능 (ES6)
  • 배열처럼 인덱스 통해 접근 가능. ==> 유사 배열
  • 이미 생성된 문자열의 일부 문자를 변경해도 반영되지 않음. 한번 생성된 문자열은 read only
  • 물론, 새로운 문자열을 재할당하는 것은 가능하다.
var str = "Hello Javascript";
for(var i=0;i<str.length;i++){
     console.log(str[i]);
}

str[0] = 'V';
console.log(str);

결과.

// 문자열 재할당
var str = "Hello Javascript";
console.log(str);
str = 'TEST';
console.log(str);
str = 'BOMB!!';
console.log(str);

 

③ Boolean

  • 참과 거짓으로 구분되는 조건에 의해 프로그램의 흐름을 제어.
  • 비어 있는 문자열, null, undefined, 숫자 0 은 false로 간주됨.

 

④ undefined

  • 선언 이후 값을 할당하지 않은 변수
  • 존재하지 않는 객체 프로퍼티
  • 자바스크립트에 의해 초기화된 값.
  • 개발자가 변수의 값이 없다는 것을 명시하고 싶은 경우, null을 할당하는 것을 권장함.

 

⑤ null

  • 자바스크립트는 대소문자를 구별하므로, null이라고 확실히 명시해줄 것. Null, NULL과 다름.
  • 의도적으로 변수에 값이 없음을 명시할 때 사용.
  • null 할당 시 변수가 기억하는 메모리 어드레스의 참조 정보를 제거함. 가비지 컬렉션을 수행하는 것.
  • 함수가 호출되었으나 유효한 값을 반환할 수 없는 경우에도 null 반환
  • ★ null 타입을 확인할 때 typeof 연산자 사용하지 말고 일치 연산자(===)를 사용해야 함. typeof 사용 시 객체로 나온다(설계상 오류라고 함)

null

 

[TIP] 가비지 콜렉션

더 이상 쓸모 없어진 값을 자바스크립트 엔진이 처리.

가비지 컬렉터가 계속 동작하며 모든 객체를 모니터링, 도달할 수 없는 객체는 삭제함.

 

⑥ symbol

  • 심볼: 이름의 충돌 위험이 없는 유일한 객체 프로퍼티 키를 만들기 위해 사용.
  • Symbol() 함수 호출해서 생성 (유일한 심볼 값)
var key = Symbol('myKey');
console.log('type: ' + typeof key);

var obj = {};
obj[key] = 'value';
console.log('obj[key]: ' + obj[key]);

 

 

 

2) 변수

변수에 명시한 고유한 식별자를 변수명, 변수로 참조할 수 있는 데이터를 변수 값이라 함.

ⓐvar, let, const 키워드를 사용하여 변수를 선언하고, ⓑ할당 연산자를 사용해 값을 할당. ⓒ식별자인 변수명을 사용해서 변수에 저장된 값을 참조함.

var test; //선언
test = 1; //값 할당
test = 2; //값 재할당
test; //변수 참조

// 변수의 선언과 할당
var test2 = (123+12) / 2;

 

[변수명(식별자) 명명 규칙]

  • 반드시 영문자, underscore(_), 달러 기호($)로 시작해야 함. 이어지는 문자에는 숫자 사용 가능
  • 자바스크립트는 대/소문자를 구분하므로, 사용할 수 있는 문자는 A-Z, a-z

변수 중복 선언 가능, 동적 타이핑 가능(같은 변수에 여러 타입 값 할당)

 

 

4) 변수 - 변수 호이스팅

호이스팅(Hoistring)

- var 선언문이나 function 선언문 등 모든 선언문이 해당 Scope의 선두로 옮겨진 것처럼 동작하는 특성.

- 모든 선언문이 선언되기 이전에 참조 가능함

console.log(t1);
var t1 = 123;
console.log(t1);
{
     var t1 = 456;
}
console.log(t1);

첫 줄의 t1은 아직 선언되지도 않았는데 undefined가 뜸. 이게 호이스팅 때문.

원래 선언되지 않은 변수 호출 시 "{변수} is not defined" 가 떠야 한다.

 

[호이스팅 과정]

① 선언 단계(Declearation phase): 변수 객체에 변수 등록. 해당 객체는 스코프가 참조하는 대상이 됨.

② 초기화 단계(Initialization phase): 변수 객체에 등록된 변수 메모리에 할당. 변수는 undefined로 초기화됨.

③ 할당 단계(Assignment phase): undefined로 초기화된 변수에 실제 값 할당.

 

var t1 = 123;

var 키워드로 선언된 변수는 선언 단계, 초기화 단계가 한번에 이루어짐.

(스코프에 변수 등록 - 메모리에 공간확보 후 undefined로 초기화)

따라서 변수 선언문 이전에 변수에 접근해도. 변수 객체에 변수가 존재하기 때문에 에러는 발생하지 않음.

이러한 현상을 변수 호이스팅(Variable Hoisting)이라 한다.

 

그리고 변수 할당문에 도달하면 비로소 할당 단계가 이루어진다.

 

{
     var t1 = 456;
}
console.log(t1);

자바스크립트의 변수는 함수 레벨 스코프를 갖는다. 위 코드의 t1은 블록 내의 변수이므로, 전역에 선언된 t1(=123)을 재할당한다. 출력되는 값은 456.


[TIP]

함수 레벨 스코프(Function-level scope)

함수 내에서 선언된 변수는 함수 내에서만 유효. 함수 외부에서는 참조 불가능함. (지역변수와 전역변수 구분)

ES6부터 let, const 키워드를 통해 블록 레벨 스코프를 사용할 수 있음.

 

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

코드 블록{} 내에서 선언된 변수는 코드 블록 내에서만 유효. 코드 블록 외부에서는 참조할 수 없음.


 

5) var 키워드로 선언된 변수의 문제점

ES5에서 변수를 선언할 수 있는 유일한 방법은 var 키워드를 사용하는 것. 다음과 같은 특징을 갖는다.

① 함수 레벨 스코프

  • 전역 변수의 남발
  • for loop 식에서 사용한 변수를 for loop 외부/전역에서 참조할 수 있음

② 중복 선언 허용

  • 의도치 않은 변수값 변경

③ var 키워드 생략 허용

  • 의도치 않은 변수의 전역화

④ 변수 호이스팅

  • 변수 선언 전에 참조가 가능

전역 변수는 불가피한 상황을 제외하고 사용을 억제해야 한다. 유효 범위(scope)가 넓어서 어디에서 사용될 지 파악하기 힘들기 때문이다. 변수의 유효 범위는 좁을수록 좋다.

그렇기에 ES6에서 let과 const 키워드를 도입.