가수면

Javascript 기본 개념 추가 (1) 본문

웹 개발/웹 개발

Javascript 기본 개념 추가 (1)

니비앙 2022. 11. 18. 15:26

 JavaScript의 자료형과 JavaScript만의 특성

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

JavaScript의 변수는 모든 타입의 값으로 할당(및 재할당)이 가능하다.

let a = 10 // a가 숫자
a = '10' // a가 이제 문자열
a = true // a가 이제 불리언

 

 JavaScript 형변환

자료 -> 숫자

  • 연산자를 사용
  • number("자료")

자료 -> 문자열

  • string("자료")
  • '숫자 + 문자 = 문자' 이용    ex) 273 + ""(빈 문자열)

자료 -> 불

  • 논리 부정 연산자(!)를 두 번 사용   ex) !!273 -> true
  • boolean("자료") -> true

-false가 되는 예외 5가지-

>Boolean(0)
false

# NaN = Not a Number
>Boolean(NaN)
false

>Boolean("")
false

>Boolean(null)
false

>let 변수
undefined
>Boolean(변수)
false

 

 == vs ===

==       값이 같은지만을 확인한다.

===     타입까지 같은지 확인한다.

예)

let a = 1
let b = "1"

a == b => true
a === b  => false

 

 느슨한 타입(loosely typed)의 동적(dynamic) 언어의 문제점과 보완할 수 있는 방법

자바스크립트라는 녀석이 워낙 자유롭다 보니 실행 도중에 예상치 못한 타입 에러가 발생하기도 한다.

동적 타입 언어는 런타임 시밖에 확인할 수 없기 때문에, 코드가 길고 복잡해질 경우 타입 에러를 찾기가 어렵다.

그러한 에러를 방지하는 방법으로 TypeScipt나 Flow 등을 사용할 수 있다.

 

 

 undefined와 null의 차이

undefined : 변수를 선언하고 값을 할당하지 않은 상태

null : 변수를 선언하고 빈 값을 할당한 상태 (빈 객체)

 

즉, undefined는 자료형이 없는 상태다.
따라서 typeof를 통해 자료형을 확인해보면 null은 object로, undefined는 undefined가 출력되는 것을 확인할 수 있다.

 

 


 JavaScript 객체와 불변성

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

기본형 타입(Primitive Type) 참조형 타입(Reference Type)
숫자(Number)
문자열(String)
불리언(Boolean)
null
undefined
심볼(Symbol)
객체(Object)
배열(Array)
함수(Function)
날짜(Date)
정규표현식(RegExp)
Map
WeakMap
Set
WeakSet

 

 불변 객체를 만드는 방법

const는 파괴적 처리를 통해 heap에 저장된 값을 바꿀 수 있다. (객체 재할당 불가능, 객체 속성 변경 가능)

※ 블로그 내 'JavaScript 반복문' 게시글의 '기본 자료형과 복합 자료형' 참조

 

Object.freeze() 메소드는 stack에 저장된 값을 바꿀 수 있다. (객체 재할당 가능, 객체 속성 변경 불가능)

 

따라서 둘을 섞어 쓰면 된다. (Object.freeze()의 접근법을 맞게 설명한 건지 모르겠다.)

const test = {
    'name' : 'jung'
};

Object.freeze(test);

 

얕은 복사와 깊은 복사 (※ 블로그 내 'JavaScript 반복문' 게시글의 '기본 자료형과 복합 자료형' 참조)

얕은 복사

객체를 대입시키는 경우 레퍼런스에 의한 할당이 이루어지므로 둘은 같은 주소를 가지게 된다.

const obj1 = { a: 1, b: 2};
const obj2 = obj1;
console.log( obj1 === obj2 );

true

obj2.a = 100;
console.log( obj1.a );

100

깊은 복사

주소 자체를 복사하므로, 한 쪽을 바꿨을 때 다른 한쪽에 영향이 미치지 않는다.

 

 


호이스팅과 TDZ

 스코프, 호이스팅, TDZ

 

스코프

구역 (변수에 접근할 수 있는 범위)

함수 스코프

블록 스코프 - 블록 {}이 생성될 때마다 새로운 스코프가 형성되는 것을 의미

 

호이스팅

자바스크립트 엔진은 코드를 실행하기 전에 코드를 구분하는 과정을 거쳐 모든 선언(var, let, const, function, class)을 스코프에 등록한다. 그렇게 실행을 하게 되면 위에서 아래로 각 스코프에 들어있는 코드를 차례대로 실행하게 되는데, 호이스팅은 순서대로 읽혀야할 선언을 최상단으로 끌어올려 먼저 실행시키는 것을 말한다. (var와 선언적 함수가 이에 해당된다.)

 

예) 원래는 변수 지정 전에 호출을 부르는 경우, 'Uncaught ReferenceError: OO is not defined'와 같은 오류를 띄워야 정상이다. 하지만 호이스팅이 발생하면 아래와 같은 일이 벌어진다.

console.log(name);
var name = '강승현';

undefined

값을 할당하지 않았다는 undefined가 떴을 뿐, 오류가 뜨지는 않았다.

그 이유는, 눈에 보이진 않지만 실제로는 아래처럼 자바스크립트가 읽어버렸기 때문이다.

var name;
console.log(name);
name = '이범규';

undefined

# 결국 호이스팅 발생으로 값은 놔두고 var만 끌려 올라가 값을 정의하지 않은 것이 되어버렸다.

이러니 var와 선언적 함수가 잘 안 쓰이게 되지.

 

