TIL 43 (2020.09.16) JS

백은진·2020년 9월 18일
0

TIL (Today I Learned)

목록 보기
43/106

오늘 JS 리플렛 공부한 것 정리.

[자료형 주의]

string과 number을 연산자를 이용해 계산할 때는 예상과 다른 값이 나올 수 있어 주의해야 한다.

예를 들어 alert("2 더하기 2는 " + 2 + 2);라는 식이 있을 때, 프로그램은 다음과 같이 계산한다.

// 1.
2 더하기 2는 2
// 2. 
2 더하기 2는 22

왜냐하면, string과 number를 '더할' 경우에는 항상 string 형으로 변경되기 때문이다.

이런 유연성이 JS의 장점이자 단점으로 다가온다.

[연산자]

===는 equality operator(동등 비교 연산자)로서, 엄격한(identity/strict) 비교연산자 이다. type이 다르면 내용이 같더라도 다르다고 한다.

반면, == 역시 equality operator(동등 비교 연산자)이나, 느슨한 비교연산자 이다. type이 다르더라도 내용이 같으면 같다고 한다.

!==는 다른지를 비교하는 연산자이다.

|| 은 or 연산자로서, 주어진 값 중 하나라도 참이 있는지를 판별한다.

&& 은 and 연산자로서, 주어진 값 모두가 참인지를 판별한다.

if (age > 65 || age < 21 && res === "한국") 문이 있을 경우
컴퓨터는 왼쪽부터 계산을 진행하기 때문에, 첫번째 연산자인 or을 기준으로 나누어서 참거짓을 판별한다.

따라서, ‘age가 65 초과’ 혹은 ‘age가 21 미만이면서 res가 한국’ 중 하나만 참이면, if문은 실행된다.

이처럼 사람이 예상한 것과 실제 컴퓨터가 실행하는 계산이 다를 수 있기 때문에, 해석의 여지가 다양할 수 있는 위와 같은 구문은 가독성을 위해 소괄호로 묶어주는 것이 좋다.

if (age > 65 || (age < 21 && res === "한국"))

만약 and를 기준으로 참거짓을 판별하고 싶다면, 

if ((age > 65 || age < 21) && res === "한국")

[함수]

함수에서 parameter 이름이 지정되었을 때,
함수 내에서 그 이름을 변수명으로 하여 값을 할당하면 안된다.

function alertSuccess(name) {   
  let name = "wecode";
  alert(name + "님 로그인 성공!"); 
}

alertSuccess();
alertSuccess("wecode");

// 모두 SyntaxError가 뜬다. 
function meetAt(year, month, day) {
  if(day) {
    return (year + "/" + month + "/" + day)
  }
  if(month) {
    return (year + "년 " + month + "월")
  }
  if(year) {
    return year + "년"
  }
}

meetAt(2020, 9, 16);

위와 같이 여러개의 parameter을 받을 때, 마지막 매개변수부터 if문으로 넣어주어야 한다.

왜냐하면 첫번째 매개변수부터 If문으로 넣는다면, 첫번째 매개변수 확인 후 함수가 종료될 것이기 때문이다.

그래서 마지막 매개변수부터 if문으로 넣어서, 함수의 모든 부분이 순서대로 다 진행될 수 있도록 해야 한다.

[매개변수]

어떤 함수가 있고, 다른 함수에서 어떤 함수를 호출해 재사용 할 때,

모든 함수의 매개변수가 같지 않아도 된다.

그러나 함수 각각에서 매개변수는 통일되어야 한다.
아래의 예시처럼.

function getTax(price) {
  return price * 0.1;
}

function calculateTotal(x) {
  return x + getTax(x);
}

function getTotal(price1, price2) {
 return calculateTotal(price1) + calculateTotal(price2)
}

getTotal(3000, 5000);
// Output: 8800

[배열]

빈 배열에 cities[2] = ‘김포’처럼 인덱스를 지정해서 요소를 추가할 수 있다.

이 때 다른 인덱스 [0, 1]는 undefined라고 출력된다.
(그래도 요소가 있는 것이라고 말할 수 있음. 그렇기 때문에 cities 배열에 현재 3개의 요소가 있는 것.)

