JavaScript의 특성

김채운·2022년 5월 20일
0

JS

목록 보기
1/3
🐤 JavaScript의 자료형과 JavaScript만의 특성은 무엇일까 ?
  • 느슨한 타입(loosely typed)의 동적(dynamic) 언어

    자바스크립트의 변수는 어떤 특정 타입과 연결되지 않으며, 모든 타입의 값으로 할당 및 재할당이 가능하다.

  • JavaScript 형변환

    자바스크립트에는 '암시적형변환'과 '명시적형변환'이 있다.
    -암시적 형변환: 자바스크립트 엔진이 필요에 따라 자동으로 데이터 타입을 변환시키는 것이다.
    암시적 형변환은 각기 다른 타입의 값들을 !!, ==, +, -, && .. 등의 비교, 산술, 문자열, 논리 연산자로 연산 시 발생한다.
    -명시적 형변환: Boolean, Number, String 등의 객체를 사용해 타입 변환을 할 때 명시적 형변환이라 부른다.

  • ==, ===

    -'==': 값만 비교해서 값이같으면 true 아니면 false ex) 0 == false 하면 true
    -'===': 값 뿐만 아니라 데이터타입까지 비교해서 ex) 0 === false 하면 false

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

    런타임에 비로소 타입이 결정되는 언어입니다. 소스가 컴파일, 빌드될 때 자료형을 결정하는 것이 아니라 실행할 때 결정됩니다. 언어 자체에서 타입을 추론해서 형을 변환해 줍니다. 대표적인 동적 언어로는 JavaScript, Ruby, Python 등이 있습니다.
    변수를 생성할 때 마다 매번 타입을 써줄 필요가 없기 때문에 기본적으로는 편하고 빠르게 코드를 작성하기 좋습니다.
    하지만 실행 도중에 변수에 예상치 못한 타입이 들어와 Type Error가 발생하는 경우가 생길 수 있습니다. 정적 언어와 달리 실행되는 시점에서 오류를 출력합니다. 특히 프로젝트의 크기가 크거나 협업을 하는 과정에서 변수의 타입이 일치하지 않는 경우가 생길 수 있으므로 주의를 기울여야 합니다.
    자바스크립트가 가진 동적 언어의 단점을 보완하는 방법으로는 TypeScript를 사용하는 방법이 있습니다. 타입스크립트란 자바스크립트에서 코드를 입력할 때 타입을 미리 부여하는 기능을 추가한 정적 타입 언어입니다.

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

    둘 다 변수에 값이 없는걸 나타내지만 의미는 다르다.
    undefined: 원시값으로 변수에 값이 할당되지 않은 상태일 때 undefinde가 반환된다.
    null과 다르게 자료형이 없는상태
    ex) let a; 변수를 선언하고 값을 할당하지 않은 상태
    null: null 또한 원시값으로 분류되고, 변수를 선언하고 의도적으로 빈 값을 할당한 상태(빈 객체)를 의미한다, typeof로 자료형을 확인 해보면 object가 나온다. but, 자바스크립트 기존 이슈로 인한 결과이니 객체형으로 오해하지 않도록 주의해야한다.

