ETC -

JavaScript의 자료형과 JavaScript만의 특성

  • -

이번 시간에는 JavaScript의 자료형과 JavaScript만의 특성은 무엇일까?에 대해서 살펴보겠습니다.

JavaScript는 느슨한 타입(loosely typed)의 동적(dynamic) 언어입니다.
JavaScript의 변수는 어떤 특정 타입과 연결되지 않으며,
모든 타입의 값으로 할당 및 재할당 가능합니다.

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

암시적변환 
암시적 변환이란 자바스크립트 엔진이 필요에 따라 자동으로 데이터타입을 변환시키는 것이다.

명시적변환
명시적변환이란 개발자가 의도를 가지고 데이터타입을 변환시키는 것이다.

자바스크립트는 엄격한 비교와 유형변환 비교를 모두 지원하므로, 어떤 연산자가 어떤 비교조건에 사용되는지가 중요하다. 
위에 말했듯이, ===는 변수 유형을 고려하는 반면, ==는 변수 값을 기반으로 유형을 수정한다.

더보기
  • ☝ '==' 연산자를 이용하여 서로 다른 유형의 두 변수의 [값] 비교
  • ✌ '==='는 엄격한 비교를 하는 것으로 알려져 있다 ([값 & 자료형] -> true).

실행 도중에 변수에 예상치 못한 타입이 들어와 타입에러가 발생할 수 있음 
동적타입 언어는 런타임 시 확인할 수 밖에 없기 때문에, 코드가 길고 복잡해질 경우 타입 에러를 찾기가 어려워 집니다. 
이러한 불편함을 해소하기 위해 TypeScipt나 Flow 등을 사용할 수 있습니다.

undefined은 변수를 선언하고 값을 할당하지 않은 상태, null은 변수를 선언하고 빈 값을 할당한 상태(빈 객체)이다. 
즉, undefined는 자료형이 없는 상태이다.


📌기본형 타입(Primitive type)

종류: 논리형(boolean), 정수형(int), 실수형(double), 문자형(char)

📌참조형 타입(Reference type)

종류: 배열(Array), 클래스(Class), 인터페이스(Interface)

'불변 객체'란 - '변하지 않는 객체' 즉 이미 할당된 객체가 변하지 않는다는 뜻을 가지고 있다.

JavaScript Immutability[참고]

// Object freeze 객체를 불변하게 만들기
let test = {
    name : 'kim'
}

Object.freeze(test);
test.name = 'Jung';
console.log(test)

name값이 변화하지 않고, "kim"을 유지하는 상태
name값이 변화하지 않고, "kim"을 유지하는 상태

📌얕은 복사(Shallow Copy)

  • 객체를 복사할 때, 해당 객체만 복사하여 새 객체를 생성한다.
  • 복사된 객체의 인스턴스 변수는 원본 객체의 인스턴스 변수와 같은 메모리 주소를 참조한다.
  • 따라서, 해당 메모리 주소의 값이 변경되면 원본 객체 및 복사 객체의 인스턴스 변수 값은 같이 변경된다.

📌깊은 복사(Deep Copy)

  • 객체를 복사 할 때, 해당 객체와 인스턴스 변수까지 복사하는 방식.
  • 전부를 복사하여 새 주소에 담기 때문에 참조를 공유하지 않는다.

변수, 호이스팅, TDZ(Temporal Dead Zone)

📌스코프: 변수, 함수, 클래스가 접근할 수 있는 유효 범위.

📌호이스팅: 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다.

📌TDZ: 아래 코드를 보면서 설명합니다.(주석 참고!)👇👇

let age = 30;
function showAge() {
    console.log(age) //여기서 위에 age에 잘 접근할수 있습니다.
}
showAge();

위에 코드에서 let age = 20;를 추가해보겠습니다.

let age = 30;
function showAge() {
    console.log(age) //2) TDZ 영역이 되어서 ReferenceError 에러를 볼수 있습니다.
    let age = 20; //1) 이것을 추가하면 
}
showAge();

함수 선언식 (function declartion) 
함수명이 정의되어 있고, 별도의 할당 명령이 없는 것
함수 전체를 호이스팅 합니다. 정의된 범위의 맨 위로 호이스팅되서 함수

function sum(a,b) {
    return a + b;
}

함수 표현식 (function Expression)
정의한 function을 별도의 변수에 할당하는 것
별도의 변수에 할당하게 되는데, 변수는 선언부와 할당부를 나누어 호이스팅 하게 됩니다.

const sum = function(a,b) {
    return a + b;
}

함수 선언식으로 작성한 함수는, 함수 전체가 호이스팅 된다고 하였는데, 전역적으로 선언하게 되면, 중복적으로 동명의 함수를 쓰게 되었을때, 원치 않는 결과를 초래할 수 있습니다. 이를 방지하려면 함수 표현식으로 작성하면 됩니다.

  1. var : 변수 재선언 가능
    const, let : 변수 재선언 불가능
  2. const : 변수 재할당 불가능 (상수)
    let : 변수 재할당 가능
  3. var : functional-scope 로 호이스팅됨
    const, let : block-scope 로 호이스팅됨

콜 스택

더보기

call은 호출을 뜻한다. 
stack은 출입구가 하나뿐인 깊은 우물 같은 데이터 구조다. 

따라서 callstack은 자바스크립트가 함수 호출을 기록하기 위해 사용하는 우물 형태의 데이터 구조이다. 

항상 맨 위에 놓인 함수를 우선으로 실행된다. 이런 식으로 자바스크립트 엔진은 가장 위에 쌓여있는 context와 관련 있는 코드들을 실행하는 식으로 전체 코드의 환경과 순서를 보장한다.

실행 컨텍스트

더보기

Execution Context 는 자바스크립트의 핵심 개념으로, 코드를 실행하기 위해 필요한 환경이다. 
더 자세히 말하자면, 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다. 
자바스크립트의 동적 언어로서의 성격을 가장 잘 파악할 수 있는 개념.

모든 코드는 특정한 실행 컨텍스트 안에서 실행된다. 
javascript는 어떤 execution context가 활성화되는 시점에 선언된 변수들을 위로 끌어올리고(hoisting), 외부 환경 정보를 구성하고, this값을 설정하는 등의 동작을 수행하는데, 이로 인해 다른 언어에서는 발생할 수 없는 특이한 현상들이 발생한다.

자바스크립트의 주요한 실행 컨텍스트에는 두 가지가 있다.Global Execution Context, Fuction Execution Context

스코프 체인

스코프에 식별자가 없으면 상위 스코프에서 다시 찾아 나간다. 
이 현상을 스코프 체인 이라고 하며 스코프가 중첩되어있는 모든 상황에서 발생한다.

변수 은닉화

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


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

let b = 1;
function hi () {
    const a = 1;
    let b = 100;
    b++;
    console.log(a,b); //const,let는 블럭 스코프에서 유효하기 때문에 함수 내부에 있는 변수들에 접근해서 출력됨
}

console.log(a); // 여기서 오류가 나는 이유는 전역적으로 a라는 변수가 존재하지 않아서 입니다.(이것을 해결하기 위해서는 전역적으로 a 초기값 변수를 할당하면 됩니다.)
console.log(b); //전역 b변수에 접근해서 출력
hi();
console.log(b); //전역 b변수에 접근해서 출력

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.