배열이름.push()를 하면 배열의 맨 마지막에 요소가 추가되고,
배열이름.unshift()를 하면 배열의 맨 앞에 요소가 추가된다.

따라서,
배열이름[n] = “blah”; 처럼 인덱스를 지정해서 요소를 추가할 수도 있고,
배열이름.push(“blah”); 처럼 배열 맨 마지막에 요소를 추가할 수도 있다.

[typeof]

이제까지 typeof를 함수처럼 사용했다.
console.log(typeof(“string”)) 이런식으로.

그런데 console.log(typeof “string”) 이렇게 괄호 없이도 사용이 가능한 걸 오늘 처음 알았다.


null은 빈 객체를 가리키고 있는 object이다.

어떤 변수에 string형의 값을 할당하면 그 변수는 string형의 변수가 된다.
반면, number형 값을 할당하면, 그 변수는 number형의 변수가 된다.

number형으로 휴대폰번호를 저장하면, 맨 앞의 0은 삭제되기 때문에 정보가 정확하지 않다.
따라서 이런 경우 숫자를 string형으로 관리해야 정확한 정보를 유지할 수 있다.

[indexOf()]

let info = "JavaScript는 프로래밍 언어이다.";
let firstChar = info.indexOf("프로그래밍");

문자열에 특정 문자열이 있는지 알려주는 내장함수이다.
만약 특정 문자열이 없으면 -1을 반환한다.

[slice()]

slice(잘릴 시작위치, 잘릴 끝위치)

(9월 18일 추가: )
아래 문제를 푸는 게 정말 힘들었다.
결론을 먼저 말하자면, 호이스팅은 전혀 관련이 없는 부분이었고,
프로그램에서 function 부분'만' 확인하기 때문에, 함수 바깥에서 선언된 char1, 2, 3(도, 시, 구 indexOf 한 것)을 인식하지 못했기 때문에 발생한 문제였다.
이 코드 자체는 문제 없이 잘 돌아가는 코드가 맞다.

문제에서 요구하는 것
1. ‘도, 시’가 있을 때 ‘시’를 삭제하고 출력하는 것
2. ‘시, 구’가 있을 때, ‘시’를 삭제하고 출력하는 것
3. ‘도, 시, 구’가 있을 때, ‘시’를 삭제하고 출력하는 것.

필요한 것
1. 어떤 경우든 ‘~~시’를 삭제하고 출력도록 if 문을 돌린다.
2. ‘도, 시, 구’의 index 값.

(9월 18일 추가: 호이스팅 문제 아님)
아… 2시간 반만에 풀었다….
호이스팅이 문제였어…

함수 바깥에서 선언된 변수를 함수 내에서 재사용을 하면,
함수 내에서는 변수이름은 인식하지만 변수값을 알지 못한다.

즉, 호이스팅을 할 때, 변수이름은 끌어오지만 변수값은 끌어오지 않는 것이다.

따라서 함수 내에서 사용을 원하는 변수는 함수 내에서 선언도 이루어져야 한다.

// 제출한 과제
function sliceCityFromAddress(address) {
  if ((char1 !== -1 && char2 !== -1 && char3)) {
    address = address.slice(0, char1+1) + address.slice(char2+1, address.length);
  }
  if ((char1 === -1 && char2 !== -1 && char3 !== -1)) {
    address = address.slice(char2+2, address.length);
  }
  return address
}

let address = "경기도 성남시 분당구 중앙공원로 53";
//let address = "서울특별시 강남구 테헤란로 427 위워크타워";

let char1 = address.indexOf("도");
let char2 = address.indexOf("시");
let char3 = address.indexOf("구");

console.log(char1, char2, char3)

sliceCityFromAddress(address);

string <-> number 변환

console.log(2019+"2000");
console.log(2019-"2000");

+ 연산자는 string, number 모두 사용 가능.
따라서 + 연산자와 따옴표가 있을 경우, -> string으로 인식.

- 연산자는 number만 사용 가능.
따라서 - 연산자와 따옴표가 있을 경우, -> number로 인식.
그래서 따옴표 내 숫자가 없을 경우, NaN (Not a number)을 출력함.

