React 입문주차 S.A.

SEO JEONG GWON·2022년 7월 1일
0

SA

목록 보기
1/1
post-thumbnail

🐤 JavaScript의 자료형과 JavaScript만의 특성은 무엇일까 ?

  • 느슨한 타입(loosely typed)의 동적(dynamic) 언어
    	let x = 1 // x가 숫자
    	x = 'bar' // x가 이제 문자열
    	x = true // x가 이제 불리언 (boolean+언어(숫자, 문자처럼)의 명칭같다)

    JS는 느슨한 타입의 동적 언어이기 때문에 (변수 생성 시)원시 변수의 타입을 미리 선언하지 않아도 된다는 장점이 있다. 프로그램이 처리되는 과정에서 자동으로 파악하고, 이 말은 결국 같은 변수에도 불구하고 상황에 따라 값의 타입이 바뀔 수 있다는 뜻이기도 하다.

    자바스크립트는 컴파일 과정 없이 실행과 동시에 해석을 하는 인터프리터 언어이다. 그런 원리에서 코드가 실행되는 과정에서 상황에 따라 값의 타입이 유연하게 바뀔 수 있는 것이다.

    타입에 엄격한 프로그래밍 언어에 익숙한 사람이라면 이 유연한 형 변환이 몰상식한 현상으로 느껴질 수도 있다. 하지만, 누군가에게는 이 형 변환이 개발하는 데 있어서 편리함과 자유로움을 느끼게 해주기도 한다.


  • JavaScript 형변환

    형변환은 크게 두 종류로 일어난다. = > 명시적 형 변환과 암시적 형 변환.
    명시적 형 변환은 말 그대로 내가 명시적으로. 즉, 의도적으로 형 변환을 하겠다는 경우이다.

    명시적 형 변환은 주로 string, number, boolean 타입으로 이루어진다.

    어떤 값을 의도적으로 형태를 변형해서 사용하겠다는 의미이기 때문에
    일단 symbol은 자주 사용되지 않고, null과 undefined는 자료형이면서 동시에 값이기 때문에 필요한 경우 그냥 그 값을 할당하면 된다.

    object도 Date 객체를 숫자로 변환하는 특별한 경우가 아니라면, 그냥 순전히 값 을 object로 만들면 만들었지 굳이 object로 형 변환하는 일은 없다. _따라서 이 세 종류로의 명시적 형 변환은 각각 String(), Number(), Boolean() 함수를 사용하면 된다.

    이어서 암시적 형변환은 연산할 때 일어난다
    어떤 값과 값이 연산되어질 때 필요한 상황에 따라 형 변환이 일어난다는 얘기다. ( JS에서 호불호가 극명하게 갈리는 요소중 하나가 바로 이 암시적 형 변환이라고 하는데 여러 상황들을 고려해보면 개발의 속도를 올리는데는 확실히 긍정적인 메커니즘이 아닌가 싶다 )
    크게 암시적 형 변환에서는 덧셈 연산자( + ) 와 관계 연산자 ( < , <= , > , >= ), 동치 연산자 (==, !=, === , !== ), 논리 연산자( &&, ||, ! ) 가 있다.


  • ==, ===

    ==는 Equal Operator이고, ===는 Strict Equal Operator이다.
    ==는 a == b 라고 할때, a와 b의 값이 같은지를 비교해 같으면 true, 다르면 false이다.
    ===는 a === b 라고 할때, 값과 값의 종류가 모두 같은지를 비교해 같으면 true, 다르면 false이다.


  • 느슨한 타입(loosely typed)의 동적(dynamic) 언어의 문제점은 무엇이고 보완할 수 있는 방법에는 무엇이 있을지 생각해보세요.

    실행 도중에 변수에 예상치 못한 타입이 들어와 타입에러가 발생할 수 있다. 동적타입 언어는 런타임 시 확인할 수 밖에 없어 코드가 길고 복잡해질 경우 타입 에러를 찾기가 어려워진다. 많은 기능 명세서와 API가 오고 가는 대형프로젝트(혹은 협업 시)에서 타입이 올바른지 체크하는 것이 굉장히 까다롭기 때문에 배포 시 예상치 못한 문제와 직면할 수 있다.보완할 수 있는 방법은 TypeSciptFlow 등 사용하는 것이다.


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

    null은 사용자가 명시적으로 '없음'을 표현하기 위해 대입한 값
    (본래의 의미에 따라 사용자가 없음을 표현하기 위해 명시적으로 undefined를 대입하는 것은 지양해야..)
    undefined는 그 자체가 값으로 '비어있음'을 의미하기는 하지만 하나의 값으로 동작한다

    null과 undefined의 의미는 둘다 값의 존재 유무를 표현하는 타입이다. 자바스크립트에서는 세밀한 부분의 의미는 달라도 문맥적 의미로는 같은 의미를 가진 가진 타입을 2개로 분리해서 정의하다보니 프로그래머 입장에서는 애매모호함을 만들어내 불편을 만들어주는 요소 중 하나라고 한다.

    변수에 값이 null이라면 변수가 선언되고 null이라는 값이 주어진 상태이고 undefined라면 변수가 선언되고 아무것도 하지 않은 상태이다. 즉 null은 직접적으로 값이 없어라고 말한 상태이지만 undefined는 아무것도 하지 않은 상태라고 말할 수 있기 때문에 프로그래머가 의도적으로 값이 주어지지 않은 상태의 동작을 개발하려는 것이 아니라면 undefined의 사용은 부적절하다고 이야기할 수 있다. 이것이 null과 undefined의 차이다.


