240812 TIL - JS문법 종합반 wk1 & .length와 .length()중 진짜는?

LIHA·2024년 8월 12일
0

내일배움캠프

목록 보기
16/54
post-thumbnail

험난한 Node.js 설치기

JS 학습주간 창민 튜터님의 말씀

  • JS 서버는 서버 효율 극대화를 위해 비동기가 가장 중요하다.
  • Closer가 이해 안된다고 좌절할 필요 없다. 보통 많이들 어려워함.
  • JS 학습주간은 3주차, 5차는 어려우면 패스해도 된다.

왜 깃배쉬로는 Node.js가 깔리지 않을까

저도 fnm 명령어 쓰고싶어요😭

그러나 끝내 명령어가 먹히지 않아 그냥 다운로드 화면에서 버튼을 눌러 프로그램으로 설치했다. 시무룩


오늘 배운 것

VS Code에서 한줄을 복사하고 싶으면 Alt + Shift + ↑ 또는 ↓

어떤 코드가 쓰인 줄에서 얘를 이 아래에 똑같이 쓰고싶다면 ↓, 위에 쓰고싶다면 ↑ 하면 된다.

JS는 String이어도 .length()를 안쓴다. 기주 튜터님의 말씀

  • 참고: 내가 기억하고 있는 .length() 는 JAVA의 문법이다. 원래 JS에서는 안 쓴다.
  • 이유: JS는string 배열의 크기를 int 값으로 이미 가지고 있다가 내어주는 방식이라서.
  • 좀더 자세히: JS의 string은 클래스가 아니라 자료형이다. 즉 크기가 정해져 있단 얘기!

JS는 () 괄호를 열고 닫는건 '함수를 호출할때만' 으로 국한되어 있다. console.log() 처럼.
JS는 길이를 고정적으로 계산해서 int로 가지고 있지만, JAVA는 String에 length()를 호출하면 그때 계산을 해서 내놓는다.

JAVA도 배열의 length는 계산하는데, String의 length는 계산하지 않는다. 왜일까?
-> 배열은 임의의 고정된 용량 한계가 있다. 근데 그걸 넘어가면 지알아서 새로 메모리를 할당 받는다.
-> JAVA는 가지고 있으려고 해서 그런것이고 JS는 가지고 있지 않으려고 해서 그런것이다...?

도움이 많이 된 블로그의 글
나 전에도 이걸로 고민했었는데?

그래서 둘 중에 누가 진짜인가요? - .length가 진짜랍니다

정리하자면 다음과 같다

  • JAVA의 배열은 기본형 중 하나로 취급되어 그 길이 또한 byte 정해지듯 정해져있다.
  • 그러나 JAVA의 String은 자료형이 아니라 클래스라서 length()라는 메서드가 정의되어 있는 것.
  • 그런데 JS에서 string은 자료형이므로 정해진 크기를 뱉어주는 .length를 쓰는 것이 당연.

switch문의 case에는 항상 break; 가 필요하다

그렇지 않으면 모든 switch 문을 다 돌고 돈 끝에 default까지 돌아 나오게 될 것이야.

truthy한 값, falsy한 값 - 당신이 직감하는 그게 맞다

NaN, undefined, null, "" 등을 넣으면 if문의 조건절이 false로 간주되어 찍히지 않는다.


JS 문법 종합반 1주차 내용

객체

JS의 신비함 - 객체 메소드

Object.keys() - 키 값만 뽑아서 배열로 보여줌
Object.values() - 밸류만 뽑아서 배열로 보여줌
Object.entries() - 키밸류를 묶어 2차원배열로 보여줌
Object.assign() - 객체를 복사해줌

원하는 대부분의 기능을 지원합니다.

우리 객체 메소드는 값도 바꿔줘요 - Object.assign()

let person = {
    name: "홍길동",
    age : 30,
    gender: "남자"
};
  • 홍길동씨의 정보를 복사하고 싶은데 나이가 바뀌었단다. 복사하는 과정에서 수정할 순 없을까?
    -> 아래와 같이 쓰면서 변경할 키밸류만 넣어주면 된다.
