6일차 - 2022.03.06

안병욱·2022년 3월 6일
0

오늘 공부한 내용 요약

( 모던 JavaScript 튜토리얼 학습 )

1. 숫자형

1e9 =  1 * 10의 9승
1.23e6 = 1.23 * 1000000

1e-3 = 1 / 1000 (=0.001)

1.23e-6 = 1.23 / 1000000 (=0.00000123)
  • 16진수는 0x를 사용해 표현가능
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는 같은 수임


  • toString(base)
    base는 2에서 36까지 사용가능 / 기본값은 10
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)는 점이 하나라 소수로 인식해 에러가 발생



  • 어림수 구하기
  1. Math.floor
    소수점 첫째 자리에서 내림. 3.1은 3, -1.1은 -2가 됩니다.
  2. Math.ceil
    소수점 첫째 자리에서 올림. 3.1은 4, -1.1은 -1이 됩니다.
  3. Math.round
    소수점 첫째 자리에서 반올림. 3.1은 3, 3.6은 4, -1.1은 -1이 됩니다.
  4. Math.trunc (Internet Explorer에서는 지원하지 않음)
    소수부를 무시. 3.1은 3이 되고 -1.1은 -1이 됩니다.

예를 들어 소수점 2자리까지 남기려면
1. 100이나 100 이상의 10의 거듭제곱을 곱하고 원하는 내장함수 호출후 곱했던 수를 나눠줌

let num = 1.23456;

alert( Math.floor(num * 100) / 100 ); 
// 1.23456 -> 123.456 -> 123 -> 1.23
  1. toFixed(n) 활용 / 가장 가까운 값으로 올림이나 내림해줌
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

  • isNaN과 isFinite
    두 숫자형은 정상적인 숫자는 아니기에 특별한 함수 가 존재함

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으로 취급된다는 점에 유의하시기 바랍니다


  • parseInt와 parseFloat

피연산자가 숫자형이 아닌경우 형 변환은 실패함

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 처럼 실행해야 한다


