오늘서핑(4.3~5.6)

gwahyun·2021년 11월 15일
0

오늘서핑

목록 보기
3/3

4.2 식별자

메모리 상에 존재하는 어떠한 값을 구별해서 식별할 수 있는 고유한 이름.
식별자와 값이 저장되어있는 메모리 주소는 매핑되어있고, 이 매핑정보도 저장되어야 한다.

식별자는 값이 아니라 메모리 주소를 기억하고 있다.
어디까지나 주소를 통한 접근임을 참고.

4.3 변수선언

  1. 값을 저장하기 위한 메모리 공간을 확보하고
  2. 확보된 메모리 공간의 주소와 변수 이름을 연결해
  3. 값을 저장할 수 있게 준비하는 것

javascript에는 3가지 선언 키워드(자바스크립트 엔진이 수행할 동작을 규정한 명령어. 엔진이 키워드를 만나면 수행해야 할 약속된 동작을 실행한다.)가 있다.

  • var
  • let
  • const

ES6에서 let과 const를 도입한 이유는 var의 단점을 보완하기 위해서고, var의 단점을 이해하려면 스코프등의 핵심기능을 알아야 한다.

var score;

변수를 선언했지만, 값은 할당하지 않은 상태다.
그러나 자바스크립트 엔진에 의해 undifined값이 암묵적으로 할당되어 초기화 된다.

엔진은 변수 선언을 2단계에 걸쳐 수행한다.

  1. 선언 : 변수 이름을 등록하고 엔진에 변수의 존재를 알림
  2. 초기화 : 값을 저장하기 위한 메모리 공간 확보

var 키워드로 성언하면 선언단계와 초기화 단계가 동시에 진행되기 때문에, 2에서 암묵적으로 undefind를 할당해 초기화된다.

초기화 하지 않으면 확보된 메모리 공간에 다른 어플리케이션의 쓰레기 값이 남아있을 수 있다. 확보후 할당하지 않고 바로 참조시 쓰레기 값이 나올 수 있는데, 자바스크립트는 암묵적으로 초기화함으로써 이에 안전하다.

모든 식별자를 사용하려면 선언이 필요하다. 선언하지 않은 식별자 접근시

  • Reference Error 참조에러
    식별자를 통해 참조하려고 했으나 자바스크립트 엔진이 식별자를 찾지 못했다는 뜻

변수 이름은 어디 등록되는가?

  • 모든 식별자는 실행 컨텍스트 execution context 에 등록된다.
  • 실행 컨텍스트란 자바스크립트 엔진이 소스코드를 평가, 실행, 결과를 관리하는 영역이다.
  • 실행 컨텍스트를 통해 엔진은 식별자와 스코프를 관리한다.
  • 식별자는 키/밸류 객체로 등록된다.

4.4 변수 선언의 실행시점과 호이스팅

  • 변수선언이 런타임이 아니라 이전 단계에서 먼저 실행된다
  • 자바스크립트 엔진은 코드를 순차적으로 실행하기 앞서 소스코드 평가과정을 거치며 실행을 준비한다
  • 변수 선언이 어디 있든 다른 코드보다 먼저 실행하므로 소스코드 어디에서나 참조가 가능하다

변수 선언문이 코드 선두로 끌어 올려진 것처럼 동작하는 자바스크립트의 특징을 호이스팅 이라고 한다

4.5 값의 할당

할당 연산자(=)는 우변의 값을 좌변의 변수에 할당한다.

//선언 
var score;
//할당
score = 80;
//선언과 동시에 초기화
var score = 80;

세 방식 모두 같게 동작한다. 선언과 동시에 초기화를 하여도, 선언과 할당은 2개의 문으로 나뉘어 실행된다.

변수 선언 - 런타임 이전
값의 할당 - 런타임 (순차적으로 소스코드가 실행될때)

  • 이전값 undefined가 저장되어있던 메모리 공간을 지우고 새로운 값을 할당하는게 아니라, 새로운 메모리 공간을 확보하고 그곳에 할당값을 저장한다 (왜??왜왜왜왜)

4.6 값의 재할당

이미 값이 할당되어있는 변수에 새로운 값을 또다시 할당하는 것.

//선언과 동시에 초기화
var score = 80;
//값의 재할당
score = 90;

var 키워드는 값의 재할당이 가능하다.
애초에 선언과 동시에 초기화시 할당된 undefined를 우리가 재할당하는 셈이다.
재할당은 변수에 저장된 값을 다른 값으로 변경하는 것이고, 재할당이 불가하다면 변수가 아니라 상수 constant 이다. (한번 정해지면 변하지 않는다, 즉 단 한번 할당이 가능하다)