let newPerson = {}
Object.assign(newPerson, person, { age : 31 });
console.log("newPerson", newPerson);

짜잔. 한살 더 먹은 홍길동 씨 등장.

솔로몬도 울고갈 진위판정 - 객체는 주소값을 저장한다

let person1 = {
    name: "홍길동",
    age : 30,
    gender: "남자"
};

let person2 = {
    name: "홍길동",
    age : 30,
    gender: "남자"
};

초보 학습자에겐 놀라운 일인데 위 코드의 console.log(person1 === person2); 를 찍으면 false가 나온다. 솔로몬도 울고 갈 노릇이다.

  • 이 console.log 값은 왜 false일까?
    -> 객체는 용량이 상당히 커서 메모리에 저장 시 별도의 공간에 저장한다. 그래서 위 객체 person1, 2를 호출 시에 반환해주는 것은 그 값 자체가 아니라 그 값이 있는 메모리 상의 주소값이다. C의 포인터 같은 느낌으로 주소를 참조하는 모양이다. ptn*, ptn**, ptn***...

단순 문자열만 비교하고 싶은데 - JSON.stringify()를 쓰자

위 코드에서 console.log(JSON.stringify(person1)===JSON.stringify(person2)); 를 하면 무난히 true가 나온다. 그런데 이런 형태를 어디서 본 것 같다.

파이썬 할때 return jsonify를 본 것 같은데?

플라스크 쓸 때 비슷한 문법이었던 기억이 있다. 프로젝트를 다시 열어보니 doc의 작성 방식도 insert_one도 비슷. JS 학습과 상관은 없지만 괜한 기시감에 열어봤다

객체를 병합하고 싶을 땐 ... 을 쓰자

let person1 = {
    name: "홍길동",
    age : 30
};

let person2 = {
    gender: "남자"
};
// 한쪽에는 이름과 나이만, 한쪽에는 성별만 있다. 둘이 합치면 완벽할거 같은데...

// ... : spread operator -> 이 객체 중괄호 풀고 내용물 다 흩뿌려줘 라는 작용
let perfectMan = {...person1, ...person2};
console.log(perfectMan);

튜터님의 perfectMan이라는 작명이 너무 웃기다


배열

array.pop()은 배열의 마지막 요소가 뿅 하고 사라지는 것

어렵다면 git stash pop을 생각해보자. 물론 git stash는 쌓이지만
예시로 천상의 맛 지옥의 냄새라는 과일계의 악마 두리안을 삭제해보자

let fruits = ["사과", "바나나", "두리안"];
console.log("1: ", fruits);

fruits.pop();
console.log("2: ", fruits);

무사히 두리안을 제거했다.

반대로 머리쪽을 삭제하고 싶으면 array.shift()를 쓰자

let fruits = ["사과", "바나나", "두리안"];
console.log("1: ", fruits);

fruits.shift();
console.log("2: ", fruits);

앗? 머리는 왼쪽인가보다. 두리안을 자른다는게 사과가 희생당해 버렸다!

머리를 잘못 잘랐으면 다시 붙여야지 - array.unshift(붙일머리)

let fruits = ["사과", "바나나"];
console.log("1: ", fruits);

fruits.unshift("포도");
console.log("2: ", fruits);

새로운 머리는 주렁주렁 포도로 붙였다. unshift()는 일종의 매개변수가 필요한 메소드.

그렇다면 배열은 큐 구조라고 할 수 있는걸까? - 정섭 튜터님의 말씀

어레이는 말 그대로 메모리 위에 일렬로 놓여있는 것.
그런데 또 메모리에 올라와있는 그 모양을 '자료구조'라고 하니까 아예 다르다고 하긴 또 그렇다.
JS가 배열같이 생긴걸 쓸수 있는 건 V8엔진이 얼마나 최적화 해주느냐에 따라 달라진다.
(그거 아는가? JS는 자료구조라는 것이 내장되어있지 않아 힙이고 버블이고 내가 구현해야 하는 아주 불쾌한 경험을 할 수 있다)

