[TIL] 코드스쿼드 코코아 2주차 - Part 2

Dico·2020년 11월 11일
1

[TIL]

목록 보기
4/13
post-thumbnail

코드스쿼드 코코아과정 2주차 TIL - Part2


Mission 4. 괄호문법 검사기

Mission 상세내용보기


Brainstorming

Linting/Linter

Linting이란, 특정 프로그래밍 언어로 소스 코드를 분석하고 프로그램 오류, 버그, 스타일 오류, 의심스러운 구조체 등 잠재적 문제를 표시하는 프로세스.

Stack(LIFO)

  • Last In, First Out / 후입선출
  • 스택의 제한사항
    1) 데이터는 스택의 에만 삽입할 수 있다.
    2) 데이터는 스택의 에서만 읽을 수 있다.
    3) 데이터는 스택의 에서만 삭제할 수 있다.
  • 보통 스택의 끝을 위(top), 스택의 시작을 밑(bottom)이라 부른다.

Queue(FIFO)

  • First In, First Out / 선입선출
  • 큐의 제한사항
    1) 데이터는 큐의 에만 삽입할 수 있다. (스택과 동일)
    2) 데이터는 큐의 에서만 읽을 수 있다. (⬅️➡️ 스택)
    3) 데이터는 큐의 에서만 삭제할 수 있다. (⬅️➡️ 스택)

typeof NaN === "number" 그리고 isNaN(NaN)

NaN이 'Not A Number'의 약자라는데, number가 아닌 것의 타입은 number다. 😂

요소의 수를 세기 위한 나의 가설은 이랬다:

  1. string ➡️ array로 바꾼다.
const data1 = "[1,2,[3,4,[5,[6]]]]";
const dataArr = dataStr.split("");  

dataArr = ['[', '1', ',', '2', ',', '[', '3', ',', '4', ',', '[', '5', ',', '[', '6', ']', ']', ']', ']']
  1. forEach로 loop를 돌면서 type coercion을 이용해 "number"타입인 요소들의 갯수를 세어본다.
  let count = 0;
    arr.forEach(function (letter) {
        if (typeof (letter*1) === "number")
        count++
    });

그런데 여기서 count가 6이 아닌 '19'가 나온다.😕
알고보니 "[", "," 이런 요소들이 *1로 강제타입변환을 하면 NaN이 되는데, NaN은 타입이 number가 되기 때문이다.

typeof NaN 
//"number"

typeof NaN === "number"
//true

이러니 조건이 다 true가 될 수 밖에... 그래서 && !(letter === NaN)라는 조건을 추가해보려 했지만

NaN === NaN 
//false ⭐️⭐️⭐️

이기 때문에 NaN을 걸러내지 못한다. 구글링을 해보니 NaNNaN인지를 검사하려면 isNaN()을 써야한다.
이렇게:

isNaN(NaN);
//true ⭐️⭐️⭐️

이렇게 조건을 추가하니 값을 정상적으로 반환해준다! 🎉

function countEl (arr) {
    let count = 0;
    arr.forEach(function (letter) {
        if (!isNaN(letter*1))
        count++
    });
    return count;
}

//count = 6;

+ Plus tip:

" "는 숫자로 강제타입변환 시 NaN이 아닌 0이 나온다!

" " * 1   //0


My Code Review

전체코드보기

eval(); 로 문자열 ➡️ 배열 변환

eval()메소드는 문자열을 JavaScript 코드로 인식해 별도의 타입변환 없이도 실행할 수 있게 변환해준다.

eval(str)은 문자로 표현된 JavaScript 코드를 실행하는 함수입니다.

-MDN

그래서 아래처럼 배열모양의 문자열을 진짜 배열로 바꾸는 데에 응용할 수도 있다!! 😃

구분자들까지 검사할 필요가 있는 게 아니라면 문자열을 배열로 바꾸기 위해서 꼭 split("")을 써서 ["[", "1", ",", "2", ",", "[", "3", ",", "4", ",", "[", "5", ",", "[", "6", "]", "]", "]", "]"]와 같은 모양으로 나눌 필요가 없는 것이다!



Peer Session

나머지 연산자(%)

나뉘는 수(dividend; 피제수)가 나누는 수(divisor; 제수)보다 작을 때, 나머지는 나뉘는 수가 그대로 반환된다.

// 피제수 > 제수
7 % 5   //2

// 피제수 < 제수
2 % 5   //2

Math.max(...arr)로 배열에서 최댓값 구하기

