728x90
728x90

 

스터디 발표 정리 (1) - 코어자바스크립트 01.데이터타입

 

01 데이터타입의 종류

기본형 / 참조형 데이터타입의 차이는 기본형은 할당이나 연산 시 복제되고 참조형은 참조되는 것
그리고 기본형은 불변성을 띈다는 것인데 이를 이해하려면 메모리와 데이터에 대한 지식이 필요하고
식별자, 변수의 개념을 구분할 수 있어야 하므로 다음으로 넘어갑니다

기본형은 값이 담긴 주소값을 바로 복제하는 반면
참조형은 값이 담긴 주소값들로 이루어진 묶음을 가리키는 주소값을 복제합니다

 

기본형 

number, string, boolean, null, undefined, symbol

참조형

array, function, date, regexp, map, weakmap, set, weakset

 

 

02 데이터타입에 관한 배경지식

컴퓨터는 모든 데이터를 0과 1로 바꿔 기억하는데, 이 하나의 메모리 조각을 비트라고 합니다
메모리는 많은 비트들로 구성되며 각 비트는 고유한 식별자를 통해 위치를 확인합니다

비트의 묶음 단위로 묶으면 효율적이며 표현할 수 있는 데이터의 개수도 늘어나나 낭비도 발생합니다
잘 안사용하는 데이터표현을 위한 빈공간보다는 표현 가능한 개수에 제약이 있어도 자주 사용하는 맞춤형 공간 구획이 나으므로
바이트 단위가 생성되었습니다

비트의 묶음 단위 바이트는 8개의 비트로 구성됩니다 **
1비트마다 0 1 두가지값 표현이 가능하므로 1바이트는 2의 8승값은 256개의 값 표현이 가능합니다
2바이트는 16개 비트이며 2의 16승 즉 65536개의 값 표현이 가능합니다

C C++ Java 등 정적타입 언어는 메모리낭비의 최소화를 위해 데이터타입별 할당할 메모리 영역을
2바이트, 4바이트 등으로 나누어 정해놓습니다 
예를 들어 2바이트 크기의 정수형 타입 short는 0을 포함한 -32768~32768 (2의 16승 65536 을 반으로 쪼개보면) 숫자만 허용합니다

이 구간 외의 숫자를 입력하면 오류가 되거나 잘못된 값이 저장됩니다
구간 외의 숫자를 입력하고자 할 경우 직접 4바이트 크기의 정수형 타입 int 등으로 형변환해야했었습니다 (과거에만)

자바스크립트 언어는 메모리용량이 월등히 커진 컴퓨터에서 사용가능하고 상대적으로 메모리 관리에 대한 압박에서 자유롭습니다
그래서 메모리 공간을 좀 더 넉넉하게 할당하여 숫자의 경우 정수형, 부동소수형 등을 구분안하고 64비트 (8바이트)를 확보합니다 **

각 비트는 고유한 식별자를 지니고 바이트 역시 시작하는 비트의 식별자로 위치 파악이 가능합니다
모든 데이터는 바이트 단위의 식별자, 메모리 주소값을 통해 서로 구분하고 연결할 수 있습니다

 

 

변수와 식별자 정확한 차이는

변수와 식별자를 혼용하는 경우가 많습니다
이유는 대부분 문맥에 따라 유추 가능하기 때문이지만 차이는 잘 짚어 둬야 혼돈이 덜하겠습니다

변수는 변할 수 있는 수로
수학 용어에서 차용하여 수가 붙게 되었는데 값은 수 외에 다른 것도 가능합니다
영어로는 variable 인데 변할 수 있는 이라는 형용사이지만 컴퓨터 용어에서는 변할 수 있는 어떤 것 인 명사로 확장되었습니다
어떤 것은 데이터입니다. 숫자, 문자열, 객체, 배열 등등입니다

식별자는 어떤 데이터를 식별하는데 사용하는 이름, 즉 변수명입니다.

 

[다른분들 정리를 참고하여 추가]

=> 기본형 데이터는 원본이 항상 있고, 데이터의 위치를 가리키는 변수값(메모리주소)는 변한다


var, const, let의 차이