🐤 JavaScript 객체와 불변성이란 ?
  • 기본형 데이터와 참조형 데이터

    기본형 데이터로 타입으로는 Number, String, Boolean, Undefined, Null, Symbol 이 있다. 이와같은 기본형 타입들은 값을 그대로 할당해준다. 그리고 메모리 내에 고정된 크기로 저장 하면서 원시 데이터인 값을 자체로 저장하고 불변적인 속성을 가지고 있다.
    참조형 데이터 타입은 객체, 함수, 배열 등을 말한고 값이 저장된 주소값을 할당(참조) 해준다. 참조형은 기본형 데이터의 집합이다.

  • JavaScript 형변환

    자바스크립트의 형변환에는 '암시적 형변환'과 '명시적 형변환'이 있다.
    '암시적변환'은 자바스크립트 엔진이 필요에따라 자동으로 데이터타입을 변환시키는 것이고,
    암시적변환에서의 산술연산자인 더하기+ 연산자는 숫자보다 문자열이 우선시되기 떄문에, 숫자형이 문자형을 만나면 문자형으로 변환하여 연산된다. 하지만 다른 연산자(-,*,/,%)같은 경우는 숫자형이 문자형보다 우선시되기 떄문에 더하기와 같은 문자형으로의 변환이 일어나지 않는다.
    '명시적변환'은 개발자가 의도를 가지고 데이터타입을 변환시키는 것이다.
    타입을 변경하는 함수인 Object(),Number(),String(),Boolean() 을 사용한다.
    만약 new 연산자가 없다면 사용한 함수는 타입을 변환하는 함수로서 사용된다.

  • 불변 객체를 만드는 방법

    '불변객체'란 변하지 않는 객체로 이미 할당된 객체가 변하지 않는다는 의미이다.
    불변 객체로 만드는 방법은 두가지가 있는데, 하나는 const를 사용하는 것이고, 다른 하나는 object.freeze()를 사용하는 방법이다.
    const는 변수를 상수로 선언하게 하는 것이고 상수로 선언된 변수는 값을 바꾸지 못한다.
    하지만, ES6에서 const는 할당된 값의 상수인 게 아니라 바인딩 된 값이 상수가 되기 때문에 불변객체라고는 할 수 없겠다. 그래서 object.freez()를 사용해 불변 객체를 만들어줄 수 있다.
    object.freez()는 자바스크립트에서 기본적으로 제공해주는 메소드이다. 공식 문서에서는 "객체를 동결하기 위한 메소드" 라고 적혀있다.
    사용법은 간단하다. 변수에 key value를 가진 객체를 바인딩 후 Object.freeze()를 사용해 바인딩된 변수를 동결 객체로 만들었다. 때문에 객체는 객체의 속성을 변경하는 시도는 불가능하다. but, Object.freeze()는 동결된 객체를 반환하지만 객체의 재할당은 가능하다.
    그래서 결론적으로는, const와 Object.freeze()를 조합하여 만들 수 있다. (const의 재할당불가 + Object.freeze()의 객체속성 변경불가)
    이렇게 되면, 객체의 재할당과 객체의 속성 둘 다 변경불가능한 불변 객체가 된다.

  • 얕은 복사와 깊은 복사

    '얕은 복사'는 객체를 복사할 때 원래값과 복사된 값이 같은 참조(주소)를 가리키고 있는 것을 말한다. 한마디로 얕은 복사는 객체의 참조값(주고)를 복사한다는 의미다. 그래서 복사를 하고 객체를 수정하면 두 변수는 똑같은 주소를 가리키고 있기 때문에 기존 객체를 저장한 변수도 영향을 받는다.
    '깊은 복사'는 객체의 실제 값을 복사하는 것을 말한다. 그래서 깊은 복사는 원시값을 복사할 때 그 값을 또 다른 독립적인 메모리 공간에 할당을 해서, 복사를 하고 값을 수정해도 기존 원시값을 저장한 변수는 영향이 없다. 이처럼 실제 값을 복사하는 것을 깊은 복사라고 한다.