ES6를 지원하는 환경이라면, Spread operator(...)를 사용해 보다 편하게 배열에서 최댓값을 구할 수 있다.
이 방법은 만일 배열 내에 최댓값이 하나 이상이라고 하더라도, 최댓값 하나만을 반환한다.

const arr = [1, 2, 3, 4, 5, 5];
Math.max(...arr)    //5

아래와 같이 apply(null, arr)를 사용해 최댓값을 찾을 수도 있다.
apply의 주요 기능은 1) 함수를 실행함과 동시에 2) this 값을 지정하는 것이다.
Math.max로 내장 Array 객체를 보강하게 되면 다른 라이브러리와 충돌 할 수 있으므로 apply로 배열에 직접 연결을 하는 것이다.
(syntax: 함수명.apply(this값, [매개변수로 전달되는 배열])

var arr = [1, 2, 18, 4, 5, 6];
Math.max.apply(null, arr);    //18

여기서 this값은 지정하지 않기 때문에 null로 대체한다.

+ Plus tip:

같은 원리로 Math.min(...arr)로는 최솟값을 구할 수도 있다.

var arr = [1, 2, 0, 4, 5, 6];
Math.min(...arr)    //0

console.dir()

console로 로깅을 할 때, 객체console.dir(); 를 사용하면 JSON파일과 유사한 object tree를 시각적으로 확인할 수 있다.

console.log prints the element in an HTML-like tree
console.dir prints the element in a JSON-like tree

-MDN

console.dir(objTree, { depth: null });로 객체트리(a.k.a JSON객체)를 출력한 모습 ⬇️ (stackoverflow의 관련 내용)

만일 DOM객체에 어떤 메서드가 있는 지 보고 싶다면 console.dir()을 사용하는 것이 좋다.

+ Plus tip:

JSON객체출력은 JSON.stringify()를 이용할 수도 있다.


In addition to that...

  • 프로그래밍에서 의미있는 단위"토큰(token)"이라고 부른다.
    예를 들어, 문자열 '1, 2, 3'에서 토큰은 쉼표와 숫자를 합쳐 총 6개이다.
  • 'const v = 3 + 4;'라는 문자열도 loop를 돌려 실행시킬 수 있다. 그리고 loop를 돌며 정보를 분석해서 토큰을 뽑은 다음, 의미를 달아준다.
  • pair 프로그램의 좋은 점은 상대방의 사고를 배우는 것.
    다른 사람이 짜는 코드를 많이 보는 게 좋지만, 그보다 더 좋은 건 pair 프로그래밍.
    문제에 어떻게 접근했는지를 배우면서 나중에 많은 선택지를 가질 수 있게 된다.
  • 내가 설계한 과정을 회고해보고, 다시 돌아가면 어떻게 해결할 지 생각해보는 것이 많은 도움이 된다.
  • 디자인 = 나만의 방법으로 구현해보기
  • 서버로 요청한 데이터가 있다면 응답값을 어떤 순서로 렌더링 할 것인지가 정해져야 한다.
    이 때 먼저 들어온 응답이 먼저 렌더링 된다면 이건 Queue!
    나중에 들어온 응답이 먼저 렌더링 된다면 이건 Stack!
  • "탐색"을 할 때도 queue나 stack 구조가 많이 쓰인다. 무엇부터, 어떤 규칙으로 탐색할 것인지가 관건!
    알고리즘 중에서는 기초 중의 기초 개념.
  • '프로그래밍이 절차가 있다면 끊어지는 곳이 있지 않을까?' 라고 생각해보면서 분해를 할 수 있어야 한다.
    동작의 흐름을 디자인 할 수 있어야 함. 절차적인 사고를 많이 연습해야 한다.
  • 함수의 시그니처 = 입력(parameter)출력(return type)을 명확하게 정의하는 것이 굉장히 중요!
  • 자바스크립트가 정보를 분석하는 방법
  • [, ,, ] 등은 '구분자'라고 부름.
  • 정규표현식은 알아두면 유용하지만 학습단계에서 우선순위로 두지는 말 것. 정규표현식으로 이메일 체크하는 방법도 있음(나중에 알아보기).
    \d는 digit을 의미하는 것으로 escaping 하는 방법.
  • parser는 분석된 정보(의미가 달린 토큰)를 가지고 스택에 푸시를 하는 것이다.
    컴파일러에서 parser를 만드는 것이 가장 중요한 부분!
  • Chrome Dev Tool에서 parser를 실행해 볼 수도 있다.
  • 반복문으로 만들었을 때 복잡해지는 코드 중에 재귀로 짜면 굉장히 쉬워지는 것들이 있다.
    대표적인 예: 하노이의 탑
  • Prototype 사용해 함수 만드는 형식
function MyName () {
}

MyName.prototype.getName = function () {
  //함수내용
}

MyName.prototype.setName = function () {
  //함수내용
}
  • ES6 Class내부적으로는 prototype과 같다.
    예제코드로 연습하면서 익히기!
//예제 코드
function MyName (name) {
    this.name = name;
} 

MyName.prototype.getName = function () {
    setTimeout(function (){
    debugger;
    console.log("name is ", this.name);
    }, 1000) 
} 

MyName.prototype.setName = function () {
}

const my = new MyName("Hannah");
my.getName();
  • 화살표 함수(=>)에서 this는 lexical scope를 가리키기 때문에 상위스코프의 this를 의미하게 된다.
    화살표 함수와 this 더 알아보기
    this는 상황에 따라 다른 것이 될 수 있음!
  • Chrome Dev Tool에서도 this가 무엇을 가리키는 지 확인할 수 있다.
    자바스크립트에서 debugger; 찍고 dev tool에서 때마다 this가 가리키는 값이 무엇인지 많이 들여다보고 실험해보면서 익히기
  • bind는 함수를 반환해주는 함수이다. 반환 시에 this를 지정해준다.
    bind와 this 더 알아보기
  • JavaScript 관련 면접에 자주 등장하는 개념들: prototype, this, scope, closure
    잘 숙지하기!
  • 코드 스타일 관련 tip:
    - 모듈 프로그래밍은 좋은 습관.
    - 3항연산자는 가급적 간단한 로직에만 사용하기. 괄호를 써주면 가독성이 더 좋다. 그리고 true일 때와 false일 때 반환하는 값의 type을 일치시켜 줄 것! (ex. isEvenNumber ? "string" : false ; 는 좋지 않음. boolean 혹은 문자열로 통일.)
    - if문의 조건을 이름을 지어서 함수 하나로 만들면 좋다.
    - (변하지 않는)상수값들은 대문자로 쓰기.
    - Return 키워드 없이 화살표 함수(람다표기법)으로 쓰면 좀 더 세련된 코드 스타일을 만들 수 있다.
    - 객체를 만들어서 속성을 기반으로 외부에서 실행하는 것이 좋다.
    - 메소드(함수)는 디버깅이 수월하도록 잘게 나누는 게 좋다(서브루틴). 프로그램의 알고리즘이 복잡한 경우는 특히!
    하지만 너무 잘게 나눠버리면 프로그램의 알고리즘이 안보일 수 있다.

    서브루틴이란?
    :프로그램 지침의 연속성, 유닛으로 프로그램들 혹은 라이브러리로 분할되어서 정의될 수 있다.
    서브루틴은 여러 프로그램 언어에서 procedure, function, routine, method, subprogram등로 불린다.

    -https://codenamenadja.github.io/2020/06/06/computing/routine_subroutine/


To-do List 💪

  • #stack과 queue가 쓰이는 곳은 각각 어디인지 알아보기
  • 괄호문법 검사기에서 문자열 변환하는 방법 통일해보기 (연결해서 동작하는 방법 구상해보기)
  • #tokenizer(), lexer(), parser() 컴파일러 알아보기

    parser : 분석된 정보(의미가 달린 토큰)를 스택에 푸시를 하는 행위.

  • #this, bind 개념알기, 예제로 연습해보기
  • #prototype 예제로 연습해보기
  • #scope, closure 개념알기, 예제로 연습해보기
  • #정규표현식 공부해보기
  • stack, queue, 재귀(recursive function)에 관련된 문제 풀며 연습해보기

Reference 📚

*본 포스팅은 아래 사이트들을 참고 및 인용하여 작성되었습니다.
학습단계로 잘못된 정보가 있을 수 있습니다. 잘못된 부분에 대해 알려주시면 곧바로 정정하도록 하겠습니다 😊
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/eval
https://ko.wikipedia.org/wiki/%EB%A6%B0%ED%8A%B8_(%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4)
http://dudmy.net/javascript/2015/11/16/javascript-sort/
https://c10106.tistory.com/3787
https://developer.mozilla.org/en-US/docs/Web/API/Console/log#Difference_with_console.dir()
https://stackoverflow.com/questions/10729276/how-can-i-get-the-full-object-in-node-jss-console-log-rather-than-object
https://ko.javascript.info/regexp-escaping
https://ko.wikipedia.org/wiki/%ED%95%98%EB%85%B8%EC%9D%B4%EC%9D%98_%ED%83%91
https://codenamenadja.github.io/2020/06/06/computing/routine_subroutine/

profile
프린이의 코묻은 코드가 쌓이는 공간

0개의 댓글