#

# 문자열과 배열의 차이

문자열 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('');
1
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));
1
2
3
4
5
6
7
8

# divide by zero 연산

에러 ❌ 무한대값 ⭕️

var a = 1 / 0; // Infinity
var b = -1 / 0; // -Infinity
1
2

# -0 +0

-0은 이동 방향을 따질때 유용하게 쓰임

let a = 0 / -3; // -0
let b = 0 * -3; // -0
1
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
1
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
1
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
1
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
1
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
1
2
3
4
5
6
7
8
9
10
11
12

이 모든 것을 아는 것은 무엇입니까?

  1. 예를 들어 기계 학습을 수행하고 분기를 위해 양수 값과 음수 값을 구분해야하는 경우를 예로들 수 있습니다. -0 결과가 양의 0으로 강제 변환되면; 그러면 까다로운 분기 버그가 발생할 수 있습니다.

  2. 또 다른 사용 시나리오는 컴파일러를 작성하고 코드를 최적화하려는 사람들을위한 것입니다. 결과는 이제 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   
1
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
1
2
3
4

오로지 NaN만이 자기자신과 비교했을 때 같지 않음을 이용할 수도 있습니다

function valueIsNaN(v) { return v !== v; }
valueIsNaN(1);          // false
valueIsNaN(NaN);        // true
valueIsNaN(Number.NaN); // true
1
2
3
4

그러나 isNaN()과 Number.isNaN()의 차이를 주의해야 합니다.

isNaN은 현재 값이 NaN 이거나, 숫자로 변환했을 때 NaN이 되면 참을 반환하지만,

Number.isNaN은 현재 값이 NaN 이어야만 참을 반환합니다.

isNaN('hello world'); // true
Number.isNaN('hello world'); // false
1
2

# undefined 와 undeclared 🔗

Q.

undefined 는 접근 가능한 스코프에 변수가 선언 되었으나 아직 값이 할당되어 있지 않음을 의미 한다. 
반면 undeclared 는 접근 가능한 스코프에 변수가 선언 조차 되지 않음을 의미 한다. 
두 가지 경우 모두 다 typeof 연산 결과는 undefined 값을 가지지만 분명 다른 의미를 가진다.
1
2
3

# undefined 미정의 변수

렉시컬 환경 레코드에 프로퍼티가 등록되었으나, 할당이 되지 않은 상태. 타입이 정의되지 않음.

let test;
typeof test;        // undefined
console.log(test);  // undefined
1
2
3

# undeclared 미선언 변수

렉시컬 환경 레코드에 프로퍼티가 등록되지 않은 상태

console.log(test2);         // Uncaught ReferenceError: test2 is not defined
console.log(typeof test2);  // 이것의 타입을 살펴보면 undefined
1
2
  • typeof : undeclared 인 경우에도 undefined 를 뱉어 브라우저가 오류 처리를 하지 않도록 한다.