자바스크립트(javascript) - new 생성자로 사용하지 말아야 하는 이유
▶ String 문자열
💻 why?
var str_1 = new String('JS');
console.log(str_1);
var str_2 = 'JS';
console.log(str_2);
이렇게 네이티브 함수에는 new 생성자로 사용하면 왜 안되는지 위 예제로 확인을 해보자.
두 개의 변수에 각각 하나는 new 생성자를 사용해서 문자열을 담았고,
또 하나의 변수에는 그냥 문자열만 담았다.
첫 번째 변수 str_1을 console.log 출력해보면 String이라는 무언가가 나오는데 이걸 열어보면
객체처럼 [[Prototype]] 이란것을 가지고 있으며, [[PrimitiveValue]]라는 것도 가지고 있다.
즉, 이 의미는 String 인건 맞는데 객체라는 것이다.
그래서 다시 설명하자면
str_1 변수는 String 인건 맞지만 타입은 객체(Object) 이며, JS라는 문자열을 담고 있다.
이렇게 표현하는게 맞을 것 같다. 그럼 하나씩 확인해 보자.
console.log(typeof str_1); // "object"
console.log(str_1 instanceof String); // true
타입을 확인 해 보면 object라고 나온다.
그리고 str_1 을 String의 인스턴스가 맞다고 나온다.
즉, str_1 변수는 문자열 JS 라는 원시 데이터를 가지고 있는 String의 객체라는 뜻이다.
근데 왜 이렇게 사용 하면 안 되나?
물론, 무조건 사용하면 안 된다라는 의미는 아니지만
평상시 개발을 할 때 우린 아래와 같은 구문을 작성을 해야 한다라면...?
if(typeof str_1 === 'string'){
}
우리가 원하는 답을 얻지 못할 것이다.
분명 String 은 맞는데 왜 저 if 구문은 안되지? 라며 혼동을 가져다 주기 때문에
이렇게 네이티브 함수를 사용할 땐 그냥 문자열을 넣어서 사용을 하는 게 바람직하다.
그럼 이제 str_2 변수를 확인해보자.
console.log(str_2); // JS
console.log(typeof str_2); // string
console.log(str_2 instanceof String); // false
console.log로 출력을 해보면 str_2는 단순 문자열만 들어가 있는 문자열 변수이며,
타입도 string이며, 인스턴스를 가지고 있지도 않다.
즉, 순수한 문자열만 담고 있는 변수이다.
이제 여기서 나는 자바스크립트를 [[Prototype]]을 심도 깊이 있게 안다라고 하는 사람들이 이런 질문을 할 것이다.
그렇다면 str_2 변수는 그냥 문자열만 담고 있는 변수인데 아무런 메서드나 속성이 없는 이 str_2 변수에
console.log(str_2.length); // 2
console.log(str_2.toLowerCase()); // js
console.log(str_2.indexOf('J') !== -1); // true
length, toLowerCase, indexOf 등등 우리가 자주 사용하는 이것을 어떻게 사용이 가능하냐?
이러한 것들을 사용하려면 객체여야 하지 않느냐?
라는 질문을 할 건데 고맙게도 자바스크립트는 문자열에 대해 자동적으로 저러한 메서드 및 속성을 사용할 수 있게 만들어주기 때문에 가능하다.
만약 지금 이 부분이 이해가 안 되면 자바스크립트의 프로토타입에 대해서
이해를 해야 지금 이 내용을 이해할 것이다.
암튼 설명하다 이 내용까지 와버렸지만 여기서 얘기하고 것은 이렇게 string 문자열만 담아서
사용하는 변수를 이용할 땐 new String() 이렇게 사용하지 말고 그냥 문자열만 담아서 사용을 하자.
그래야 개발할 때 그나마 신경 덜 쓰고 혼동을 줄 일 수 있다.
이와 같은 이유로 Number 도 new Number() 이렇게 사용하지 말고, 그냥 숫자만 넣어서 사용을 하자.
▶ Boolean 부울 값
💻 why?
이 부울 형태도 Number 나, String에서 알아봤던 이유 + 이상한?
결과를 초래할 수 있어서 이 Boolean에 대해서 왜 new Boolean(true);
이런 식으로 사용하면 안 되는지 이유를 알아보자.
var BOOL = new Boolean(false);
if(!BOOL){
console.log("Ok"); // 어떤 결과가 나올까?
}
위 코드를 실행해보면 위 if문 안에 있는 console.log 가 출력이 될까?
어찌 대부분은 저 console.log의 OK 가 출력이 될 거라 생각을 한다.
하지만 실행해보면 경악을 금치 못한다.
console.log는 출력이 안된다. 그 이유는 아까도 말했듯이....
지금 저 변수 BOOL은 Boolean의 원시 값인 true / false 값만 들어가 있는 게 아니라 객체이기 때문에
BOOL 변수 자체가 존재하는 것만으로도 항상 참이다 즉, true 인 것이다.
그래서 저 if구문은 통과하질 못 하는 것이다.
BOOL 자체는 지금 객체이고 원시 데이터 값은 false를 가지고 있는 것이지 BOOL 자체가
false라는 의미가 아니라는 소리이다.
그렇다면 지금 저렇게 new 생성자를 사용해서 if문을 통과하게 구현하려면 어떻게 해야 하는가?
당연히 BOOL의 원시 데이터 값을 찾아서 비교 구문을 만들면 된다.
if(!BOOL.valueOf()){
console.log("Ok");
}
이렇게 사용을 하면 console.log가 출력을 할 것이다.
이 처럼 BOOL의 객체에 valueOf() 라는 메서드를 이용해서 원시 데이터 값을 가져와야 한다.
엄청 불편하지 않은가? 그래서 자바스크립트에선
var BOOL = true;
// 또는
var BOOL = false;
이렇게 사용하는 게 정신건강에 이롭다.
▶ Array 배열
💻 why?
이 배열에서도 new Array()를 이용해서 사용하면 어떤 혼동을 줄 수 있는지 알아보자.
var arr_1 = new Array(1,2,3);
console.log(arr_1); // [1,2,3]
var arr_A = [1,2,3];
console.log(arr_A); // [1,2,3]
new Array() 를 이용해서 1,2,3의 값을 넣고,
[]를 이용해서 1,2,3의 값을 넣은 것은
그냥 배열의 원소의 값이 1,2,3 들어가지 있는게 동일하다.
그냥 우리가 상식적으로 생각한 데로 맞다.
그런데 이러한 경우는 얘기가 달라진다.
var arr_1 = new Array(3);
console.log(arr_1); // 결과는??
console.log(arr_1.length); // 3
var arr_A = [3];
console.log(arr_A);// [3]
console.log(arr_A.length); // 1
위 와 같은 경우는 우리가 생각하는 일반적인 결과를 얻을 수가 없다.
arr_1은 결과는 비어있는 3개의 원소의 자리가 있는 배열을 만들라는 의미이다.
그래서 두 배열 전부 length를 찍어보면 arr_1의 length는 3이며, arr_A의 length는 1이다.
이렇듯 배열도 new 생성자를 이용해서 사용하지 말자 혼란의 여지를 충분히 줄 수 있으며 실수하기가 쉬워진다.
배열도 리터럴 방법인 var arr_A = []; 이런 방식으로 사용을 하자.
'web 언어 > HTML5 & CSS & Javascript' 카테고리의 다른 글
JS - 형 변환에 대하여 - (2) (0) | 2022.04.15 |
---|---|
JS - 형 변환에 대하여 - (1) (0) | 2022.04.14 |
JS - Number 타입에 대해 알아보자 - (5) (0) | 2022.04.08 |
JS - Number 타입에 대해 알아보자 - (4) (0) | 2022.04.07 |
JS - Number 타입에 대해 알아보자 - (3) (0) | 2022.04.06 |