본문 바로가기
Development

[20.12.24] YDKJSY - Surveying JS

by igy95 2024. 1. 7.

Each File is a Program

요즘에는 거의 모든 웹 사이트가 수많은 JS file 로 이루어져 있다. 하나의 거대한 프로그램은 서로 다른 작은 프로그램들이 모여 만들어진 집합체일 뿐, 초기의 js 파일은 각각 '모듈'이라는 단위로 작은 프로그램에 대한 기능을 하나씩 맡고 있는데, 그러한 이유는 주로 빠른 에러 핸들링을 통한 유지 보수의 용이함에 있으며 작은 프로그램을 큰 프로그램으로 합치기 위해서 별도의 빌드 툴을 사용한다고 한다.

 

다수의 js 파일들이 하나의 프로그램처럼 동작하기 위해서는 전역 단계에서 state 를 공유를 할 수 있어야 하는데, 이를 구현하기 위한 방법은 여러가지가 있다. 그 중의 하나로 따로 state 클래스를 만들어 각각의 모듈에서 담당하는 이벤트 핸들러나 데이터의 변환을 공유하는 방법이 있다. ES6부터 JS는 모듈을 지원하게 되었는데 HTML에서 <script type='module'> 태그나 import 를 선언하게 되면 해당 파일은 모듈로써 동작한다고 보면 된다.

Value Type Determination

typeof 42;                  // "number"
typeof "abc";               // "string"
typeof true;                // "boolean"
typeof undefined;           // "undefined"
typeof null;                // "object"
typeof { "a": 1 };          // "object"
typeof [1,2,3];             // "object"
typeof function hello(){};  // "function"

 

위 예시를 보면 typeof 연산자는 각각의 value type을 명시해주는데, 자세히 보면 null의 타입은 object인 것을 확인할 수 있다. 이 부분은 버그라고 하는데, 다수의 코드에 영향을 미칠 수 있어 고치기는 힘들다고 한다.

Equal: value

JS 안에는 두 값의 동등 여부를 비교하는 연산자가 두 개가 있다.

 

  • == : 동등 연산자 (느슨한 비교)
  • === : 일치 연산자 (엄격한 비교)

흔히, ===== 차이가 단순한 값의 비교와 값 + 타입 비교라는 의견이 있지만 그것은 사실이 아니라고 한다. 타입 비교는 == 에서도 일어난다. 하지만 둘의 차이점은 형 변환 에 있다. == 는 두 값을 비교할 때 타입이 다르면 형 변환 처리를 한 후에 비교하지만, === 는 그것을 허용하지 않는다. === 을 사용함에도 불구하고, 자신과 비교했을 때 false 를 리턴하는 타입이 있는데 대표적으로 NaN이 있다. 때문에 해당 값에 대해 동등 비교를 원할 때는 Number.isNaN(..) 을 사용하도록 하자.

Equal: reference

[ 1, 2, 3 ] === [ 1, 2, 3 ];    // false
{ a: 42 } === { a: 42 }         // false
(x => x * 2) === (x => x * 2)   // false

 

위의 예시를 보면 두 object 안에 존재하는 값들이 일치하기 때문에 얼핏 true 를 리턴할 것 같지만, === 가 비교하고자 하는 건 안의 값들이 아닌 그것을 감싸는 object 이다. JS 에서 모든 object 타입은 각각의 레퍼런스 주소를 가지고 있으니 '두 개체가 동등한가' 에 대한 물음은 false 가 맞다고 볼 수 있다.

 

❗ 부등호 같은 관계 연산자 같은 경우 형 변환에 대한 적절한 방지책이 따로 존재하지 않는다. 때문에 타입이 string 이더라도 안의 값이 number 를 연상하게 하는 경우, 비교 단계에서 형 변환 처리 후 값을 비교하게 되기 때문에 이 부분에 대해서는 따로 숙지하면서 올바르게 코딩을 할 수 있는 쪽으로 하는 게 좋은 접근 방식인 것 같다.

Value vs Reference ?

JS에는 primitive type 라는 6가지 데이터 타입이 존재한다. number, string, boolean, null, undefined, symbol 이 있는데 이 값들은 작기 때문에 각각 정해진 데이터만큼 메모리를 차지하게 된다. 하지만 object 타입은 그 안의 들어갈 값들이 가변적이고, 비대해질 우려가 있기 때문에 해당 객체에 들어갈 값들을 묶어 놓은 임의의 주소를 참조하게 되는데 이것을 reference 라고 한다. 위에서 얘기한 동등 비교에서도 차이가 있듯, valuereference 에서는 몇 가지 유의해야 할 부분이 있다.

var a = 2;
var aCopy = a;
aCopy = 3;
console.log(a, aCopy); // 2 3

var arr = [1, 2, 3];
var arrCopy = arr;
arrCopy[2] = 4;
console.log (arr, arrCopy); //[1, 2, 4] [1, 2, 4]

 

해당 예시처럼 value 를 할당받은 변수를 다른 변수에 할당하게 될 때는 해당 변수 안에 있는 값의 사본을 전달하게 되어 다른 변수의 값을 바꾸게 되더라도 원래의 변수에는 아무런 변화가 없다. 하지만 reference 를 할당받은 변수를 다른 변수에 할당하게 되면 참조한 주소값을 공유 한다는 의미를 내포하고 있기 때문에 하나의 변수를 이용해 그 안의 값에 변화를 주게 되면, 그것은 곧 다른 변수에도 영향을 미치기 때문에 하나의 변수를 복사하거나 그 안의 값을 운용하게 될 때는 이러한 사항을 잘 알고있도록 하자.