[변환 내장함수]

  • string -> number

Number();
parseInt(); -> 정수만 출력함
parseFloat(); -> 소수도 출력함

  • number -> string

toString();
string변수이름 - 0; -> 연산 특성을 이용해서 변경

[날짜 호출 방법]

let rightNow = new Date();
let year = rightNow.getFullYear();
let month = rightNow.getMonth()+1; -> 꼭 +1 해줘야 현재 달이 출력됌!!
let date = rightNow.getDate(); -> 날짜 반환
let day = rightNow.getDay(); -> 요일반환(0이 일요일, 0~6 중 1개 출력함)
let currentHour = rightNow.getHours();
let currentMin = rightNow.getMinutes();
let time = rightNow.getTime(); -> 밀리초 반환

위의 내장함수는 모두 Date 타입이 갖고 있는 메서드이다.

실행될 때의 밀리초를 반환하는 getTime() 메서드는 1970년1월1일을 기준으로 한다.
따라서 그 날을 기준으로 1600255724603 밀리초가 지났다는 의미이다.
밀리초를 비교연산하면, 언제가 더 과거인지 알 수 있다.


와!!! month+1이 정말 큰 부분을 차지한다!!
문제가 계속 풀리지 않아서 1~2시간 정도 헤맸는데, 예상과 다른 값이 출력된 이유는 컴퓨터가 month 값을 1개가 차이나도록 인식하기 때문이다.

따라서,
내가 직접 month 혹은 year, month, day 값을 입력할 때는 -1한 month 값을 입력해야 하고,
컴퓨터로부터 month 혹은 year, month, day 값을 출력받을 때는 +1한 month 값이 출력되도록 코드를 추가해야 한다.

아래의 코드 부분을 보면 date1, date2, date3을 로그한 것을 볼 수 있다.
그런데 년, 월, 일만 Date()로 낸 date3의 결과값이 예상과 크게 다르다.

결론을 말하자면, month +1 특성과 우리나라가 UTC에 비해 +9시간 차이나는 것 때문에 그렇다.

컴퓨터는 month값을 -1로 인식한다. (이유는 아직 모르겠다.)
따라서, new Date(2019, 5, 1)를 입력하니까 컴퓨터는 month값인 5가 -1된 값이라고 인식한 것이다.

때문에 (2019, 5, 1)을 (2019, 6, 1) 00시00분이라고 받아들였고,
그 날짜에서 -9시간을 계산해서 (2019-05-31T15:00:00.000Z)가 출력된 것이다.

나는 이런 내용을 스택오버플로우에서 찾지 못했는데,
라운지에 계신 멘토님께 질문했더니 이 스택오버플로우에서 찾아주셨다 ㅠ.ㅠ
(검색력을 늘리자!!)

공부할 때 사소하게 보이는 요소들도 사소히 넘어가지 않고 꼼꼼히 알아봐야겠다.


아래의 내용은 너무 궁금해서 stackoverflow에 질문하려고 쓴 글이다.
(올리기 전 답을 찾게 되어서 실제로 올리진 않았다 ㅋ.ㅋ)

Does computer not calculate month when makes 'new Date()' with only year, month, and day? (in javascript)

Hi, I tried to get the value of new Date(2019, 5, 1).
So put the result to variable 'date3', and logged to console.
However, the log shows me that the result is "2019-05-31T15:00:00.000z".
My time zone is GMT+9 which is ahead 9 hour by Coordinated Universal Time (which is same with UTC).
I think the computer calculated minus 9 hour with date3 data to adjust with UTC time. 

**But is the computer not also calculate month value?
And what data should I add to 'date3' to get proper result when similar situations?**

Any answers will be appreciated.


```
let date1 = new Date('December 17, 2019 03:24:00z');
let date2 = new Date('2019-12-17T03:24:00');
let date3 = new Date(2019, 5, 1);

console.log("1", date1)
console.log("2", date2)
console.log("3", date3)

// 1 2019-12-17T03:24:00.000Z
2 2019-12-16T18:24:00.000Z
3 2019-05-31T15:00:00.000Z

```
profile
💡 Software Engineer - F.E

0개의 댓글