본래 배열을 처음 배우면 pop은 빠르고 shift는 느리다고 배운다. 그리고 컴퓨터는 원래 index의 첫번째부터 접근해서 작업하는게 일반적이다. 배열의 인덱스가 0인 이유는 우리가 이미 그 주소값을 알고있기 때문이다.
배열의 끝을 자르는건 쉽지만, 주소값을 아는 머리를 날리는 것은 별개의 문제다. 날리면 뒤의 애들을 전부 다 한칸씩 땡겨와야 한다. 이걸 '정합성의 유지' 라고 한다.

  • 그래서 배열이 큐 구조와 근본적으로 다른 이유는, 큐는 앞으로 빼는게 뒤를 자르는 것만큼 빠르게 할수 있게 만든거다. shift가 pop만큼 빠른 구조인 것.
    배열은 그렇지 않다. shift가 아주아주 느리다.
    (+ 큐는 방향이 정해져있다. 넣는 반대방향으로 나감)

  • 큐는 맨앞이던 애가 나가버리면 그 맨앞을 가리키는 포인터가 이동하던가 하는 식으로 어떻게든 머리가 항상 유지된다. 그래서 머리에 shift를 쓰든 꼬리에 pop을 쓰든 상관없다.

  • 배열은 그게 아니다. 머리가 짤리면 아주 곤란해진다. 그리고 민족대이동이 일어난다. 그러나 대신 중간에 slice를 쓰든 splice를 쓰든 할 수 있다. 물론 최적화가 와장창 되면서 속도는 구려지지만.

[참고]
어느쪽으로나 넣고 뺄수 있는 더블 엔디드 큐 라고 있다. DEQUE 라고 쓴다.
레드블랙트리 같은거 물어보는 곳은 거의 없다. 그보다는 기초적인 내용을 묻는 곳이 훨씬 많다.

배열, 스택, 큐 관련 참고한 블로그


트러블슈팅

왜 자꾸 VS Code가 멈추지? - 증감문의 위치가 틀렸다!

while (i < 100) {
    if (i > 3 && i % 5 == 0) {
        console.log(i, " 는 5의 배수");
        i++;
    }
}

이 while문을 실행시키면 수억의 반복을 거행하며 당신의 VSC의 터미널을 먹통으로 만들거나 한방에 다운되게 할 수 있다.
i는 if문과 상관없이 증가되어야 하니 if문 밖으로 빼주도록 하자.

1주차 첫번째 숙제를 풀었던 방법 기록

// 1. 문자열 연습하기

// 문자열 내의 p와 y의 갯수를 비교해 같으면 true, 다르면 false를 return 한다.
// p와 y 모두 하나도 없는 경우에는 항상 true를 return한다
// s의 길이는 50 이하의 자연수!

// 나의 방법
// 문자열 s와 예문 모두 소문자로 만들어 s와 비교하자
// filter를 걸어 찾아서 두 배열의 길이가 같으면 true를 비교하는 것으로

let s = "gggbbby";
let arr = [...s.toLowerCase()];

let cntp = arr.filter(function(item1) {
    return item1 == 'p';
});

let cnty = arr.filter(function(item2) {
    return item2 == 'y';
});

    if (cntp.length === cnty.length) {
         console.log("true");
    } else console.log("false");

1주차 두번째 숙제가 도저히 안풀려요 - 부호를 바꾸고 싶어

아무리 해도 false에 -1을 적용하는 것이 먹히지 않아 도저히 모르겠어서 JAVA로 풀었던 코드를 보던 차에 부호의 처리법을 깨달았다. 내가 문제였던 것은 조건절이 false일 때를 어떻게 처리하느냐 였다.

        if (signs[i] === false) {
        absolutes[i] = -absolutes[i];
        } 

나는 이렇게 쓰고 false가 계속 0으로 치환되어 내내 애를 먹었는데, signs[i]가 불린타입으로 false임을 나타내려면 이렇게 쓰는 것이었다.

        if (!signs[i]) {
        absolutes[i] = -absolutes[i];

15조 공부 멈춰!

우리조 멈춰... 공부 그만해... 지금 밤 9시가 넘었는데...

profile
갑자기 왜 춤춰?

0개의 댓글