[항해 99] 프로그래밍 기초 - Node.js 과제

박선우·2022년 5월 17일
0

항해99

목록 보기
1/1
post-thumbnail

1. JavaScript의 자료형과 JavaScript만의 특성

느슨한 타입(loosely typed)의 동적(dynamic) 언어

  • 동적 타입
    JavaScript는 느슨한 타입(loosely typed)의 동적(dynamic) 언어입니다. JavaScript의 변수는 어떤 특정 타입과 연결되지 않으며, 모든 타입의 값으로 할당 (및 재할당) 가능합니다.
let foo = 42 // foo가 숫자
foo = 'bar' // foo가 이제 문자열
foo = true // foo가 이제 불리언

JavaScript의 타입

  • 원시값 : 객체를 제외한 모든 타입은 불변 값(변경할 수 없는 값)을 정의합니다. 예를 들어 (C 언어와는 달리) 문자열은 불변합니다. 이런 일련의 타입을 "원시 값"이라고 합니다.

  • Boolean 타입
    Boolean 타입은 논리 요소를 나타내며 true와 false 두 가지의 값을 가질 수 있습니다.

  • Null 타입
    Null 타입은 null 하나의 값만 가질 수 있습니다.

  • Undefined 타입
    값을 할당하지 않은 변수는 undefined 값을 가집니다.

  • Number 타입
    ECMAScript는 Number와 BigInt 두 가지의 내장 숫자 타입을 가지고 있습니다. 부동소수점 숫자 외에도 +Infinity, -Infinity, NaN("Not a Number") 세 개의 상징적인 값을 가집니다.

  • BigInt 타입
    BigInt 타입은 임의 정밀도로 정수를 나타낼 수 있는 JavaScript 숫자 원시 값입니다. BigInt를 Number의 안전 한계를 넘어서는 큰 정수도 안전하게 저장하고 연산할 수 있습니다.
    BigInt는 정수 끝에 n을 추가하거나 생성자를 호출해 생성할 수 있습니다.

  • String 타입
    JavaScript의 String 타입은 텍스트 데이터를 나타낼 때 사용합니다. String은 16비트 부호 없는 정수 값 "요소"로 구성된 집합으로, 각각의 요소가 String의 한 자리를 차지합니다. 첫 번째 요소는 인덱스 0에, 그 다음 요소는 인덱스 1, 그 다음은 2, ...입니다. String의 길이는 그 안의 요소 수와 같습니다.
    C 언어와 같은 일부 프로그래밍 언어와 달리 JavaScript 문자열은 불변합니다. 즉 문자열을 생성한 후 바꾸는 것은 불가능합니다.
    그러나 원본 문자열을 사용해 새로운 문자열을 생성하는 것은 가능합니다.

  • Symbol 타입
    Symbol은 고유하고 변경 불가능한 원시 값이며 객체의 속성(아래를 참고하세요) 키로 사용할 수 있습니다. 어떤 프로그래밍 언어들에선 "아톰"이라고 부르기도 합니다.

JavaScript 형변환(Type Casting)
자바스크립트는 타입이 매우 유연한 언어이다. 때문에 자바스크립트 엔진이 필요에 따라 암시적변환을 혹은 개발자의 의도에 따라 명시적변환을 실행한다.

  • 암시적 형 변환(Implicit type conversion)
    형변환은 각기 다른 타입의 값들을 !!, ==, +, -, && .. 등의 비교, 산술, 문자열, 논리 연산자로 연산 시 발생한다.
    연산 불가한 값이라고 에러를 뿜는 대신 강제 변환을 시키더라도 js 내에서 연산 가능한 값으로 변환 후 결과를 반환하려 하기 때문이다.
    이때 초기 데이터 타입과 관계없이 강제 형변환을 통해 3개의 원시 타입 boolean, number, string 중 하나로 변경된다.
let num = 10
console.log(num, typeof num) // 10 "number"

num = num.toString()
console.log(num, typeof num) // 10 "string"

num = parseInt(num)
console.log(num, typeof num) // 10 "number"
  • 명시적 형 변환
    개발자가 의도적으로 형변환을 하는 것이다.
    기본적인 형변환은 Obejct(), Number(), String(), Boolean()과 같은 함수를 이용한다.
let variable = 100

console.log(variable, typeof variable) // 100 "number"

variable = Object(variable)
console.log(variable, typeof variable) // Number {100} "object"

variable = String(variable)
console.log(variable, typeof variable) // 100 "string"

variable = Boolean(variable)
console.log(variable, typeof variable) // true "boolean"

== , ===의 차이점

  • ==
    a와 b의 값이 같은지를 비교해서, 같으면 true, 다르면 false라고 한다.(값만 같으면 true이다.)

  • '==='값과 값의 종류(Data Type)가 모두 같은지를 비교해서, 같으면 true, 다르면 false라고 한다.

  • 변수를 비교하거나 어떤 비교를 위해 항상 '===' 연산자를 사용 할 것을 권장한다.
    가능한 '==' 연산자를 사용하지 않도록 하고, 대신 직접 자료형을 변환하여(casting) 보다 코드 가독성을 높이도록 한다.