2. 문자열

  • 백틱(`)은 ${}을 사용해 문자열 중간에 삽입하게 해줄 뿐 아니라
let guestList = `손님:
 * John
 * Pete
 * Mary
`;

처럼 문자열을 여러줄에 걸쳐 사용할 수 있게 해준다


  • 특수 기호
    모든 특수문자는 \로 시작함
  • 줄바꿈문자(\n)를 사용하면 '나 "로도 여러줄로 문자열을 만들 수 있다
let guestList = "손님:\n * John\n * Pete\n * Mary";

  • I'm the Walrus!를 반환시키려면 '가 문자열을 닫는것으로 생각하지않게
alert( 'I\'m the Walrus!' ); 와 같이 실행 

이때 \는 역할을 마치면 사라지기 때문에 반환시키려면 \2개를 붙이면 됨


  • 문자열의 길이
alert( `My\n`.length ); // 3
\n은 ‘특수 문자’ 하나로 취급되기 때문에 My\n의 길이는 3입니다.

  • 특정 문자에 접근하기
    대괄호를 이용하거나 str.charAt(pos)라는 메서드를 호출
    위치는 0부터 시작한다
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과 비교    

  • 비트 not 연산자 (~)
    피연산자를 32비트 정수로 바꾼 후 모든 비트를 반전한다
    따라서 n이 32비트 정수일 때 ~n은 -(n+1)이 됩니다.
alert( ~0 ); // -1, -(0+1)과 같음
alert( ~-1 ); // 0, -(-1+1)과 같음

~n을 0으로 만드는 경우는 n == -1일 때가 유일하다

if (~str.indexOf(...)) 패턴의 코드를 만나면 '부분 문자열인지 확인’하는 코드


  • includes, startsWith, endsWith

1)str.includes(substr, pos)
substr이 있는지에 따라 true나 false를 반환한다. 부분 문자열의 위치 정보는 필요하지 않고 포함 여부만 알고 싶을 때 적합한 메서드이다

2) startsWith, endsWith
-> 이름 그대로 문자열 str이 특정 문자열로 시작하는지(끝나는지) 확인함


  • 부분 문자열 추출 (slice를 주로 사용)

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

-소문자는 대문자보다 항상 크다 (소문자의 코드가 대문자의 코드보다 크다)


  • 그외
    str.trim() – 문자열 앞과 끝의 공백 문자를 다듬어 줍니다(제거함).
    str.repeat(n) – 문자열을 n번 반복합니다.

3. 배열

배열 선언 방법
1. let arr = new Array();
2. let arr = [];

let fruits = ["사과", "오렌지", "자두"];

fruits[2] = '배'        -> ["사과", "오렌저", "배"로 바뀜 

추가도 가능 / 배열의 자료형에 제약은 없음


  • pop·push와 shift·unshift

1) 배열 끝에 변화를 주는 메서드
pop -> 배열 끝 요소를 제거하고, 제거한 요소를 반환합니다.
push -> 배열 끝에 요소를 추가한다

2) 배열 앞에 변화를 주는 메서드
shift -> 배열 앞 요소를 제거하고, 제거한 요소를 반환합니다.
unshift-> 배열 앞에 요소를 추가한다

(push와 unshilft는 동시에 여러개를 추가할 수 있다)


  • 배열의 내부동작 원리
    배열은 자바스크립트의 원시 자료형이 아닌 객체형에 속하기 때문에 객체처럼 동작합니다.

그러나 배열을 일반 객체처럼 다루면 배열을 다룰때만 적용되는 최적화 기법이 작동하지 않게됨
예시)

arr.test = 5 같이 숫자가 아닌 값을 프로퍼티 키로 사용하는 경우
arr[0]과 arr[1000]만 추가하고 그사이에 아무런 요소도 없는 경우
arr[1000], arr[999]같이 요소를 역순으로 채우는 경우


  • 성능

push와 pop은 빠르지만 shift와 unshift는 느립니다.
배열 끝에 작업을 하는 메서드는 다른 요소들을 이동시키는 등의 작업이 필요하지 않으므로 배열 앞을 바꿔주는 메서드보다 빠름


  • 배열의 반복문
    for ..0f문은 현재 요소의 인덱스는 얻을 수 없고 값만 얻을 수 있습니다.
    원하는 것을 충분히 구현할 수 있고 문법도 짧기 때문에 유용
    for ..in문도 가능하지만 느리고 오류의 가능성이 있음 (되도록 사용x)

  • length 프로퍼티
    arr.length = 0;을 사용해 간단하게 배열을 비울 수 있습니다.
    length의 값을 수동으로 증가시키면 아무 일도 일어나지 않지만 값을 감소시키면 배열이 잘립니다. 짧아진 배열은 다시 되돌릴 수 없습니다.

  • new Array()
    대괄호로 배열만드는 방법에 비해 거의 쓰이지 않는데 그 이유는
    숫자형 인수 하나를 넣어서 new Array를 호출하면 배열이 만들어지는데, 이 배열엔 요소가 없는 반면 길이는 인수와 같아집니다.
    new Array(number)를 이용해 만든 배열의 요소는 모두 undefined

  • 다차원 배열
    배열 역시 배열의 요소가 될 수 있는데 이런 배열을 가리켜 다차원 배열이라 한다. 다차원 배열은 행렬을 저장하는 용도로 쓰입니다.

  • toString
    배열엔 toString 메서드가 구현되어 있어 이를 호출하면 요소를 쉼표로 구분한 문자열이 반환됩니다.

몰랐던 용어

UTF-16

-> 유니코드 인코딩 문자의 방식 중 하나로, 주로 사용되는 기본 다국어 평면에 속하는 문자들은 그대로 16비트 값으로 인코딩이 되고 그 이상의 문자는 특별히 정해진 방식으로 32비트로 인코딩이 된다.

공부사이트

코어 자바스크립트


위의 내용은 공부중 본인이 이해한 내용으로 몇몇 틀린 내용이 있을 수 있습니다.
회독중 발견시 수정하겠습니다

profile
working hard

0개의 댓글