시작 전

해당 글은 'Triplex'님 블로그에서 그대로 퍼온 게시글 입니다.

너무나 좋은 내용 정리여서 가져왔지만 그 내용을 있는 그대로 이해하기엔 저에게 부족한 부분이 많아 각 파트별로 제가 읽고 느끼고 이해한 주관적인 생각들을 주석처럼 달아보았습니다. 내용에 이해가 어려우신 부분은 제 주석도 참고 해 주시면 좋을 것 같고 혹시 주석 부분에서 저의 잘못된 이해 부분이 있다면 댓글로 언제든지 알려주시면 다시 공부해보겠습니다😁

본문링크

TriplexLab

👉JavaScript의 자료형과 JavaScript만의 특성

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

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

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

JavaScript의 변수는 어떤 특정 타입과 연결되지 않으며, 모든 타입의 값으로 할당 (및 재할당) 가능합니다.
아마 느슨한 타입의 동적 언어라는 건 변수가 어떤 타입에 묶여있지 않기 때문에 느슨하다고 표현하고 어떤 타입의 값이든 할당과 재할당이 가능하기 때문에 '동적이다'라고 표현하는것 같습니다.

let foo = 42 // foo가 숫자
foo = 'bar' // foo가 이제 문자열
foo = true // foo가 이제 불리언

tastekim의 생각

🎯JavaScript 형변환

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

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

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

뒤에 나올 '=='와 '==='연산자에서 볼 수 있는데
'=='연산자가 스스로 변수의 타입을 변환해서 비교조건의 값과 평가하는 것을 보면 암시적변환은 이 부분을 말하는 것 같다.

console.log('10' == 10);
true

tastekim의 생각

🎯'=='와 '==='의 차이점

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

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

🎯느슨한 타입(loosely typed)의 동적(dynamic) 언어의 문제점은 무엇이고 보완할 수 있는 방법

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

느슨한 타입의 동적 언어는 자유로운 할당 및 재할당이 가능하기 때문에 의도치 않게 다른 타입의 값이 언제든지 들어갈 수 있기 때문에 컴파일 타임에 알려주지 않는다면 에러를 그 만큼 빨리 찾을 수가 없다라는 뜻으로 이해했습니다. Typescript나 Flow 등은 제가 아직 겪어보지 못해서 이 문제점의 보완법으로는 더 공부해야 할 것 같습니다.
tastekim의 생각

🎯undefined와 null의 미세한 차이들을 비교해보세요.

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

let a; //undefined
let b = null; // null

결국 undefined는 변수는 선언했지만 어떠한 타입의 값도 정의되지 않은 상태이고 null은 값은 존재하지만 어떠한 타입으로도 정의할 수 없음을 표현
tastekim의 생각

👉JavaScript 객체와 불변성이란?

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

📌기본형 타입(Primitive type)

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

📌참조형 타입(Reference type)

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

기본형 타입은 그 값 자체로서 의미를 갖는 타입이고 참조형 타입은 그 값을 참조(무엇에 관해 알기 위하여 다른 것을 견주어 살펴보다.) 해서 다른 원하는 값을 찾는 타입으로 이해했다.
tastekim의 생각

🎯불변 객체를 만드는 방법

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

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

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

객체 변수를 선언할 때 const로 선언한 변수의 값도 한번 선언 후엔 다시 할당, 재할당이 불가능하다고 알고있는데 같은 의미인지 찾아봐야겠다.
tastekim의 생각

🎯얕은 복사와 깊은 복사

📌얕은 복사(Shallow Copy)

  • 객체를 복사할 때, 해당 객체만 복사하여 새 객체를 생성한다.

  • 복사된 객체의 인스턴스 변수는 원본 객체의 인스턴스 변수와 같은 메모리 주소를 참조한다.

  • 따라서, 해당 메모리 주소의 값이 변경되면 원본 객체 및 복사 객체의 인스턴스 변수 값은 같이 변경된다.

📌깊은 복사(Deep Copy)

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

    얕은 복사와 깊은 복사의 개념은 제가 '코어 자바스크립트' 서적을 통해서 이해하려고 공부중입니다,,,

👉호이스팅과 TDZ는 무엇일까?

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

🎯스코프, 호이스팅, TDZ

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

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

📌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;
}

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

🎯let, const, var, function 이 어떤 원리

  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변수에 접근해서 출력
profile
재밌어서 공부하는 개발자

0개의 댓글