변수 선언 방식 문법 변수 재선언 여부 변수 재할당 여부 변수의 유효범위
var ES5 재선언 가능 재할당 가능 function scope
const ES6(ECMAScript6) 불가 불가 block scope
let ES6(ECMAScript6) 불가 재할당 가능 block scope

 

// var
var name = "Marcus";
console.log(name);

var name = "Jogeonsang";
console.log(name);

output: Marcus
output: Jogeonsang

// let
let testCase = 'let' // output: let
let testCase = 'let2' // output: Uncaught SyntaxError: Identifier 'testCase' has already been declared
testCase = 'let3' // output: let3

// const
const testCase = 'const' // output: const
const testCase = 'const2' // output: Uncaught SyntaxError: Identifier 'testCase' has already been declared
testCase = 'const3' // output: Uncaught TypeError:Assignment to constant variable.

// 출처 : https://velog.io/@marcus/2019-02-10-1702-%EC%9E%91%EC%84%B1%EB%90%A8
// var
var foo = "This is String.";
if(typeof foo === 'string'){
    var result = true;
} else {
  var result = false;
}

console.log(result);    // var가 hoisting이 되기 때문에 result : true 

// let, const
var foo = "This is String.";
if(typeof foo === 'string'){
    const result = true;
} else {
  const result = false;
}

console.log(result);    // 에러 발생. result : result is not defined

// 출처 : https://velog.io/@marcus/2019-02-10-1702-%EC%9E%91%EC%84%B1%EB%90%A8

 

 

* 자바스크립트 호이스팅 

모든 변수 선언은 호이스트(변수의 정의가 범위에 따라 선언, 초기화, 할당 분리) 된다.
즉 변수가 함수 내에서 정의되었을 경우 선언이 함수의 최상위로, 
함수 밖에서 정의되었을 경우 전역 컨텍스트의 최상위로 변경된다.

 

 

* scope (유효범위)

