# 값
# 문자열과 배열의 차이
문자열 Immutable
배열 Mutable
str[0] ❌ str.charAt(0) ⭕️
대부분의 배열 메서드는 문자열에 쓸 수 없지만,
문자열
에 대해 불변 배열 메서드
는 빌려
쓸 수 있다.
불변 배열 메서드
- 원본 배열을 바꾸지 않고 새로운 배열을 만들어 반환시키는 메서드.
const a = 'foo';
const c = Array.prototype.join.call(a, '-');
const d = Array.prototype.map.call(a, v => v.toUpperCase() + '.').join('');
2
3
# 소수점의 비교
결과 값은 0.30000000000000004 에 가깝다.
0.1 + 0.2 === 0.3 // false
컴퓨터의 소수점 표현을 생각하면 되겠군요
Number.EPSILON
자바스크립트에서 표현할 수 있는 가장 작은 수.
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 == 0.3); // false!!!
function isEqual(a, b){
// Math.abs는 절댓값을 반환한다.
// 즉 a와 b의 차이가 JavaScript에서 표현할 수 있는 가장 작은 수인 Number.EPSILON 보다 작으면 같은 수로 인정할 수 있다.
return Math.abs(a - b) < Number.EPSILON;
}
console.log(isEqual(0.1 + 0.2, 0.3));
2
3
4
5
6
7
8
# divide by zero 연산
에러 ❌ 무한대값 ⭕️
var a = 1 / 0; // Infinity
var b = -1 / 0; // -Infinity
2
# -0 +0
-0은 이동 방향을 따질때 유용하게 쓰임
let a = 0 / -3; // -0
let b = 0 * -3; // -0
2
🔗 컴퓨터 값의 표현은 IEEE 754 standard 를 준수합니다.
IEEE 754는 부동 소수점 숫자에 대한 -0, +0 을 허용한다.
# 1 / +0 = +∞, 1 / -0 = -∞
반대쪽 끝에 있는 값.
- 반대 방향을 가리키는 0 크기의 벡터
- ∞ 의 결과가 다르기 때문에 +0 -0 은 혼란을 일으킨다.
# IEEE 754 에 두개의 0 이 존재하는 이유.
숫자값의 부호를 나타내는 bit 존재.
Consequently if the magnitude of a number goes to zero without its sign changing then it becomes a -0. (?)
0 값은 실제로 부호가있는 0 (+0) 이다.
let a = -0;
a; // -0
let b = +0;
b; // 0
2
3
4
5
0이 아닌 피연산자를 더하거나 뺀 결과로 음의 0을 만들 수 없다 -3 + 3 = 3 – 3 = +0
// Addition and Subtraction
3 - 3 // 0
-3 + 3 // 0
// Addition of zero values
-0 + -0; // -0
-0 - 0; // -0
0 - 0; // 0
0 + -0; // 0
// Multiplication
3 * 0 // 0
3 * -0 // -0
// Division
3 / Infinity // 0
-3 / Infinity // -0
// Modulus
6 % 2 // 0
-6 % 2 // -0
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
toString 을 호출 하면 항상 결과가 "0"이됩니다. 정보가 손실 된다. 반대로 parseInt 및 parseFloat 는 음수 0 값을 구문 분석합니다.
let a = '-0';
JSON.stringify(a); // "0"
a.toString(); // '0'
JSON.parse(a) // -0
parseInt('-0', 10); // -0
parseFloat('-0', 10); // -0
2
3
4
5
6
7
# +0과 -0의 구별
-0 === 0; // true
-0..toString(); // '0'
0..toString(); // '0'
-0 < 0; // false
0 < -0; // false
Object.is(0, -0); //false
2
3
4
5
6
7
8
function isNegativeZero(value) {
value = +value; // cast to number
if(value) {
return false;
}
let infValue = 1 / value;
return infValue < 0;
}
isNegativeZero(0); // false
isNegativeZero(-0); // true
isNegativeZero('-0'); // true
2
3
4
5
6
7
8
9
10
11
12
이 모든 것을 아는 것은 무엇입니까?
예를 들어 기계 학습을 수행하고 분기를 위해 양수 값과 음수 값을 구분해야하는 경우를 예로들 수 있습니다. -0 결과가 양의 0으로 강제 변환되면; 그러면 까다로운 분기 버그가 발생할 수 있습니다.
또 다른 사용 시나리오는 컴파일러를 작성하고 코드를 최적화하려는 사람들을위한 것입니다. 결과는 이제 x의 값에 따라 달라 지므로 예를 들어 x * 0이되는 식은 최적화 할 수 없습니다. 이러한 표현식을 최적화하고 0으로 바꾸면 버그가 발생합니다. (???????)
# IEEE 사양
Math.round(-0.4); // -0
Math.round(0.4); // 0
Math.sqrt(-0); // -0
Math.sqrt(0); // 0
1 / -Infinity; // -0
1 / Infinity; // 0
2
3
4
5
6
7
8
제곱근 규칙은 내가 이상하게 생각하는 규칙입니다. 규격은“squaresquare (–0)이 –0 인 것을 제외하고 모든 유효한 squareRoot는 양의 부호를 가져야한다”고 말합니다. 궁금하다면 IEEE 754가 대부분의 언어에서 0.1 + 0.2! = 0.3 과 같은 이유입니다. 그러나 그것은 또 다른 이야기입니다.
# 내가 이해한 요약
IEEE 754 에 의하면 컴퓨터에는 '부동 소수점 숫자에 대한 -0, +0 을 허용한다' 부동 소수점 숫자에 대한... 의 맥락의 이해가 어렵다. 일단 확실히 +0, -0이 구별되는 값이 존재한다는 것을 본문을 통해 알 수 있다. 그러나 프로그래밍에서 이해할 수 없는 일들이 일어나도, 예측하기 힘든 버그도 만들 수 있다는 점.
아직 수련이 더 필요한 이해이다.
# Object.is 🔗
# NaN의 판별 🔗
NaN은 다른 모든 값과 비교(==, !=, ===, !==)했을 때 같지 않으며, 다른 NaN과도 같지 않습니다.
NaN의 판별은 Number.isNaN() 또는 isNaN()을 사용하면 제일 분명하게 수행할 수 있습니다.
NaN === NaN; // false
Number.NaN === NaN; // false
isNaN(NaN); // true
isNaN(Number.NaN); // true
2
3
4
오로지 NaN만이 자기자신과 비교했을 때 같지 않음을 이용할 수도 있습니다
function valueIsNaN(v) { return v !== v; }
valueIsNaN(1); // false
valueIsNaN(NaN); // true
valueIsNaN(Number.NaN); // true
2
3
4
그러나 isNaN()과 Number.isNaN()의 차이를 주의해야 합니다.
isNaN은 현재 값이 NaN 이거나, 숫자로 변환했을 때 NaN이 되면 참을 반환하지만,
Number.isNaN은 현재 값이 NaN 이어야만 참을 반환합니다.
isNaN('hello world'); // true
Number.isNaN('hello world'); // false
2
# undefined 와 undeclared 🔗
Q.
undefined 는 접근 가능한 스코프에 변수가 선언 되었으나 아직 값이 할당되어 있지 않음을 의미 한다.
반면 undeclared 는 접근 가능한 스코프에 변수가 선언 조차 되지 않음을 의미 한다.
두 가지 경우 모두 다 typeof 연산 결과는 undefined 값을 가지지만 분명 다른 의미를 가진다.
2
3
# undefined 미정의 변수
렉시컬 환경 레코드에 프로퍼티가 등록되었으나, 할당이 되지 않은 상태. 타입이 정의되지 않음.
let test;
typeof test; // undefined
console.log(test); // undefined
2
3
# undeclared 미선언 변수
렉시컬 환경 레코드에 프로퍼티가 등록되지 않은 상태
console.log(test2); // Uncaught ReferenceError: test2 is not defined
console.log(typeof test2); // 이것의 타입을 살펴보면 undefined
2
- typeof : undeclared 인 경우에도 undefined 를 뱉어 브라우저가 오류 처리를 하지 않도록 한다.