Post

(JS) 리터럴, 자료형, 반복문

JS에서 숫자 타입은 Number인데, 이건 소수점 타입이다.

parseInt()를 사용할 때는 항상 기수를 지정해 주는 것이 좋다. parseInt("08")로 쓰면 8진수로 인식해 결과가 0이다. 명시적 형변환은 String(), Number()를 사용하는데, 이보다는 parseInt(string), parseFloat(string) 이를 사용하는게 좋다. 16진수 등도 인식한다.

자료형

  • 어떤 수를 0으로 나눠도 문제가 발생하지 않는다.
  • JS는 null, undefined, NaN, 빈 문자열 '', 0, falsefalse로 본다. * 이 외의 값은 모두 참이다.
  • NaN은 자기 자신을 포함해서 어떤 값과도 같지 않다. 그래서 NaN인지 확인하려면 반드시 isNaN()을 사용해야한다.
  • 항상 ===!== 를 사용하는 편이 좋다.이는 변수 값 비교 시 auto casting을 비활성화 해 타입을 엄격하게 검사한다. NaN == falsetrue지만, NaN === falsefalse다. ==, !=를 사용해야 하는 경우 isFinite(), isNaN()또는 (foo), (!foo)로 변경해서 작성한다.

문자열

문자열은 유사 객체이며 immutable 이다. 일단 한 번 만들어지면 변경되지 않는다. str[0] = "b"; 같은 코드는 동작하지 않는다.

+연산자로 문자열 결합이 가능한데, ` number + char 결합에서 타입에러가 발생하지 않고 자동으로 형변환해서 처리해준다. + 연산은 문자열이 우선순위가 높아 숫자가 문자열로 변환된다. 일반적으로 substring()보다 slice()`를 사용하는 것이 좋다.

템플릿 문자열

아래처럼 ""가 아니라 backtick으로 묶으면 된다.

1
2
3
4
5
6
var body\_str = "body"
var head\_str = "head"
var panelFormatStr = `<div class=\"panel panel-primary\">
<div class=\"panel-heading\">${head\_str}</div>
<div class=\"panel-body\">${body\_str}</div>
</div>`

구조 분해 할당

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

1
const [a, b] = [1, 2];

배열

JS의 배열은 연속적인 공간에 메모리를 할당하는게 아니고 배열 첨자를 문자열로 변환해서 속성으로 만들기 때문에, 실제 배열이 아니라 배열같은 객체 다. 속성을 읽고, 갱신하는 작업은 일반 객체와 똑같이 처리된다. 그러나 객체는 Object.prototype을, 배열은 Array.prototype을 상속한다. 그래서 Array를 다룰 수 있는 메소드와 length 속성 등을 상속하게 된다. 그래서 배열이 필요한 순간에는 객체가 아니라 배열을 사용하는게 바람직하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
var arr = ['a', 'b', 'c'];  // 배열 리터럴
arr[3] = 'd';
arr.push('e');      //push pop은 index를 따로 구할 필요가 없어 편할 때가 있다.
arr.push('f');
arr.pop();        //a, b, c, d, e
arr.unshift('0'); //0, a, b, c, d, e     앞에 0 추가
arr.splice(2, 2); //0, a, d, e    삭제하면서 인덱스를 당긴다. 그래서 배열이 큰 경우 느릴 수 있다.
delete arr[2];    //0, a, , e    삭제하면서 인덱스를 당기지 않는다.
arr[5] = 'g';     //0, a, , e, , g     index를 건너 뛰고 바로 [5]에 넣을 수 있다.
// arr.length == 6


// typeof arr == object

typeof하면 object로 알려주기 때문에 is_array() 함수를 만들어 보완할 수 있다.

배열 초기화

이렇게 하면 절대 안됨!

1
2
const stars = new Array(30).fill(new Star());
// stars[0] == stars[1]이 된다. 같은 객체가 들어감.

new Array(30);은 실제로 30개의 element를 가진 배열이 만들어지는게 아니라, length:30만 가지고 있는 객체가 만들어진다. 이걸 30개의 element를 가진 배열로 만드려면 spread [...obj]또는 js Array.fill()을 사용한다. 그래서 그 다음에 map으로 초기화해주어야 의도한 대로 초기화 된다.

1
2
const stars1 = Array(30).fill().map(() => new Star());
const stars2 = [...Array(30)].map(() => new Star());

가장 빠르고 좋은건 from을 쓰는 것이다.

1
let sampleData = Array.from({length: 10}, (\_, id) => ({id}))
is_array()
1
2
3
4
5
6
7
8
9
var is\_array = function (value) {

return value &&

typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
}
sort(비교함수)

기본 sort()는 [4, 32, 12]를 [12, 32, 4]로 정렬한다. 제대로 사용하려면 비교함수를 지정해주어야 한다.

1
2
3
4
5
6
7
8
9
m.sort(function (a, b) {
if (a === b) {
return 0;
}
if (typeof a === typeof b) {
return a < b ? 1 : 1;
}
return typeof a < typeof b ? 1 : 1;
});

반복문

함수형을 쓸 수 있나 고민. while / do while / for / for in / for of을 지원하고 array의 method 형태로 forEach()도 지원한다. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of#Difference_between_for...of_and_for...in

JQuery의 each. 기본 forEach는 array에서만 사용 가능한 반면 이건 object에서도 사용 가능해서 이 방식이나 함수형이 제일 편한 듯.

1
$.each(object, function(index, item) {})
forEach
1
2
3
4
var numbers = [4, 9, 16, 25];
numbers.forEach(function (item, index) {
demoP.innerHTML = demoP.innerHTML + "index[" + index + "]: " + item + "<br>";
});
for in
  • for in은 프로토타입 체인의 속성을 포함한 객체의 모든 속성을 포함해 반복한다.
  • 그래서 프로토타입 체인 탐색이 필요하지 않은 일반적인 반복에서는 for in 사용을 피하고 그냥 함수형을 사용하는 것을 권장한다.
  • 브라우저에 따라 Array의 index 순서가 아니라 Array에 추가된 순서로 반환되는 경우가 있어 순서가 꼬인다.
  • 속도도 for보다 더 느리다.

for in을 사용할 필요가 있을 때는 보통 typeof와 함께 사용하게 되는 경우. 굳이 for in을 사용해야 하는 경우 다음과 같이 object.hasOwnProperty(variable) 메소드로 속성이 실제로 객체의 속성인지, 아니면 프로토타입 체인(prototype chain) 상에 있는 것인지를 확인하며 사용해야 한다.

1
2
3
4
5
for (key in obj) {
    if (obj.hasOwnProperty(key)) {
        console.log(key, obj[key])
    }
}
for of
  • 프로토타입 체인 상에 있는 iterable이면 제외
    1
    2
    3
    
    for (key of Object.keys(obj)) {
      console.log(key, obj[key])
    }
    
This post is licensed under CC BY 4.0 by the author.