역시 이전 값이 저장된 메모리 공간을 지우고 재할당 값을 저장하는 게 아니라 새로운 메모리 공간을 확보한 뒤 저장하므로

  • 이전의 undefined와 80은 이제 어떠한 식별자도 갖고있지 않다
  • == 더 이상 불필요하다
  • 가비지 콜렉터에서 자동 해제된다. (단 언제 해제될지는 모른다)

가비지 콜렉터란?

애플리케이션이 할당한 메모리 공간을 주기적으로 검사하며 더이상 사용되지 않는 메모리 == 어떤 식별자도 참조하지 않는 메모리 공간을 해제한다.

4.7 식별자 네이밍 규칙

ok 문자, 언더스코어(_), 달러($)
no 특수문자, 숫자로 시작, 예약어 사용

  • 자바스크립트는 대소문자를 구별하므로 네이밍시 참고

네이밍 컨벤션

하나 이상의 영단어로 구성된 식별자를 만들때 사용하는 명명규칙

var firstName //카멜 케이스 : 변수, 함수 명명시 사용
var first_name//스네이크 케이스
var FirstName //파스칼 케이스 : 생성자 함수, 클래스 이름에 사용

5.1 값

값 values는 표현식 expression이 평가 evaluate되어 생성된 결과.

  • 모든 값 value에는 데이터 타입이 있고, 메모리에 2진수(bit의 나열)로 저장된다.
  • 평가란 식을 해석해서 값을 참조하거나 생성하는 것을 말한다

메모리에 저장된 2진수를 데이터 타입에 따라 해석하는 것.
ex) 0100 001은 숫자로 해석할때 65, 문자로 해석할때 A가 된다.

var sum=10+20;

해당 변수 sum에 할당되는 것은 10+20이 아니라 평가된 결과값 30이다. 즉 할당 이전에 평가되어 값을 생성해야 한다.

5.2 리터럴

값을 생성하는 가장 기본적인 방법.
사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 표기법이다 notation

자바스크립트 엔진은 코드가 실행되는 시점, 즉 런타임에 리터럴을 평가해 값을 생성한다.

5.3 표현식

표현식 expression : 값으로 평가될 수 있는 문 statement

값으로 평가될 수 있다는 것은

  • 새로운 값을 생성하거나
  • 기존 값을 참조한다는 것

리터럴=값. 리터럴도 표현식이다

  • 50+50이 평가되어 값 100이 되므로 표현식이다.
  • 참조된 변수식별자는 값을 생성하지는 않으나 값이 평가되므로 표현식이다.

표현식==값 은 동치된다.

  • 표현식은 값처럼 사용할 수 있다
  • 문법적으로 값이 위치한 자리에 표현식도 위치할 수 있다
  • 표현식은 다른 표현식의 일부가 되어 새로운 값을 만들 수 있다.

5.4 문

문 statement 프로그램을 구성하는 기본 단위이자 최소실행 단위

  • 문의 집합이 프로그램이며
  • 작성하고 순서에 맞게 나열하는 것이 프로그래밍이다.

문은 여러 토큰 token으로 구성된다.

  • 토큰: 문법적으로 더 이상 나눌 수 없는 코드의 기본요소
var sum = 1 + 2 ;
//키워드 식별자 연산자 리터럴 세미콜론

문은 명령문이라고도 부른다

  • 컴퓨터에 내리는 명령어
  • 선언문, 할당문, 조건문, 반복문 등등.

5.5 세미콜론

(;)세미콜론은 문의 종료를 나타낸다.
코드블록은 언제나 문의 종룔르 의미하는 자체종결성이 있다

자바스크립트 엔진이 소스코드를 해석할때 예측된 구문의 끝에 자동으로 세미콜론을 붙여주는 기능이 있다. ASI automatic semicolon insertion

그러나 개발자의 예상과 다르게 세미콜론이 삽입되어 작동되는 경우가 있으므로, 대체적으로 세미콜론 사용이 권장되고 있다.

5.6 표현식인 문과 표현식이 아닌 문

표현식은 문의 일부일수도, 그 자체로 문일수도 있다

var x; //선언문은 표현식이 아니므로 값으로 평가 불가능하다.
x=1+2; //표현식이면서 문이다.