TDZ

자바스크립트 내부에 존재하는 호이스팅 안전지대.

이 안에 변수가 들어가게 되면 접근이 불가능해지기에 호이스팅이 발생하지 않는다. (let, const, class도 내부적으로는 모두 호이스팅이 발생되지만, TDZ에 들어가기에 TDZ에 들어가지 않는 var와 선언적 함수만 호이스팅 영향을 받게 됨.)

 

 

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

선언적 함수 (함수 선언문) - 호이스팅이 발생함.

익명 함수 (함수 표현식) - 위에서 아래로 순서대로 읽힘. 호이스팅 발생 X (따라서 호출이 익명 함수보다 위에 있으면 오류 발생)

 

호출이 선언적 함수보다 위에 있을 때에도 선언적 함수는 호이스팅이 일어나 호출의 위로 올려져 우선 실행 된다. (호출이 함수보다 위에 있는데도 정상 작동 된다는 얘기.)

선언적 함수가 익명 함수보다 아래 있어도 호이스팅이 발생해 선언적 함수가 우선 실행된다.

익명 함수는 순서대로 읽힌다.

예)

작성 코드

함수()

함수 = function() {
	console.log('익명 함수입니다.')
}

function 함수() {
	console.log("선언적 함수입니다.")
}

함수()

# 결과는 선언적 함수에 호이스팅이 발생해 맨 윗 줄에 있던 '함수()'를 밀어내고 맨 위를 지가 차지하게 됨

선언적 함수입니다.
익명 함수입니다.

눈에 안 보이지만 실제 실행 순서

function 함수() {
	console.log("선언적 함수입니다.")
}

함수()

함수 = function() {
	console.log('익명 함수입니다.')
}

함수()

선언적 함수입니다.
익명 함수입니다.

 

.html파일은 위에서 아래로 내려가며 각 태그별로 읽고 실행하게 되는데, 그럴 일은 거의 없지만 다른 <script> 에서 호출했는데도 선언적 함수가 실행될 수도 있다.

예)

<script>
	함수()
    
	function 함수() {
		console.log("선언적 함수입니다.")
	}
</script>
<script>
	함수()
    
	함수 = function() {
		console.log('익명 함수입니다.')
	}
</script>

선언적 함수입니다.
선언적 함수입니다.

# 아마 형식에 관대한 자바스크립트가 오류를 내지 않기 위해 이런 결과를 도출해낸 듯하다?

 

let, const, var, function

var: 변수 재선언 가능, 함수 스코프, 호이스팅 대상

let: 변수 재선언 불가능, 변수 재할당 가능, 블록 스코프, 호이스팅 대상이지만 적용X

const: 변수 재선언 불가능, 변수 재할당 불가능, 블록 스코프, 호이스팅 대상이지만 적용X, 

 

 

 실행 컨텍스트와 콜 스택

실행 컨텍스트 (Execution context)

코드를 실행하기 위해 필요한 환경.

앞의 '호이스팅'에서 자바스크립트 엔진은 코드를 실행하기 전에 코드를 구분하는 과정을 거친다고 했었는데, 그렇게 구분하는 과정을 거친 뒤 자바스크립트 엔진은 처음 코드를 실행하면서 Global Execution Context라는 것을 생성하게 된다.

이후에는 구분을 거친 함수들을 호출할 때 마다 그 함수를 위한 Execution context를 생성하게 된다.

 

콜 스택

콜 스택은 그렇게 생성된 실행 컨텍스트를 저장하는 자료 구조다.

step 1. 엔진이 처음 script를 실행할 때, Global Execution Context를 생성하고 이를 Stack에 push한다

step 2. .그 후 엔진이 함수를 호출할 때 마다 그 함수(가령 function a ()라고 해보자)를 위한 Execution Context를 생성하고 Stack에 추가로 push한다.

step 3. 함수가 실행되어 종료되면 stack에서 제거한다.

step 4. 다음 함수 b를 위한 Execution Context를 생성한다.

.

.

.

이러한 구조를 콜 스택이라고 한다.

 

 

스코프 체인, 변수 은닉화

스코프 체인

각각의 스코프가 어떻게 연결(chain)되고 있는지 보여주는 것.

만약 콜 스택 과정에서 함수 a를 위한 Execution Context를 생성했는데 그 a 안에 또 다른 함수 b가 들어있다면 어떻게 될까?

위 그림과 같이 Execution Context를 하나 더 불러와 push하게 될 것이다. 하지만 엔진은 스코프가 각각 나뉘어져 있음에도 b함수를 계산하고  a함수 스코프로 거슬러 올라가 적용시킬 수 있다.

이게 스코프 체인이다.

 

변수 은닉화 (즉시 호출 함수)

변수를 함수 안에 선언함으로써 그 함수에서만 변수명이 먹히도록 하는 것.

협업하다보면 상수나 변수 명이 겹칠 수 있기에 함수를 짜고 그 내부에서만 사용할 수 있도록 코드를 짜는 것이 좋다.

 

예)

      (function () {
        const a =10
      }) ()

      (function () {
        const a =20
      }) ()

 

 

'웹 개발 > 웹 개발' 카테고리의 다른 글

Javascript 객체  (0) 2022.11.22
Javascript 간단 퀴즈  (0) 2022.11.18
Javascript 기본 개념 추가 (2)  (0) 2022.11.18
JavaScript 함수 (2)  (0) 2022.11.12
JavaScript 함수 (1)  (0) 2022.11.11
Comments