오늘 공부한 내용 요약
( 모던 JavaScript 튜토리얼 학습 )
1e9 = 1 * 10의 9승
1.23e6 = 1.23 * 1000000
1e-3 = 1 / 1000 (=0.001)
1.23e-6 = 1.23 / 1000000 (=0.00000123)
alert( 0xff ); // 255
alert( 0xFF ); // 255 대·소문자를 가리지 않으므로 둘 다 같은 값을 나타낸다
2진수는 0b, 8진수는 0o를 사용
let a = 0b11111111; // 255의 2진수
let b = 0o377; // 255의 8진수
alert( a == b ); // true 진법은 다르지만, a와 b는 같은 수임
let num = 255;
alert( num.toString(16) ); // ff
alert( num.toString(2) ); // 11111111
base =16
-> 16진수. 색, 문자 인코딩 등을 표현할 때 사용.
숫자는 0부터 9, 10 이상의 수는 A부터 F를 사용
base =2
-> 2진수. 비트연산 디버깅에 주로 사용. 숫자는 0 또는 1
base =36
– >사용할 수 있는 base 중 최댓값. 0~9와 A~Z를 사용해 숫자를 표현
123456..toString(36) = (123456).toString(36)
123456.toString(36)는 점이 하나라 소수로 인식해 에러가 발생
예를 들어 소수점 2자리까지 남기려면
1. 100이나 100 이상의 10의 거듭제곱을 곱하고 원하는 내장함수 호출후 곱했던 수를 나눠줌
let num = 1.23456;
alert( Math.floor(num * 100) / 100 );
// 1.23456 -> 123.456 -> 123 -> 1.23
et num = 12.36;
alert( num.toFixed(1) ); // "12.4"
이때 반환값이 문자열이므로 num앞에 +나 Number()를 호출하면 숫자형으로 변환가능
1)
alert( 1e500 ); // Infinity
숫자가 너무 커지면 64비트 공간이 넘쳐 Infinty
2)
alert( 0.1 + 0.2 == 0.3 ); // false
위 같은 경우는 2진법에서 0.1같이 10으로 2의 거듭제곱이 아닌 값으로 나누게 되면 무한소수가 되버림.
해결을 위해 toFixed로 어림수를 만듬 (이때 toFixed는 문자열을 만듦에 유의)
let sum = 0.1 + 0.2;
alert( sum.toFixed(2) ); // 0.30
1) isNaN
alert( isNaN(NaN) ); // true
alert( isNaN("str") ); // true
이때 ===NaN으로 비교를 못하는 이유가 NaN은 자기자신도 포함하여 같지 않기 때문임 ex) alert( NaN === NaN ); // false
2) isFinite
NaN/Infinity/-Infinity가 아닌 일반 숫자인 경우 true를 반환함
alert( isFinite("15") ); // true
alert( isFinite("str") ); // false, NaN이기 때문입니다.
alert( isFinite(Infinity) ); // false, Infinity이기 때문입니다.
<주의>
빈 문자열이나 공백만 있는 문자열은 isFinite를 포함한 모든 숫자 관련 내장 함수에서 0으로 취급된다는 점에 유의하시기 바랍니다
피연산자가 숫자형이 아닌경우 형 변환은 실패함
alert( +"100px" ); // NaN
parseInt와 parseFloat 두 함수는 불가능할 때까지 문자열에서 숫자를 읽고 읽는 도중 오류가 발생하면 이미 수집된 숫자를 반환한다
parseInt는 정수, parseFloat는 부동 소수점 숫자를 반환한다
alert( parseInt('100px') ); // 100
alert( parseFloat('12.5em') ); // 12.5
alert( parseInt('12.3') ); // 12, 정수 부분만 반환됩니다.
alert( parseFloat('12.3.4') ); // 12.3, 두 번째 점에서 숫자 읽기를 멈춥니다.
읽을 수 있는 숫자가 없는경우 NaN을 반환
1) Math.max(a, b, c...) / Math.min(a, b, c...)
인수 중 최대/최솟값을 반환합니다.
2) Math.pow(n, power)
n을 power번 거듭제곱한 값을 반환합니다.
3)
alert( 1.35.toFixed(1) ); // 1.4 와 다르게
alert( 6.35.toFixed(1) ); // 6.3 인 이유는
-> 정밀도 손실이 일어났기 때문인데 1.35는 1.350000...이라 우연히 올림이 됨
alert( Math.round(6.35 * 10) / 10);
// 6.35 -> 63.5 -> 64(반올림됨) -> 6.4 처럼 실행해야 한다
let guestList = `손님:
* John
* Pete
* Mary
`;
처럼 문자열을 여러줄에 걸쳐 사용할 수 있게 해준다
let guestList = "손님:\n * John\n * Pete\n * Mary";
alert( 'I\'m the Walrus!' ); 와 같이 실행
이때 \는 역할을 마치면 사라지기 때문에 반환시키려면 \2개를 붙이면 됨
alert( `My\n`.length ); // 3
\n은 ‘특수 문자’ 하나로 취급되기 때문에 My\n의 길이는 3입니다.
let str = `Hello`;
// 첫 번째 글자
alert( str[0] ); // H
alert( str.charAt(0) ); // H
// 마지막 글자
alert( str[str.length - 1] ); // o
두 방식의 차이점은 접근하려는 위치에 글자가 없는 경우
[]는 undefined를, charAt은 빈 문자열을 반환합니다.
let str = 'Hi';
str = 'h' + str[1]; // 문자열 전체를 교체함
alert( str ); // hi
처럼 새로운 문자열을 만들면 됨
alert( 'Interface'.toUpperCase() ); // INTERFACE
alert( 'Interface'.toLowerCase() ); // interface
1) str.indexOf(substr, pos) 메서드를 이용하는 것입니다.
문자열 str의 pos에서부터 시작해, 부분 문자열 substr이 어디에 위치하는지를 찾아준다. 원하는 부분 문자열을 찾으면 위치를 반환하고 그렇지 않으면 -1을 반환합니다.
let str = 'Widget with id';
alert( str.indexOf('Widget') ); // 0, str은 'Widget'으로 시작함
alert( str.indexOf('widget') ); // -1, indexOf는 대·소문자를 따지므로 원하는 문자열을 찾지 못함
str.lastIndexOf(substr, position)는 문자열 끝에서부터 문자열을 찾는 메서드
if문의 조건식에 indexOf를 쓸 때 0이 반환될 경우 false로 간주할 수 있음
let str = "Widget with id";
if (str.indexOf("Widget") != -1) {
alert("찾았다!"); 정상 작동
위와 같이 -1과 비교
alert( ~0 ); // -1, -(0+1)과 같음
alert( ~-1 ); // 0, -(-1+1)과 같음
~n을 0으로 만드는 경우는 n == -1일 때가 유일하다
if (~str.indexOf(...)) 패턴의 코드를 만나면 '부분 문자열인지 확인’하는 코드
1)str.includes(substr, pos)
substr이 있는지에 따라 true나 false를 반환한다. 부분 문자열의 위치 정보는 필요하지 않고 포함 여부만 알고 싶을 때 적합한 메서드이다
2) startsWith, endsWith
-> 이름 그대로 문자열 str이 특정 문자열로 시작하는지(끝나는지) 확인함
1) str.slice(a,b)
-> str의 a부터 b전까지 반환(b는 미포함)
let str = "stringify";
alert( str.slice(0, 1) ); // 's'
alert( str.slice(2) ); // ringify 2번째 인수가 없으면 끝까지
alert( str.slice(-4, -1) ); // gif 음수면 끝에서부터
2) str.substring(a,b)
slice와 거의 유사한데 a가 b보다 커도 된다는 것과 음수를 허용하지 않는다는 차이점이 있다(음수는 0처리)
let str = "stringify";
alert( str.substring(2, 6) ); // "ring"
alert( str.substring(6, 2) ); // "ring"
-> 동일한 결과
alert( str.slice(2, 6) ); // "ring" (같음)
alert( str.slice(6, 2) ); // "" (빈 문자열)
-> 다른 결과
3) str.substr(a,b)
a부터 시작해 b개의 문자열을 반환
let str = "stringify";
alert( str.substr(2, 4) ); // ring
alert( str.substr(-4, 2) ); // gi 음수면 끝부터
모든 문자열은 UTF-16을 사용해 인코딩되는데, UTF-16에선 모든 글자가 숫자 형식의 코드와 매칭된다
1) str.codePointAt(pos)
pos에 위치한 글자의 코드를 반환합니다.
alert( "z".codePointAt(0) ); // 122
alert( "Z".codePointAt(0) ); // 90
2) String.fromCodePoint(code)
숫자 형식의 code에 대응하는 글자를 만들어줍니다.
alert( String.fromCodePoint(90) ); // Z
-소문자는 대문자보다 항상 크다 (소문자의 코드가 대문자의 코드보다 크다)
배열 선언 방법
1. let arr = new Array();
2. let arr = [];
let fruits = ["사과", "오렌지", "자두"];
fruits[2] = '배' -> ["사과", "오렌저", "배"로 바뀜
추가도 가능 / 배열의 자료형에 제약은 없음
1) 배열 끝에 변화를 주는 메서드
pop -> 배열 끝 요소를 제거하고, 제거한 요소를 반환합니다.
push -> 배열 끝에 요소를 추가한다
2) 배열 앞에 변화를 주는 메서드
shift -> 배열 앞 요소를 제거하고, 제거한 요소를 반환합니다.
unshift-> 배열 앞에 요소를 추가한다
(push와 unshilft는 동시에 여러개를 추가할 수 있다)
그러나 배열을 일반 객체처럼 다루면 배열을 다룰때만 적용되는 최적화 기법이 작동하지 않게됨
예시)
arr.test = 5 같이 숫자가 아닌 값을 프로퍼티 키로 사용하는 경우
arr[0]과 arr[1000]만 추가하고 그사이에 아무런 요소도 없는 경우
arr[1000], arr[999]같이 요소를 역순으로 채우는 경우
push와 pop은 빠르지만 shift와 unshift는 느립니다.
배열 끝에 작업을 하는 메서드는 다른 요소들을 이동시키는 등의 작업이 필요하지 않으므로 배열 앞을 바꿔주는 메서드보다 빠름
몰랐던 용어
UTF-16
-> 유니코드 인코딩 문자의 방식 중 하나로, 주로 사용되는 기본 다국어 평면에 속하는 문자들은 그대로 16비트 값으로 인코딩이 되고 그 이상의 문자는 특별히 정해진 방식으로 32비트로 인코딩이 된다.
공부사이트
위의 내용은 공부중 본인이 이해한 내용으로 몇몇 틀린 내용이 있을 수 있습니다.
회독중 발견시 수정하겠습니다