실수를 컴퓨터상에서 근사하여 표현할 때 소수점 위치를 고정하지 않고 그 위치를 나타내는 수를 따로 적는 것 입니다.
유효숫자를 나타내는 가수(假數)와 소수점의 위치를 풀이하는 지수(指數)로 나누어 표현한다.
지수(Exponent)는 소수점 자리수를 계산을 위한 것, 가수부(Mantissa)는 실제 값을 나태내는 부분이라고 이해하면 된다.
Number(7).toString(2); // "111"
비트 값은 0 아니면 1입니다. 2^n승 값을 더해 값을 구합니다. 예를 들면 정수 7은 0비트 부터 1, 1, 1로 1(2^0) + 2(2^1) + 4 = 7 입니다.
console.log(Number.MAX_SAFE_INTEGER); console.log(Math.pow(2,53)-1); console.log(Number.MIN_SAFE_INTEGER); console.log(-(Math.pow(2,53)-1)); // 9007199254740991 // 9007199254740991 // -9007199254740991 // -9007199254740991
미세한 값 차이 형태
const total = 0.1 + 0.2; console.log(total); console.log(total === 0.3); // 0.30000000000000004 // false
⇒ 0.3이 나올것 같지만 실제로 출력해보면 0.30000000000000004이 출력하기에 false판정입니다. 이는 JS가 부동 소수점 처리를 하기 때문(IEEE-754 준수)인데 이처럼 미세한 값 차이로 일치하지 않을 때 EPSILONE을 사용합니다.
미세한 값 차이를 같은 값으로 간주
const value = Math.abs(0.1 + 0.2 - 0.3); console.log(value < Number.EPSILON); // true
⇒ 값 차이가 EPSILON 보다 작은 경우 이 값을 무시하고, 근사값으로 간주합니다.
0/0으로 NaN가 되는 것을 방지
console.log(0 / 0); const value = 0 / (0 + Number.EPSILON); console.log(value); // NAN // 0
⇒ 0 / 0은 NaN이지만 0 + Number.EPSILON처럼 작은 값을 더해 나누면 0이되서 그 뒤 연산을 이어서 할 수 있습니다.
const value = 0B111; console.log(value); // 7
const value = 0o111; console.log(value); // 73
Number.isNaN(value)
주어진 값의 유형이 Number이고 NaN이면 true 아니면 false를 반환합니다.글로벌 오브젝트의 isNaN()와 비교했을 때 형변환, 데이터 타입 확인에서 차이가 있습니다.
console.log(Number.isNaN("ABC"), isNaN("DEF")); //false true ---(1) console.log(Number.isNaN(NaN), isNaN(NaN)); //true true ---(2) console.log(Number.isNaN(0 / 0), isNaN(0 / 0)); //true true ---(3) console.log(Number.isNaN("100"), isNaN("200")); //false false ---(4)
- NaN체크 방법
- NaN === NaN 결과가 false이므로 사용 불가
- isNaN(), 글로벌 오브젝트
- Number.isNaN()
- Object.is(NaN,NaN):true
Number.isInteger(value)
파라미터 값으로 받은 value가 정수인지 확인하려는 값으로 반환 타입은 Boolean입니다. 파라미터 값이 정수이면 true아니면 false를 반환합니다.
console.log(Number.isInteger(0)); console.log(Number.isInteger(1.0)); console.log(Number.isInteger(1.01)); // true // true // false
⇒ 1.0은 정수이고 1.01은 소수입니다.
console.log(Number.isInteger("12")); console.log(Number.isInteger(true)); // false // false
⇒ "12"는 숫자로 변환하면 Number가 맞지만 Number.isIteger()는 치환하지 않고 값 그대로 판단하기에 false가 반환됩니다.
Number.isSafeInteger(testValue)
파라미터인 testValue가 안전한 정수인지 확인하며 Boolean타입으로 반환합니다. 파라미터 값이 safe 정수, 즉 -(2의 53승 -1) ~ (2의 53승 -1) 사이이면 true, 아니면 false를 반환합니다.
const isSafe = Number.isSafeInteger; console.log(isSafe(7.0)); console.log(isSafe(Number.MAX_SAFE_INTEGER)); console.log(isSafe(Number.MIN_SAFE_INTEGER)); // true // true // true
⇒ 7.0은 정수이며, 값 범위에 속하므로 true
const isSafe = Number.isSafeInteger; console.log(isSafe(7.1)); console.log(isSafe("100")); console.log(isSafe(NaN)); console.log(isSafe(Infinity)); // false // false // false // false
⇒ 7.1은 정수가 아닙니다.
⇒ 값을 Number로 변환하여 체크하지 않습니다.
isFinite(testValue)
파라미터 값이 유한한지 확인하는 함수로 유한 값이면true 아니면 false를 반환합니다. 데이터 타입을 변환하여 판단하는 글로벌 오브젝트의 isFinite()와 결과가 다릅니다.
const num = Number.isFinite, global = isFinite; console.log(num(100), global(200)); console.log(num("70"), global("80")); console.log(num(true), global(true)); console.log(num(NaN), global(NaN)); console.log(num(undefined), global(undefined)); // true true // false true // false true // false false // false false
함수는 오브젝트에 속해야 하므로 Number와 관련된 것은 Number 오브젝트의 함수를 사용하고 글로벌 오브젝트의 함수는 글로벌 사용이 목적입니다.
유니코드는 U+0031형태입니다.
코드 포인트(code point)
110만개 정도가 표현 가능합니다.
평면(plane)
이스케이프 시퀀스(Escape Sequence)
const escape = "\x31\x32\x33"; console.log(escape); console.log("\\"); // 123 // \
유니코드 이스케이프 시퀀스(Unicode Escape Sequence)
const escape = "\x31\x32\x33"; console.log(escape); const unicode = "\u0034\u0035\u0036"; console.log(unicode); // 123 // 456
const unicode = "\u0034\u0035\u0036"; console.log(unicode); const es6 = "\u{34}\u{35}\u{36}"; console.log(es6); console.log("\u{1f418}"); // 456 // 456 // 🐘
const pair = "\uD83D\uDC18"; console.log(pair); // 🐘
String.fromCodePoint(num1[, ...[, numN]])
유니코드의 코드 포인트에 해당하는 문자를 반환하는 함수
const point = String.fromCodePoint; console.log(point(49, 50, 51)); console.log(point(44032, 44033)); console.log(point(0x31, 0x32, 0x33)); console.log(point(0x1F418)); // 123 // 가각 // 123 // 🐘
⇒ 문자를 연결하여 반환
⇒ 49, 50, 51은 코드 포인트를 10진수로 작성한 형태
⇒ 0x31, 0x32, 0x33은 코드 포인트를 16진수로 작성한 형태
console.log(String.fromCharCode(0x1f418)); console.log(String.fromCharCode(0xD83D, 0xDC18)); // // 🐘
⇒ 0x1f418(아스트랄 코드포인트)를 지원하지 않아 제대로 출력이 안됩니다.
⇒ Surrogate pair로 작성
String.prototype.codePointAt()
대상 문자열에서 파라미터에 작성한 인덱스 번째 문자를 유니코드 코드포인트로 변환하여 반환합니다.
const result = "가나다".codePointAt(2); console.log(result); console.log(typeof result); console.log("가나다".codePointAt(3)); console.log(String.fromCodePoint(result)); // 45796 // number // undefined // 다
Q. String.fromCodePoint(50)와 "123".codePointAt(1)의 형태가 다른데 그 이유는 무엇일까요?
String.fromCodePoint(50)은 직접 호출하는 함수의 형태로 다수의 파라미터를 작성합니다
"123".codePointAt(1)은 String.prototype.codePointAt() 호출, prototype을 사용한 메소드 형태로 파라미터에 인덱스 하나만 작성합니다.
codePointAt()은 값을 구하는 대상이 있지만, fromCodePoint()은 대상이 없습니다.
이는 유니코드와 문자열을 서로 인코딩과 디코딩을 하기위한 목적으로 설계되었다고 생각하였습니다.
fromCodePoint()은 String 빌트인에서 직접 호출하여 사용하는 함수 형태입니다. 이는 파라미터에 작성한 유니코드 값을 문자열로 변환하는 것에 초점이 맞추어져 있으며, 즉 디코딩의 목적으로 사용하라는 의미 같습니다.
fromCodePoint( )은 다수의 파라미터를 작성합니다. [50, 60, 70].fromCodePoint() 형태로 작성하면, 빌트인 String 오브젝트가 아니라 빌트인 Array 오브젝트에 fromCodePoint()가 있어야 하는데, 이것은 문자열 처리 시맨틱이 Array 처리 시맨틱으로 바뀌게 됩니다.
이를 방지하기 위해 "506070".fromCodePoint() 형태로 작성하면 값을 구분할 수 없습니다.
codePointAt()은 생성한 String 오브젝트에 대하여 프로토 타입에 내장된 메소드를 사용하는 형태입니다. 생성한 오브젝트에 초점이 맞추어져 있으며, 즉 인코딩의 목적으로 사용하라는 의미 같습니다.
String.prototype.normalize()
대상 문자열을 파라미터에 지정한 유니코드 정규화 형식으로 변환 및 반환하는 함수입니다.
파라미터: 정규화 형식. 디폴트: NFC
반환: 변환된 문자열
문자열을 지정한 유니코드 정규화 형식으로 변환
console.log("ㄱ".codePointAt().toString(16)); console.log("ㅏ".codePointAt().toString(16)); console.log("\u{3131}\u{314F}"); const point = "\u{3131}\u{314F}"; console.log(point.normalize("NFC")); console.log(point.normalize("NFD")); console.log(point.normalize("NFKD")); console.log(point.normalize("NFKC")); // 3131 // 314f // ㄱㅏ // ㄱㅏ // 가 // 가
⇒ ㄱ과 ㅏ 의 코드 포인트를 16진수로 구합니다.
⇒ ㄱ과 ㅏ의 코드 포인트를 연결하여 작성합니다.
⇒ "ㄱㅏ"로 표시되지만 제대로 연결이 되진 않았습니다.
⇒ NFC와 NFD는 단지 연결하여 어색하지만 NFKD와 NFKC는 모아 쓴형태로 표시됩니다.
유니코드 정규화 형식
String.prototype.startsWith()
대상 문자열이 첫 번째 파라미터의 문자열로 시작하면 true 아니면 false를 반환합니다.
const target = "ABC"; console.log(target.startsWith("AB")); console.log(target.startsWith("BC")); console.log(/^AB/.test(target)); // true // false // undefined
⇒ "AB"로 시작하기에 true를 반환하고 "BC"는 있지만 시작점이 아니기에 false를 반환합니다.
const target = "ABC"; console.log(target.startsWith("BC", 1)); // true
⇒ BC는 중간에 있지만 시작 인덱스가 1이므로 true를 반환합니다.
String.prototype.endsWith()
대상 문자열이 첫 번째 파라미터의 문자열로 끝나면 true, 아니면 false를 반환합니다.
파라미터: 비교 문자열, 사용 문자열 길이(default: 전체)
반환: 끝나면 true, 아니면 false
대상 문자열이 첫 파라미터의 문자열로 끝나는지 여부 확인
endsWith()는 정규 표현식 사용이 불가능
const target = "ABC"; console.log(target.endsWith("BC")); console.log(target.endsWith("AB")); console.log(/BC$/.test(target); // true // false // true
두 번째 파라미터는 선택이며 사용할 문자열 길이를 지정합니다.
const target = "ABC"; console.log(target.endsWith("AB", 2)); // true
String.prototype.repeat()
대상 문자열을 파라미터에 작성한 수만큼 복제, 연결하여 반환합니다
대상 문자열을 작성한 수만큼 복제, 연결
const target = "ABC"; console.log(target.repeat(3)); console.log(target.repeat(0)); console.log(target.repeat()); console.log(target.repeat(2.7)); // ABCABCABC // "" // "" // ABCABC
⇒ repeat(3): ABC를 3번 복제하고 연결하여 반환합니다.
⇒ 파라미터를 작성하지 않거나 0을 작성하면 빈 문자열을 반환합니다.
⇒ 2.7에서 0.7을 무시하고 2를 사용합니다.
대상 문자열에 첫 번째 파라미터의 문자열이 있으면 true없으면 false를 반환.
파라미터: 존재 여부 비교 문자열, 비교 시작 인덱스(default: 0)
반환: 존재하면 true, 아니면 false
대상 문자열에 첫 파라미터의 문자열 존재 여부
첫 번째 파라미터가 숫자면 문자열로 변환하여 체크합니다.
const target = "123"; console.log(target.includes("1")); console.log(target.includes(12)); console.log(target.includes("13")); // true // true // false
두 번째 파라미터를 작성하면 비교 시작 인덱스
includes()는 정규 표현식 사용이 불가능
const target = "ABC"; console.log(target.includes("A", 1)); try{ result = target.includes(/^A/); } catch(e){ console.log("정규표현식 사용 불가"); } // false // 정규표현식 사용 불가
String.prototype.padStart()
첫 번째 파라미터 값 만큼 길이를 늘리고 늘어난 끝에 대상 문자열을 설정한 후, 앞의 남은 공간에 두 번째 파라미터를 채웁니다.
파라미터: 늘릴 길이 값, 설정할 값(Optional)
반환: 길이를 늘리고 문자열을 채운 결과
두 번째 파라미터에 채울 문자열 작성
console.log("ABC".padStart(10, "123")); console.log("ABC".padStart(6, "123456")); console.log("ABCDE".padStart(3, "123")); console.log("ABC".padStart(6).length); // 1231231ABC // 123ABC // ABCDE // 6
String.prototype.padEnd()
첫 번째 파라미터 값만큼 길이를 늘리고 늘어난 앞에 대상 문자열을 설정한 후, 뒤의 남은 공간에 두 번째 파라미터를 채웁니다.
파라미터: 늘릴 길이 값, 설정할 값(Optional)
반환: 길이를 늘리고 문자열을 채운 결과
두 번째 파라미터에 채울 문자열 작성
console.log("ABC".padEnd(10, "123")); console.log("ABC".padEnd(6, "123456")); console.log("ABCDE".padEnd(3, "123")); console.log("ABC".padEnd(6).length); // ABC1231231 // ABC123 // ABCDE // 6
String.prototype.trimStart()
문자열 앞의 공백 삭제
const value = " 123"; console.log(value.length); console.log(value.trimStart().length); const split = "a, b, c".split(","); for(let value of split) { console.log(`${value}, ${value.length}`); console.log(value.trimStart().length); }; // 5 // 3 // a, 1 // 1 // b, 2 // 1 // c, 2 // 1
String.prototype.trimEnd()
문자열 끝의 공백 삭제
const value = "123 "; console.log(value.length); console.log(value.trimStart().length); // 5 // 3