표현식인지 아닌지 구별하는 법

  • 변수에 할당해본다.
  • 표현식==값이므로 할당이 가능하며
  • 표현식이 아닐경우 에러가 발생한다.

완료값 completion value

크롬 개발자 도구에서 표현식이 아닌 문을 실행하면 undefined출력. (완료값)
표현식의 평과결과가 아니기 때문에 변수에 할당하거나 참조할 수 없다.
표현식인 문을 실행하면 콘솔창은 언제나 평가된 값을 반환한다.


오늘서핑

선언과 호이스팅과 undefined

java에서는 변수 선언시 자료형을 명시해주어야 한다. 그래서 변수선언이 필요한 만큼의(적정량의) 메모리를 확보하는 역할을 하고 있다고 알고 있었는데...

  • javascript는 선언시 자료형을 해석해 적정량의 메모리를 확보할것이 아니면서 왜 호이스팅을 하는건지 궁금해졌다.

  • 그리고 만약 undefined로 초기화한 변수들이 런타임에 할당될때 가용 메모리를 초과해버린다면?

  • 그러고보니 undefined로 얼마만큼의 메모리를 확보해놓는거지?

Size of undefined and null: stack overflow

  • Q. null이 더 큰가요 undefined가 더 큰가요.
  • A. 당신이 사용중인 엔진에 따라 다르겠죠.

null과 undefined 성능과 효율에 대한 답변이 이어졌다.

null은 어쨌든 용량을 차지하고,
undefined는 명시적 선언시에만 차지하며, 직접 해제(삭제)해줘야한다
가비지콜렉터, 브라우저, 엔진, 메모리의 영향을 많이 받는다.
(그러니 차지하는 용량차이가 궁금하다면 콘솔에서 힙영역을 직접 확인해보라는 조언이 있다.)

우선 MDN의 호이스팅 정의는 이러하다

JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다. 반면 let과 const로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.
호이스팅을 설명할 땐 주로 "변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는" 것으로 말하곤 합니다. 따라서 변수를 정의하는 코드보다 사용하는 코드가 앞서 등장할 수 있습니다. 다만 선언과 초기화를 함께 수행하는 경우, 선언 코드까지 실행해야 변수가 초기화된 상태가 됨을 주의하세요.

그래요 호이스팅이 뭔지는 알겠어요, 그런데 호이스팅하면 뭐가 좋은지가 궁금하단 말이예요 (울기 직전) 호이스팅을 왜하죠? 이점이 뭐죠? 왜 호이스팅하죠!!!

Main advantage of hoisting in Javascript : stack overflow

여기서 단서를 얻었다. 고차함수를 사용할때 호이스팅 되는 부분에서, 즉 가독성 측면에서 이점이 있는듯 했다. (...) 고차함수를 써보면 호이스팅의 장점을 언젠가 알게 되려나.

그리고

TDZ을 모른 채 자바스크립트 변수를 사용하지 말라 :TOAST

JavaScript의 let과 const, 그리고 TDZ :블로그

let, const도 호이스팅 되지만 TDZ로 인해 방어되고 있다는것. var, let, const로 선언할때 v8 엔진이 어떻게 분기처리하는지 v8 내부 코드를 보여주셔서 이해에 큰 도움이 된 글이다.

앨리스의 토끼굴에서 가까스로 기어나온 기분. TDZ는 나중에 따로 정리하면 좋을듯 하다.

헝가리안 케이스

헝가리안 표기법 설명 및 예제: 블로그

처음보는 유형의 네이밍 규칙이어서 메모해뒀다.
헝가리 사람이 만들어서 헝가리안 케이스(...)
접두어로 (소문자)자료형을 포함시키는 명명규칙이다

  • 변수명을 보면 타입을 알수 있어 편리하지만
  • 변수 타입을 바꿀때 변수명도 모두 바꿔줘야하고
  • 요즘 IDE는 직관적인 UI로 타입을 보여주므로

연식이 오래된 프로그램이 아니면 쓰지 않는다고.


어쩔수 없이 CS에서 막히는 것 같다. 메모리는 왜 그렇게 동작하는걸까, 어떻게 메모리를 운용하는것이 효율적이라고 사람들이 생각했을까...

오늘은 자바스크립트의 메모리 운용에 대한, 미래의 숙제를 남겨두는 날.
하지만 오늘 서핑 역시 재미있고 무척 의미있었다. 이미 검색해서 본 글도 의문을 가지고 다시보니 새롭다.

profile
에메랄드 바다의 웹서퍼

0개의 댓글