스코프는 참조 대상 식별자(identifier, 변수, 함수의 이름과 같이 어떤 대상을 다른 대상과 구분하여 식별할 수 있는 유일한 이름)를 찾아내기 위한 규칙이다. (https://poiemaweb.com/js-scope)

변수는 전역 또는 코드 블록(if, for, while, try/catch 등)이나 함수 내에 선언하며 코드 블록이나 함수는 중첩될 수 있다.
식별자는 자신이 어디에서 선언됐는지에 의해 자신이 유효한(다른 코드가 자신을 참조할 수 있는) 범위를 갖는다.
스코프는 같은 식별자 이름의 충돌을 방지한다. 스코프가 없다면 같은 식별자 이름은 충돌을 일으키므로 프로그램 전체에서 하나밖에 사용할 수 없다. 디렉터리가 없는 컴퓨터를 생각해보자. 디렉터리가 없다면 같은 이름을 갖는 파일을 하나밖에 만들 수 없다. 

변수는 선언 위치(전역 또는 지역)에 따라 전역 스코프와 지역 스코프로 나눠 가진다.

 

전역 스코프(Global scope) 

전역에 변수를 선언하면 이 변수는 어디서든지 참조할 수 있는 전역 스코프를 갖는 전역 변수가 된다. var 키워드로 선언한 전역 변수 전역 객체(Global Object) window의 프로퍼티이다.
전역 변수의 사용에서 주의할 점은 변수 이름이 중복될 수 있고, 의도치 않은 재할당에 의한 상태 변화로 코드를 예측하기 어렵게 만드므로 사용할 때 잘 고려해야 한다.

 

var global = 'global';

function foo() {
  var local = 'local';
  console.log(global);
  console.log(local);
}
foo();

console.log(global);
console.log(local); // Uncaught ReferenceError: local is not defined

// https://poiemaweb.com/js-scope

 

 

지역 스코프, 함수레벨 스코프 (Local scope or Function-level scope)

자바스크립트는 함수 레벨 스코프를 사용한다. 즉, 함수 내에서 선언된 매개변수와 변수는 함수 외부에서는 유효하지 않다. 따라서 변수 b는 지역 변수이다.

 

var a = 10;     // 전역변수

(function () {
  var b = 20;   // 지역변수
})();

console.log(a); // 10
console.log(b); // "b" is not defined

// https://poiemaweb.com/js-scope

 

전역 영역에서는 전역변수만이 참조 가능하고 함수 내 지역 영역에서는 전역과 지역 변수 모두 참조 가능하나 변수명이 중복된 경우, 지역변수를 우선하여 참조한다.

 

var x = 'global';

function foo() {
  var x = 'local';
  console.log(x);
}

foo();          // local
console.log(x); // global

 

 

 

비블록 레벨 스코프 (Non block-level scope)

if (true) {
  var x = 5;
}
console.log(x);

// https://poiemaweb.com/js-scope

 

변수 x는 코드 블록 내에서 선언되었다. 하지만 자바스크립트는 블록 레벨 스코프를 사용하지 않으므로 함수 밖에서 선언된 변수는 코드 블록 내에서 선언되었다할지라도 모두 전역 스코프을 갖게된다. 따라서 변수 x는 전역 변수이다.

 

 

다른 언어와 다른 자바스크립트 스코프의 특징

대부분의 타 언어는 코드블록 내에서 유효한 블록 레벨 스코프를 따른다. 
예를 들어 if문이 있다면 if문 코드 블록 내에서 참조, 접근 가능한 스코프를 따른다.
그러나 자스는 함수레벨스코프를 따라, 함수코드블록 내에서 유효하고 함수 외부에서는 그렇지 않다.

ES6 let 을 사용하면 블록레벨스코프를 사용 가능하다.

 

var x = 0;
{
  var x = 1;
  console.log(x); // 1
}
console.log(x);   // 1

let y = 0;
{
  let y = 1;
  console.log(y); // 1
}
console.log(y);   // 0

// https://poiemaweb.com/js-scope

 

 


변수와 리터럴의 차이

리터럴 : 리터럴은 변수의 값이 변하지 않는 데이터(메모리 위치안의 값)를 의미한다. 보통은 기본형의 데이터를 의미하지만, 특정 객체(Immutable class , VO class)에 한에서는 리터럴이 될 수 있다. (https://mommoo.tistory.com/14 [개발자로 홀로 서기])

 

 

 

03 변수 선언과 데이터 할당

 

 

 

04 기본형 데이터와 참조형 데이터

 

 

 

05 불변 객체 (immutable object)

 
참조형 데이터의 가변성은 데이터 자체가 아닌 내부 프로퍼티를 변경할 때만 성립하며
새로운 데이터를 메모리에 할당
하고자 하면 기본형 데이터처럼 불변함

내부 프로퍼티를 변경할 때마다 매번 새로운 객체를 만들어 재할당해주는 대신 자동으로 새로운 객체를 만들어주는 도구를 사용할 수 있음 
==> immutable.js, immer.js, immutability-helper 등의 라이브러리나 ES6의 spread operator, Object.assign 메서드 등

* 불변 객체가 필요한 상황 : 값으로 전달받은 객체에 변경을 가해도 원본 객체는 보존되어야 하는 경우

더보기
  • 여기서부터 볼 것
  • 얕은 복사 : 딱 한 단계 밑의 프로퍼티 값까지만 복사됨
    깊은 복사 : 프로퍼티 값 속의 프로퍼티 값까지 재귀적으로 복사됨.

 

 

06 undefined, null

 

더보기
  • 기본형 데이터 타입에 속하므로, 그 자체로 타입인 동시에 ‘값’에 해당

  • undefined

    • 사용자가 리터럴로 undefined 할당하는 경우 -> ‘값’

      • 참조형 데이터의 요소나 프로퍼티 값으로 할당했을 경우, 배열 메서드가 이를 ‘존재하는 값’으로 보고 순회함

    • 엔진이 런타임에 ‘반환’하는 경우가 있다. -> ‘상태’에 가깝다

      • 값을 할당하지 않은 변수에 접근할 경우

      • 존재하지 않는 객체 프로퍼티에 접근할 경우

      • return문이 없거나 호출되지 않는 함수의 실행 결과

  • null

    • 개발자가 직접 null을 변수에 할당했을 때

    • ‘아무것도 없음’이라는 값을 할당한 것임. 

    • undefined를 직접 할당하는 대신 null을 할당하면 됨.

 

728x90
728x90
블로그 이미지

coding-restaurant

코딩 맛집에 방문해주셔서 감사합니다.

,

v