JS 정리(1) - 기본편

1. Basic Data Types(기본 데이터 타입)

// String : Text data를 나타낸다
let st = ‘hello world’
console.log(st) // hello world
// Number : 정수 or 부동 소수점 숫자를 말한다
3, 3.123, 2e-2
// Boolean : 두 값 중 하나가 True or False를 나타낸다
let a = true;
let b = false;
true or false
// Undefined : 변수가 초기화되지 않은 데이터 유형을 말한다
// (데이터 유형이 할당되지 않은 값을 말함, 변수가 선언되었지만, 값이 지정되지 않는 것을 말한다)
let a;
// Null : null 값을 나타낸다(비어 있거나 알 수 없는 값을 말한다)
let a = null;
// Symbol : 인스턴스가 고유하고 변경할 수 없는 데이터 유형을 말한다
let value = Symbol(’apple’);// Symbol : 인스턴스가 고유하고 변경할 수 없는 데이터 유형을 말한다
let value = Symbol(’apple’);// Symbol : 인스턴스가 고유하고 변경할 수 없는 데이터 유형을 말한다
let value = Symbol(’apple’);
// Object : 데이터 수집의 키 - 값 쌍을 나타낸다
let student = { };

2. Variables(변수)

// Variable : 변수라고 불리며, 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 
// or 그 메모리 공간을 식별하기 위해 붙인 이름이라고 생각하면 된다
/*
			 Identifier                              Memory
		myNum(variable)      ->   Address(0012CCGWH80) / Value(23)
*/
/*
	1. JS는 개발자가 직접 메모리를 제어하지 못한다. 그래서 개발자가 직접 메모리 주소를 통해 값을 
	저장하고 참조할 필요가 없고 변수를 통해 안전하게 값에 접근이 가능하다.
	2. 변수명인 myNum은 변수의 값이 아닌 메모리 주소를 기억하고 있다. 변수명을 사용하면, JS 엔진이
	변수명과 매핑된 메모리 주소를 통해 거기에 저장된 값(23)을 반환해 준다.
	3. 변수에 값을 저장하는 것을 할당(Assignment, 즉 대입, 저장이라 말한다)이라 하며 변수에 저장된
	값을 읽어 들이는 것을 참조(Reference)라 한다. 그리고 변수명을 JS 엔진에 알리는 것을 
	선언(Declaration)이라 한다.
*/
// 변수 선언[Var, Let, Const]
/*
	변수 선언은 var, let, const 키워드로 할 수 있으며, ES6에서 const와 let이 추가되었으며,
	JS에서 변수 선언은 선언 -> 초기화 단계를 거쳐 수행된다.
*/
// 선언 단계 : 변수명을 등록하여 JS 엔진에 변수의 존재를 알리는 것을 말한다
// 초기화 단계 : 값을 저장하기 위한 메모리 공간을 확보하고 암묵적으로 undefined를 할당해 초기화 한다
var a;
console.log(a); // output : undefined
/*
	Hoistion(호이스팅) 
		1. 변수 선언을 포함한 모든 선언문을 찾아내 먼저 실행하는 것을 말한다
		2. var, let, const, function, class 키워드를 사용해 선언한 모든 식별자는 호이스팅이 된다
*/
console.log(b); // undefined
let b;
/*
	변수 할당
		1. 변수에 값을 할당 할 때에는 할당 연사자(=)를 사용한다
		2. 변수 선언과 할당은 하나의 문(Statement)으로 단축 표현할 수 있지만, 두 개의 실행 시점이
		다르며, 변수 선언이 호이스팅되어 런타임 이전에 실행되지만, 값의 소스코드가 순차적으로
		실행되는 런타임에 실행된다
		3. 변수의 할당과 console을 실행하는 위치에 따라 반환되는 값이 다르다
*/
console.log(c); // undefined
var c = 'hello'; // 변수 할당
console.log(c); // value = hello
// 변수에 새로운 값을 재할당 할 수 도 있다
console.log(c); // hello
c = 'world';    // 재할당 c(hello) = world -> hello에서 world로 재할당 하겠다는 의미이다
console.log(c); // vaule = world
/* 
	재할당은 변수에 저장된 값을 다른 값으로 변경하는 것이기에 변경할 수 없는 값이라면 변수가 
	아니라 상수(constant)라 부른다
*/