undefined와 null의 미세한 차이

  • undefined은 변수를 선언하고 값을 할당하지 않은 상태
  • null은 변수를 선언하고 빈 값을 할당한 상태(빈 객체)이다.

2.JavaScript 객체와 불변성

기본형과 참조형의 종류 및 차이점

  • 기본형(Primitive type) : 기본형 데이터는 값을 그대로 할당하는 것.
    메모리 내에 고정된 크기로 저장되면서, 원시 데이터 값 자체를 보관, 불변적
    기본적으로 데이터는 하나의 메모리를 사용한다.(재사용)
  • number : 3.141592
  • string : ‘Hanamon’
  • boolean : true & false
  • undefined : 변수가 정의되지 않았거나 값이 없다.
  • null : 의도적으로 비어있음을 표현하기 위해 null 이라는 것이 들어있다.
  • Symbol(ES6 부터 추가 됨, 객체 속성을 만드는 데이터 타입)

  • 참조형(Reference Type) : 값이 저장된 주소 값을 할당
  • 자바스크립트에선 원시 자료형이 아닌 모든 것은 참조 자료형이다.
  • 참조형은 원시형 데이터의 집합이다.
  • 배열([])과 객체({}), 함수(function(){})가 대표적이다.
  • 참조 자료형은 기존에 고정된 크기의 보관함이 아니다.
  • 참조 자료형을 변수에 할당할 때는 변수에 값이 아닌 주소를 저장한다.
  • 동적으로 크기가 변하는 데이터를 보관하기위해 변수가 아닌 다른곳에 데이터를 저장하고 변수에는 그 주소만 할당한다.
  • 배열 – Array : [0,1,2,3,4]
  • 객체 – Object {name : “Hanamon”, age : 16}

불변 객체를 만드는 방법

  • const
    자바스크립트 키워드 중 하나인 const이다. ES6문법부터 let과 const를 지원한다.
    const 키워드는 변수를 상수로 선언할 수 있다, 일반적으로 상수로 선언된 변수는 값을 바꾸지 못하는 것으로 알려져 있다.

  • Object.freeze()
    자바스크립트에서 기본적으로 제공하는 메소드인 Object.freeze() 메소드이다. 공식 문서에서는 "객체를 동결하기 위한 메소드" 라고 적혀있다.

  • const와 Object.freeze()를 조합하여 만들 수 있다. (const의 재할당불가 + Object.freeze()의 객체속성 변경불가)
    먼저 const키워드로 바인딩 된 변수를 상수화 시킨 다음, Object.freeze()로 해당 변수를 동결 객체를 만들면
    객체의 재할당과 객체의 속성 둘 다 변경불가능한 불변 객체가 된다.

const test = {
    'name' : 'jung'
};

Object.freeze(test);

얕은 복사와 깊은 복사

  • 얕은 복사

  • 객체를 복사할 때 위의 예제처럼 원래값과 복사된 값이 같은 참조를 가리키고있는 것을 말한다. 객체안에 객체가 있을 경우 한개의 객체라도 원본 객체를 참조하고 있다면 이를 얕은 복사라고 한다.
    -1. Object.assign()
    -2. 전개연산자

  • 깊은 복사

  • 깊은 복사된 객체는 객체안에 객체가 있을 경우에도 원본과의 참조가 완전히 끊어진 객체를 말한다.

    1. 재귀함수를 이용한 복사
    1. JSON.stringify()
    1. 라이브러리 사용

3. 호이스팅과 TDZ

스코프, 호이스팅, TDZ

  • 호이스팅
    함수의 코드를 실행하기 전에 함수 선언에 대한 메모리부터 할당한다. 덕분에 스크립트내에서 함수 선언의 위치는 중요하지 않다. 스크립트내에서 함수 호출을 함수 선언보다 먼저 해도 문제가 없다. 또 호이스팅은 스코프 단위로 일어난다..

  • 자바스크립트는 ES6에서 도입된 let, const를 포함하여 모든 선언(var, let, const, function, function*, class)을 호이스팅합니다. 호이스팅(Hoisting)이란, var 선언문이나 function 선언문 등을 해당 스코프의 선두로 옮긴 것처럼 동작하는 특성을 말합니다.

  • TDZ
    스코프 시작 ~ 초기화 시작 사이의 구간을 의미합니다. 다른 말로 변수가 선언되고 변수의 초기화가 이루어지기 전까지의 구간이라고 말할 수 있겠습니다.

    1. 선언 단계 (Declaration phase)
      변수를 실행 컨텍스트의 변수 객체에 등록하는 단계
    1. 초기화 단계 (Initialization phase)
      실행 컨텍스트에 등록한 변수를 위한 메모리를 만드는 단계, 메모리가 만들어지면 처음에는 undefined 가 할당
    1. 할당 단계 (Assignment phase)
      사용자가 undefined 로 할당된 변수에 다른 값을 할당하는 단계
  • 스코프
  • 전역 스코프 - 변수가 함수 바깥에 선언되어 있거나, 변수 선언 시 var 키워드를 사용하지 않으면 변수는 전역 스코프에 포함됩니다.
  • 함수 스코프 - 변수가 함수 내에서 선언되면 이 변수는 함수 스코프 내에 존재하게 됩니다.
  • 자바스크립트의 변수는 변수가 접근할 수 있는 범위(스코프)에 따라 전역변수와 지역변수로 나눌 수 있습니다.
  • 전역변수는 전역 스코프, 즉 함수 바깥에서 선언된 변수입니다. 따라서 전역변수는 프로그램의 전체에서 접근 가능합니다.
  • 반면에 지역변수는 함수 스코프, 즉 함수 내부에서 선언된 변수로, 함수 내부에서만 접근 가능합니다.