🐤 호이스팅과 TDZ는 무엇일까 ?
  • 스코프, 호이스팅, TDZ

    '스코프'란 '영역','범위'라는 뜻이다. 이런 의미가 자바스크립트에서는 변수에영향을 줄 수 있는 범위 혹은 변수에 접근할 수 있는 범위를 뜻한다. 스코프는 '전역스코프(global)'와 '지역스코프(local)'로 분류할 수 있다. 전역스코프는 변수가 바깥에 선언되어 있어 프로그램 전체에서 접근이 가능하고, 지역 스코프는 함수 내에서 선언되어 함수 스코프 내에서만 존재하고 그래서 함수 내부에서만 접근이 가능하다.
    '호이스팅'이란, 코드가 실행되기 전 변수선언과 함수선언이 해당 스코프의 최상단으로 끌어 올려진 것 같은 현상을 말한다. 자바스크립트 엔진은 코드를실행하기 전 실행 간응한 코드를 형상화하고 구분하는 과정을 거치는데 이 과정에서 모든 선언(var,let,const,function,class)들을 스코프에 등록한다. 이런 선언이 코드 실행 보다 먼저 메모리에 저장되는 과정으로 인한 현상을 호이스팅이라한다.
    즉, 함수의 코드를 실행하기 전에 함수 선언에 대한 메모리부터 할당한다는 뜻이다.
    그래서 스크립트내에서 함수 호출을선언보다 먼저 해도 문제가 없다.
    'TDZ'란, 일시적인 사각지대라는 뜻으로, 스코프 시작지점부터 초기화 시작지점 사이의 구간을 의미한다. 한마디로 변수가 선언되고 변수의 초기화가 이루어지기 전까지의 구간이라고할 수있다.
    TDZ는 const, let class 구문의 유효성에 영향을 미치는 개념으로 TDZ는 선언 전에 변수를 사용하는 것을 허용하지 않는다.

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

    '함수 선언문'은 함수 전체를 호이스팅 합니다. 정의된 범위의 맨 위로 호이스팅이 돼서 함수선언 전에 함수를 사용할 수 있다.
    '함수 표현식'은 별도의 변수에 할당하게 되는데, 변수는 선언부와 할당부를 나누어 호이스팅 하게 된다. (선언부만 호이스팅하게 된다.)

  • 실행 컨텍스트와 콜 스택

    '실행 컨텍스트'는 자바스크립트 코드가 실행되는 환경을 의미한다.
    자바스크립트는 실행 컨텍스트가 활성화되는 시점에 호이스팅을 발생시키고, 외부 환경 정보를 구성하며, this값을 설정한다.
    '콜스택'은 코드가 실행되면서 생성되는 Execution Context를 저장하는 자료구조이다.
    엔진이 처음 script를 실행할 때, Global Execution Context를 생성하고 이를 Call Stack에 push한다.
    그 후 엔진이 함수를 호출할 때 마다 함수를 위한 Execution Context를 생성하고 이를 Call Stack에 push 한다.
    자바스크립트 엔진은 Call Stack의 Top에 위치한 함수를 실행하며 함수가 종료되면 stack에서 제거(pop)하고 제어를 다음 Top에 위치한 함수로 이동한다.
    콜 스택은 프로그램이 함수 호출을 추적할때 사용한다.

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

    '스코프 체인'이란 '객체의 리스트'로서 전역 객체와 중첩된 함수의 스코프의 레퍼런스를 차례로 저장하고, 각각의 스코프가 어떻게 연결되고 있는지 보여주는 것을 말한다. 식별자의 유효범위를 안에서부터 바깥으로 차례로 검색해 나가는 것을 스코프 체인이라고 부른다.
    '변수 은닉화'란 외부 객체로부터 '속성 값'을 감추는 특성으로, 직접적으로 변경되면 안 되는 변수에 대한 접근을 막는 것을 은닉화라고 한다.

🐤 실습 과제
  • 콘솔에 찍힐 b 값을 예상해보고, 어디에서 선언된 “b”가 몇번째 라인에서 호출한 console.log에 찍혔는지, 왜 그런지 설명해보세요.
    주석을 풀어보고 오류가 난다면 왜 오류가 나는 지 설명하고 오류를 수정해보세요.
    ```jsx
    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);
    ```

console이 찍히는 순서는 1, 1 101, 1이 된다. console.log(a,b)에서의 b는 '101'이 되고, 두번째 console.log(b)에서의 b는 1이 나오고 제일 첫번쨰의 1로 출력된다. 왜냐면 일단 hi 함수의 바깥에서 console을 찍어주었기 때문에 스코프 안의 변수b에는 접근이 불가했고, 첫번쨰로 찍힌 이유는 자바스크립트의 비동기적 특성으로 함수가 다 실행되기 전에 그 다음 식을 실행해주기 때문에 바깥의 console.log(b)가 제일 첫번째 1을 출력할 수 있었던 것이다. 그리고 주석처리 되어있는 console.log(a)는 hi 함수 바깥에 찍어주었는데 hi함수 바깥에는 a를 변수로 선언해준 값이 없다. 그래서 a를 찾을 수 없다는 에러가 뜨기 때문에 console.log(a)를 hi 함수 안으로 옮겨주면 된다. 그럼 console.log(a)는 1이 나온다. 그리고 맨 마지막의 console.log(b)는 맨 마지막의 1을 출력해준다.

0개의 댓글