🐤 JavaScript 객체와 불변성이란 ?

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

    기본형에는 Number, String, Boolean, null, undefined 가 있다. 바로 값을 그대로 할당한다.
    참조형은 대표적으로 객체(Object)가 있고 그 하위에 배열(Array), 함수(Function), 정규표현식(RegExp) 등이 있다. 값이 저장된 주소값을 할당(참조)한다.


  • 불변 객체를 만드는 방법

    각종 라이브러리(immutable.js, baobab.js 등)
    spread operator { . . . state }
    JavaScript에 내장된 Object.assign 등의 메서드
    JSON 객체의 메서드 이용
    사용자 정의 함수


    참조형 데이터 타입인 객체는 가변값을 가지기 때문에 객체를 복사하면 같은 주소값을 서로 가리키고 복사된 객체의 프로퍼티 값을 변경해도 여전히 같은 주소값을 참조하게 됨으로 원본의 데이터도 변경이 된다. 이러한 현상을 피하기 위해 애초에 서로 다른 주소값을 참조하게 하여 객체 역시 불변성을 확보할 수 있다.

    불변객체가 필요한 순간은 값으로 전달받은 객체를 변경 하더라도 원본 객체가 변하지 않아야 하는 경우에 사용된다.


  • 얕은 복사와 깊은 복사

    얕은 복사(shallow copy) : 바로 아래 단계의 값만 복사하는 방법
    깊은 복사(deep copy) : 내부의 모든 값들을 하나하나 찾아서 전부 복사하는 방법


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

  • 스코프, 호이스팅, TDZ

    호이스팅 : 스코프 내부 어디서든 변수 선언은 최상위에 선언된 것 처럼 행동하는것 ( 하단에 선언된 변수를 해당 스코프의 최상다으로 끌어올리는(선언하는) 것을 의미한다. 선언은 호이스팅 되지만, 할당은 호이스팅이 되지 않음 그래서 undefined를 출력한다 ).

    [ var는 선언하기 전에 사용 x ( error가 생기지 않음 ) ][ let은 선언 전에 사용할 수 없다 ]

    => var를 선언 전에 사용할 수 있는 이유는 JS의 특징인 호이스팅이라는 개념 때문이다.
    변수 선언이 런타임에서 되는 것이 아니라, 그 이전 단계에서 먼저 실행된다.
    자바스크립트 엔진은 소스코드를 한 줄씩 순차적으로 실행하기 앞서, 변수 선언을 포함한 모든 선언문(변수 선언, 함수 선언)을 찾아내 먼저 실행한다.
    즉, 변수 선언이 어디에 있든 상관없이 다른 코드보다 먼저 실행되는 특징을 호이스팅(hoisting)이라 한다.

    스코프란 JS에서 어떤 변수들에 접근할 수 있는지를 정의한다. 두가지 종류가 있는데 전역 스코프와 지역 스코프가 있다.
    그 중에서도 지역 스코프(local scope)에는 두가지의 지역 변수가 존재한다. 바로 함수 스코프(function-scoped - var)와 블록 스코프(block-scoped - let, const) 두가지가 있다.

    TDZ란 일시적 사각지대 Temporal Dead Zone의 줄임말. 선언단계에서 초기화 단계로 넘어가는 사이의 영역을 TDZ라고 부르는데, TDZ영역에 있는 변수는 초기화 단계가 선언문에서 이루어지기 때문에 그 전에 할당 및 호출할 경우 참조오류(Reference Error)를 발생 시킨다.


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

    함수 선언식은 함수 전체를 호이스팅 한다. 정의된 범위의 맨 위로 호이스팅되서 함수 선언 전에 함수를 사용할 수 있다는 것이다.

    함수 표현식은 별도의 변수에 할당하게 되는데, 변수는 선언부와 할당부를 나누어 호이스팅 하게 된다. 선언부만 호이스팅하게 된다.


  • 실행 컨텍스트와 콜 스택

    콜 스택이란, 실행 컨텍스트들을 차곡차곡 쌓는 것이다. (= 실행 컨텍스트들을 기록하고 있는 자료구조다 라고 생각하면 편할 듯 하다. )

    실행 컨텍스트란, 실행 가능한 코드를 형상화하고 구분하는 추상적인 개념이다.
    즉, 실행 가능한 코드가 실행되기 위해 필요한 환경이다. 대표적으로 두 가지 타입의 Execution context가 있다 => ( 1. Global Execution context 2. Function Execution context )
    JS엔진은 코드를 실행하기 위해 실행에 필요한 여러가지 정보를 알고 있어야 한다. 실행에 필요한 여러가지 정보란 아래와 같다.

    1. 변수: 전역변수, 지역변수, 매개변수, 객체의 프로퍼티
    2. 함수 선언
    3. 변수의 유효범위 (Scope)
    4. this

  • 스코프 체인, 변수 은닉화

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

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


실습 과제

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

function hi () {

const a = 1;

let b = 100;

b++;

console.log(a,b);

}

//console.log(a); // a는 hi함수의 지역변수로 지정이 되어있어서 함수 밖에서는 a 호출이 불가

console.log(b); // 결과 = 가장 상단의 전역 변수 b 값을 가져와 1을 출력
  
hi(); 결과 = 함수 내에 있는 지역변수 a,b++ (1,100)이 출력

console.log(b); // 2번째줄과 동일하게 전역 변수 b 값을 가져와 1을 출력