함수 선언문과 함수 표현식에서 호이스팅 방식의 차이

  • 주요 차이점은, 호이스팅에서 차이가 발생합니다.
    함수 선언식은 함수 전체를 호이스팅 합니다. 정의된 범위의 맨 위로 호이스팅되서 함수 선언 전에 함수를 사용할 수 있다는 것입니다.
    함수 표현식은 별도의 변수에 할당하게 되는데, 변수는 선언부와 할당부를 나누어 호이스팅 하게 됩니다. 선언부만 호이스팅하게 됩니다.

  • 호이스팅은 var 변수 선언, 함수선언식에서만 일어난다. let/const에서는 호이스팅이 발생하지 않는다.

var minus = function (a,b) { // 함수 표현식
  return a - b;
}

sum(50, 50); // 100
minus(100, 50) // 50

function sum(a, b) { // 함수 선언식
  return a + b;
};

실행 컨텍스트와 콜 스택

  • 실행 컨텍스트(Execution context)
    자바스크립트 코드가 실행되는 환경을 의미합니다. 자바스크립트에서 대표적으로 두 가지 타입의 실행 컨텍스트가 있습니다.
    1. Global Execution context
    1. Function Execution context
  • 자바스크립트 엔진은 처음 코드를 실행할 떄 단 한번 Global Execution Context를 생성하며 함수를 호출할 때 마다 함수를 위한 Execution context를 생성합니다.

  • 콜 스택(Call stack)

  • 코드가 실행되면서 생성되는 실행 컨텍스트를 저장하는 자료구조 입니다.
  • 엔진이 처음 script를 실행할 때, Global Execution Context를 생성하고 이를 Call Stack에 push합니다. 그 후 엔진이 함수를 호출할 때 마다 함수를 위한 Execution Context를 생성하고 이를 Call Stack에 push 합니다.

스코프 체인, 변수 은닉화

  • 스코프 체인 : 식별자에 대한 유효 범위를 나타낸다.떤 경계 A의 외부에서 선언한 변수는 A의 외부뿐 아니라 A의 내부에서도 접근이 가능하지만, A의 내부에서 선언한 변수는 오직 A의 내부에서만 접근할 수 있다. 이러한 식별자의 유효범의를 안에서부터 바깥으로 차례로 검색해나가는 것을 스코프 체인이라고 부른다.

  • 변수은닉화 : 외부 객체로부터 '속성 값(데이터, 멤버 변수값)'을 감추는 특성

  • 접근제어자 private로 감춘다. (private - class내에서만 접근가능)

  • private를 사용하는 이유 ?
    외부로부터 데이터를 보호(캡슐화)하기 위해서
    인스턴스 변수는 private로 하여 외부에서 접근하지 못하도록 하고, 메서드는 public으로 하여 직접 접근은 막고 메서드를 통한 간접 접근 허용
    외부에는 불필요한, 내부적으로만 사용되는 , 부분을 감추기 위해서

4.실습 과제

콘솔에 찍힐 b 값을 예상해보고, 어디에서 선언된 “b”가 몇번째 라인에서 호출한 console.log에 찍혔는지, 왜 그런지 설명해보세요.
주석을 풀어보고 오류가 난다면 왜 오류가 나는 지 설명하고 오류를 수정해보세요.

let b = 1;

function hi () {

	const a = 1;
	let b = 100;
	b++;
	console.log(a,b);

}

//console.log(a);
console.log(b);
hi();
console.log(b);

풀이

let b = 1;

function hi () {
	const a = 1;
	let b = 100;
	b++;

	console.log(a,b);

}

//console.log(a);
console.log(b); // 첫 줄 b =1
hi();
console.log(b); // 첫 줄 b =1
let b = 1;

function hi () {

    const a = 1;
    let b = 100;
    b++;
    console.log(a,b);
}

console.log(a);
console.log(b); 
hi();
console.log(b);
// a가 지역스코프로 선언되어 바깥의 범위에서는 console 불가
let b = 1;
const a = 1;
function hi () {

    let b = 100;
    b++;
    console.log(a,b);
}

console.log(a);
console.log(b); 
hi();
console.log(b);
profile
코린이 열심히 배우자!

0개의 댓글