Ch2. 값
2.1 배열
하나의 배열에 여러 타입의 값을 담을 수 있다.
- 배열에 delete 연산자...?!
배열을 변태같이 사용하는 방법
case 1: 구멍난 배열
var a = [];
a[0] = 1;
a[2] = [3];
a[1]; // undefined
a.length; // 3
중간 index를 생략하면 length는 건너뛰고 중간은 undefined가 된다.
case 2: 문자열 index
var a = [];
a[0] = 1;
a["footbar"] = 2;
a.length; // 1
a.["footbar"]; // 2
a.footbar; // 2
case 3: string 타입 숫자 index
var a = [];
a["13"] = 42;
a.length; // 14
크롬 기준으로 empty * 13 이라고 나오는걸 보니 좀 신기하긴 하다.
map 을 돌려도 저렇게 나온다.
값이 뭐지?
근데.... 굳이 알아야 할까요?
저런건 그냥 쓰지 말자...
해로운 버그다...
유사 배열
진짜 이상한짓 많이 하는듯 한데...
유사 배열이란 아래의 경우가 있다.
var aaa = function (a, b, c) {
console.log(arguments);
console.log(typeof arguments);
}
aaa(1, 2, 3);
argument 는 object이지만 동시에 array이기도 하다.
따라서 여기있는 array를 빼올때 indexOf, concat, forEach 등의 내장 함수를 통해 가져온다.
최근엔 Array.from 을 사용하여 유사배열을 배열로 만든다.
이거 왜 쓰는건지 모르겠다... argument는 뭐지?
왜 나오는건지 모르겠넹;;
2.2 문자열
다른 언어에선 문자열은 문자의 배열로 구현되어져있다.
Javascript 에선 많이 비슷하긴 하지만 둘은 서로 다르다.
- 문자열 index로 접근할때 charAt과 [index] 의 차이점
var a = 'foo';
var b = ['f', 'o', 'o'];
a.length; // 3
b.length; // 3
a.concat("bar"); // 'foobar'
a.concat("bar"); // ['f', 'o', 'o', 'b', 'a', 'r']
a; // 'foo'
b; // ['f', 'o', 'o']
가장 큰 차이점은 문자열은 immutable이고, 배열은 mutable 이다.
a[1] = "O";
b[1] = "O";
a; // 'foo'
b; // ['f', 'O', 'o']
immutable값은 내용을 바로 변경하지 않고, 새로운 문자열을 생성한 후 반환한다.
Immutable에 대해서 좀더 자세히 알아보자.
문자열 reverse 하기
문자열은 배열이 아니기때문에 reverse나 join, map과 같은 함수는 사용할 수 없다.
따라서 다음과 같이 Array에 있는 메서드를 가져다 사용한다.
var c = Array.prototype.join.call(a, '-');
var d = Array.prototype.map.call(a, function (v){
return v.toUpperCase() + '.';
});
c; // "f-o-o"
d; // "F.O.O"
근데 유니코드가 섞여있는 경우 문자열의 join은 불가능하다는데, 왜그런거지?
마티아스 바이넨의 에스레베르를 사용하라고 하던데...ㄷㄷ?
⇒ 유니코드는 2바이트라서...!!
2.3 숫자
javascript 에선 정수와 부동소수점 모두 number 타입 하나로 처리한다.
Number 객체로 박싱할 수 있어서 Number.prototype 메소드에 접근이 가능하다.
부동 소숫점 이슈
모든 숫자를 부동 소숫점을 사용하기 때문에 고질적인 문제가 발생한다.
0.1 + 0.2 === 0.3 // false
0.1 + 0.2 는 0.30000000....4 에 가깝다.
해결 방법은 Number.EPSILON을 사용하는것이다.
function numbersCloseEnoughToEqual(a, b) {
return Math.abs(a - b) < Number.EPSILON;
}
최대 허용 오차를 사용하여 구분이 가능하다.
안전한 정수 범위
부동 소숫점때문에 Number.MAX_VALUE 보다 작은 수준에서 안정성을 보장한다.
표현한 값과 실제 값이 정확하게 일치한다고 보장되는 범위를 안전한 정수 범위라 한다.
그치만 9000조를 넘기때문에... ㅇㅇ;;
DB id가 64비드 숫자라면 Big Number
와 같은 유틸 라이브러리나 문자열로 처리하는게 일반적이다.
정수인지 확인
Number.isInteger() 를 통해서 정수인지 확인이 가능하다.
안전한 정수인지 여부는 Number.isSafeInteger를 활용하면 된다.
32bit?
이건 언제 사용하는지 한번 찾아보자...ㄷㄷ
뭔지 모르겠넹;; 왜왱?
2.4 특수 값
값이 아닌 값
undefined, null
undefined는 키워드지만 값을 삽입할 수 있다?! strict mode 에선 동작하지 않는다.
undefined = 3;
console.log(undefined); // 3
undefined
...
void 연산자
void는 어떤 값이던 undefined로 만들어버리는 연산자이다.
도대체 왜쓰는지 모르겠다...
<a href="javascrit: void(0)">???</a>
특수 숫자
NaN ⇒ Not a Number
하지만 typeof NaN은 "number"이다.
NaN === NaN // false
나 블리츠크랭크 아니다?!.png
2.5 값 vs 레퍼런스
- 자바스크립트엔 포인터 개념이 없음
- 어떤 변수가 다른 변수를 참조할 수 없음
- 값의 타입에 따라 값-복사 또는 레퍼런스-복사 가 일어난다.
값-복사
- null
- undefined
- string
- number
- boolean
- symbol
레퍼런스-복사
- object
- array
- function
- 합성 값
- 기타 나머지...
함수에서의 복사
함수에서도 마찬가지로 값의 타입에 의해 발생된다.
function foo(x) {
x.push(4);
x; // [1, 2, 3, 4]
}
var a = [1, 2, 3];
foo(a);
a; // [1, 2, 3, 4]
위의 코드에선 배열이기 때문에 레퍼런스-복사가 발생한다.
내장 함수를 통한 Boxing 데이터 넘길때
function foo(x) {
x = x + 1;
x; // 3
}
var a = 2;
var b = new Number(a);
foo(b);
b; // 2
⇒ 내부의 스칼라 원시 값이 불변이다.
Number + 1 이 이루어질때 Number는 자동으로 unboxing 되어 2 라는 값이 나오고
2 + 1 인 새로운 원시 데이터로 계산되어 값-복사가 이루어진다.
2.6 정리하기
'개발 > Javascript' 카테고리의 다른 글
[You don't know JS] Part1 - 5장. 문법 (0) | 2020.09.06 |
---|---|
[You don't know JS] Part1 - 4장. 강제변환 (0) | 2020.09.06 |
[You don't know JS] Part1 - 3장. 네이티브 (0) | 2020.09.06 |
[You don't know JS] Part1 - 1장. 타입 (0) | 2020.08.23 |
[You don't know JS] 스터디 시작 (0) | 2020.08.23 |