// 함수 호이스팅

// 1. 함수 선언문(함수 이름 생략 불가능하다)
function add(x, y) {
	return x + y;
};

// 2. 함수 표현식(함수 이름 생략 가능하다)
var add = function(x, y) {
	return x + y;
};

// 3. Function 생성자 함수
var add = new Function('x', 'y', 'return x + y');

// 4. 화잘표 함수
var add = (x, y) => x + y;

/* 
  함수 선언문의 경우, 런타임 이전에 JS 엔진에서 먼저 실행되어, 함수 자체를 호이스팅 시킬 수
	있으며 함수 표현식은 위에서 봤던 변수 호이스팅과 같이 런타임 이전에 해당 값을 undefined로 
	초기화만 시키고, 런타임에서 해당 함수 표현식이 할당되어 그때 객체가 된다
*/

/*
	스코프(Scope)
		1. 식별자의 유효범위를 뜻하며, 선언된 변수는 전역 스코프를 지역에 선언된 변수는 지역 스코프를
		갖는다
		2. 전역 변수 : 어디에서든지 참조가 가능한 값을 말한다
		3. 지역 변수 : 함수 몸체 내부를 말한다
			-> 지역변수는 자신의 지역 스코프와 그 하위 지역 스코프에서 유효하다
			-> [주의] : 모든 코드 블록 if,for,while,try/catch등이 지역 스코프를 만들며, 
					블록 레벨 스코프라 하며, var 키워드로 선언된 변수는 오로지 함수의 코드 블록만을 지역
					스코프로 인정하는데, 이를 함수 레벨 스코프라 한다. 지역 스코프(var)로 변수를 재할당 
					하기 보다 let, const로 블록 레벨 스코프를 지원하는 변수를 사용하는 것을 권장한다
*/
// var, let, const의 차이

/*
	Var
		[문제점]
		1. 변수중복 선언 가능하여, 예기치 못한 값을 반환할 수 있다
		2. 함수 레벨 스코프로 인해 함수 외부에서 선언한 변수는 모두 전역 변수로 된다
		3. 변수 선언문 이전에 변수를 참조하면 언제나 undefined를 반환한다
*/

// let : 변수 중복 선언이 불가하지만, 재할당은 가능하다
let nm = 'kim';
console.log(nm); // kim
let nm = 'ji';
nm = 'ji'
console.log(nm); // ji

// const : 반드시 선언과 초기화를 동시에 진행되어야 한다
const nm; // Uncaught SyntaxError : Missing initialiazer in const declaration
const nm = 'kim'; // kim
/*
	let과 마찬가지로 재선언이 불가하며, 재할당도 불가하다. 재할당의 경우, 원시 값은 불가능
	하지만, 객체는 가능하다. const 키워드는 재할당을 금지할뿐, '불변'을 의미하지 않는다
*/ 
// 원시값 -> 재할당
const nm = 'kim';
nm = 'ji'; // Uncaught TypeError : Assignment to constant variable

// 객체 -> 재할당
const nm = {
	en : 'kim',
};
nm.en = 'ji';
console.log(nm); // ji
// 블록 레벨 스코프

let d = 1;

if (true) {
	let d = 4;
};

console.log(d); // 1

/*
	let을 선언한 경우 if문 안에 있는 것은 지역 스코프를 가져 전역에서 console을 찍었을 경우,
	전역에 있는 d가 결과 값으로 출력됨을 알 수 있다.(const도 동일하다)
*/

// 변수 호이스팅

/* 
	let : 선언 단계와 초기화 단계가 분리되어 진행되며, 런타임 이전에 JS 엔진에 의해 선언단계가
				먼저 실행되지만, 초기화 단계가 실행되지 않았을 때 해당 변수에 접근하려고 하면 참조 
				에러가 뜬다
*/
console.log(nm); // Uncaught ReferenceError: name is not defined
let nm = 'kim'; 

/*
	const : 선언 단계와 초기화 단계가 동시에 진행되며, 초기화가 진행되지 않으면 Cannot access
					'nm' before initialization 에러 문구가 뜬다
*/
console.log(nm); // Uncaught ReferenceError: Cannot access 'name' before initialization
const nm = 'kim';
// Boolean