이 글의 시작은 매우 간단했다. JavaScript로 문제를 코딩테스트 풀다가, Map이라는 자료구조를 사용할 일이 생겼다.

 

복잡한? 기능들을 사용하기는 귀찮아서 Object로 문제를 해결하려했는데, 그럼 시간 복잡도에 문제가 없을까?라는 생각이 들었다.

 

Stackoverflow에서 찾아보니, Object도 hash로 이루어져있어서 find에 O(1)의 시간 복잡도를 가진단다.

 

stackoverflow.com/questions/12241676/javascript-objects-as-hashes-is-the-complexity-greater-than-o1

 

JavaScript Objects as Hashes? Is the complexity greater than O(1)?

For some algorithm I was writing recently I thought that a hash would be excellent. I thought that I could probably just use the member variables in an object as key value pairs. I am not sure if t...

stackoverflow.com

 

여기서 의문이 시작됐다. JavaScript에서 Object와 Map은 어떻게 이루어져있을까?? 물론 인터프리터, 컴파일러, 엔진에 따라 다르겠지만,내가 자주 쓰는 Node를 기준으로 어떻게 되어있는지 궁금했다. 이에 대해 개인 Notion에 러프하게 정리했었는데, 블로그에 깔끔히 정리해보려한다.

 

Map과 HashMap

먼저 Map과 HashMap에 대하여 알고 있어야 이해하기가 편할 것 같다.

 

HashMap = unordered Map

  • HashMap은 key 와 value 를 hash 알고리즘에 의해 구현

  • Hash 알고리즘으로 넣으므로 전체가 어떤 특정한 규칙으로 정렬이 되어 있지 않다.
  • hash_map은 find에 이상적으로 O(1)의 시간을 소요한다.

  • 하지만 hash_map은 실제로는 hash table의 크기에 반비례하는 O(n)의 시간을 소요한다.

    • 예를 들어 1000개 저장하는데, 테이블 크기가 100이라면, 시간은 10만큼 걸릴 것이다.

Map ( Tree Map ), Ordered Map

  • Map( Tree Map)은 보통 red-black tree 알고리즘을 이용하여 구현

  • Tree의 규칙대로 들어가므로, Order되어 있다, 즉 정렬되어 있다.
  • Map( Tree Map )을 쓰는 경우, 최악의 경우 O(n), 최상의 경우 O(logn)의 시간복잡도

    • 이진 트리의 원리에 따라 일렬로 이루어졌을 경우 O(n)이 걸리고,
    • 균등하게 나누어져 있다면 O(logN)이 걸릴 것이다.
반응형

자바스크립트에서는 set을 구조분해할당으로 배열로 바꿀 수 있다.

 

set을 배열로 바꿈으로 쉽게 중복을 제거할 수 있는데,

 

예를 들면

 

let a = new Set([1,2,3,1])

let b = [...a]

 

이렇게 하면, 쉽게 중복(예제에서는 1)이 제거된 배열을 구할 수 있다.

 

하지만 타입스크립트에서는 

 

'Set<any>' 형식이 배열 형식 또는 문자열 형식이 아닙니다.

 

라는 오류가 발생한다.

 

구조분해할당은 원래 배열이나 객체, 문자열을 해체하는 것이기 때문에, set은 해당이 안되는 것 같다.

javascript는 유연하여 set도 구조분해할당해주지만, 엄밀하게 타입을 정하는 typescript에서는 오류를 띄운다.

 

따라서 이 문제를 해결하기 위해서는 

 

Array.from(집합) 을 사용해주면 된다.

위의 예제를 예를 들면

 

let a = new Set([1,2,3,1])

let b = [Array.from(a)]

 

이렇게 해결해주면 된다.

set을 문자열로 형변환을 해주기 때문에 문제가 발생하지 않는다.

 

 

반응형

JavaScript에는 Function Chaining 혹은 Method Chaining이라는 기법이 있다.

 

만약 A라는 리스트에 filter와 map이라는 두 개의 메소드를 적용시키고 싶다.

 

그렇다면 원래라면

 

A= A.filter(~~~)

A.map(~~~~)

 

이런 식으로 두 줄로 적어주어야할 것이다.

 

하지만 이것을

 

A.filter(~~).map(~~~)

 

이렇게 한 줄로 줄여줄 수 있고, 이것을 Method Chaining이라 한다.

 

A = A.filter(~~~~)A'이 되고

A'.map(~~~)을 수행한다.

 

따라서 Method Chainging을 할 때 순차적으로 적는 것이 중요하다.

 

체이닝 패턴

 

 

반응형

ES6 문법이 확장되면서 화살표 함수라는 것이 생겼다.

 

let a =  () => { } 이런 식으로 쓰는 함수인데, 

 

단순히 표기가 간편해졌다 뿐만 아니라 여러 가지 차이점들이 생겼다.

 

1. this

 

아마 가장 큰 차이가 this의 여부가 아닐까 싶은데, 화살표 함수에서는 this가 바인딩 되지 않는다.

즉 함수 내부에서 this를 생성하지 않으므로, this를 사용할 시 바로 바깥의 함수 또는 클래스의 this를 불러온다.

그래서 함수 안의 함수를 사용할 때, this를 바인딩해주어야하는 경우가 많은데, 화살표 함수는 그 수고를 줄일 수 있다.

 

하지만 이런 점 때문에, 화살표 함수는 함수나 클래스의 메소드를 만들때는 적절하지 않다.

 

 

 

2. arguments

 

일반적인 function에서는 argument라는 문법을 사용할 수 있는데

함수의 인자들을 접근할 수 있습니다.

 

예를 들면 

 

foo(){
    console.log(arguments[0])

}

 

이렇게 함수를 생성하면,

 

foo(1)로 함수를 사용하면, 1이 로그에 찍힙니다.

 

하지만 화살표함수는 이 기능을 지원하지않습니다.

 

하지만 args라는 조금은 다른 문법을 지원합니다.

 

 

 

3. new 사용 불가 ( 생성자로 사용 불가 )

 

말그대로 클래스나 객체의 생성자로 사용 불가하다

그와 동시에 new를 붙혀서 생성할 수 없다.

 

 

 

 

 

이 부분은 좀 더 사용하면서 익혀봐야할 것 같다.

여러 글을 읽으면서 느낀 것은 내가 화살표 함수를 모르는 것보다, 기존 함수를 잘 몰랐다는 생각이 많이 들었다.

반응형

사실 구조 분해 자체는 어려운 개념은 아닌데, 구조 분해라는 이름을 모르고 쓰고 있어가지고 이렇게 정리하게 되었다.

 

React에서 많이 사용하는 것 중 하나가

 

const { props에 있는 변수명들~~~ } = props

 

이런 코드다.

 

예시를 설명하자면

 

const player1 =

{ name: "hello",

   id: 3, 

}  

 

const { name, id } = player1

 

이렇게 한다면

nameid에 각각 player1.name, player1.id 의 값이 저장된다.

 

따라서 console.log(name) 을 하면 "hello"가 출력된다.

 

그리고 name 값을 수정해도, player1.name의 값은 수정되지 않는다.

참조 복사가 아니라 값 복사가 이루어지기 때문이다.

 

그리고 재밌는 것은, 이것을 함수에도 활용할 수 있다는 것이다.

 

원래라면 player1의 name 값을 출력하기 위해

 

var printPlayerName = player1 => {

   console.log(player1.name)

}

 

이렇게 해주어야했다면,

 

var printPlayerName = ({ name }) =>  {

   console.log(name)

}

 

 

이렇게 출력이 가능하다.

 

또 이렇게하면 장점이 있는데, 작성자가 사용하는 변수만 코드에 작성하게 되므로,

 

작성자의 의도를 잘 알 수 있다.

 

그리고 이것을 선언적이라고 한다.

 

선언적이 무엇인지에 대해 간단히 설명하자면,

어떻게 보다 ,무엇을 할 것인지에 대해 초점을 맞추는 것이다.

 

이 부분이 궁금하다면 선언적 프로그래밍을 찾아보는 것이 좋을 것 같다.

 

그리고 배열 또한 구조 분해가 가능하다.

 

var [first] = [1, 2, 3]

 

이라면 first에는 1이 담긴다.

 

그리고 리스트 매칭 또한 활용 가능한데,

 

var [ , , third] = [1,2,3]

 

이면 third는 3이 된다.

 

리스트 매칭도 간단히 설명하자면,

배열에서 사용하지 않는 부분, 건들이지 않는 부분은 그냥 비워놓는 것이다.

 

물론 변수를 하나 뿐만 아니라 이렇게 

 

var [ first, second, third] = [1,2,3]

var [ first, , third] = [1,2,3]

 

여러 개도 가능하다.

 

아마 리스트 매칭도 선언적이다 라고 볼 수 있을 것 같다.

 

 

p.s

지금 공부하고 있는 러닝 자바스크립트에 리스트 매칭이라고 되어 있는데,

리스트 매칭이라고 검색하면 자료가 잘 없다...ㅠㅠ

 

이번에 구조 분해를 공부하면서, 선언적 프로그래밍, 리스트 매칭 등 사용하고는 있었지만, 그 이름을 몰랐는데 이름을 알게 되었다.

공부하면서 내가 쓰고 있는 것의 이름을 아는 것이 참 중요한 것 같다.

덕분에 검색하며 더 자세하고 깊게 알게 된 것 같다 ㅎㅎ

반응형

 

JS로 코테를 볼 것을 대비하여 C++과 다른 함수들을 정리해보았다.

 

 

<문자열 관련>

 

var s = "abcde" 

var num = 25 

라고 했을 때

 

var  a = s.split(끊을 기준) - 기준으로 끊어서 배열에 나눠 저장. 예를 들어 var a = s.split('c')하면 a[0] = "ab", a[1] = "de"가 저장된다.

s.substring(시작, 끝+1)  - 예를 들어 s.substring(0,4) 하면 abcd로 끊긴다.

s.substr(시작, 끊을 크기) - 예를 들어 s.substr(1,2)하면 bc로 끊긴다.

 

String( 문자열로 바꿀 값 ) 

Number( 숫자로 바꿀 값 ) 

num.toString( 이 수는 몇 진수로 변환할거야? - 없으면 디폴트값 10진수 ) -  숫자를 문자로 변경한다.

 

<수학 관련>

 

Math.min(비교할 값1, 비교할 값2, 비교할 값3..... ) - C++의 min함수와 동일 

반응형

ESLINT : 자바스크립트 linter이다.

 

그러면 linter란 무엇인가?

 

정적 타입 분석 도구이다.

즉, 코딩 컨벤션과 문법적 에러 체크를 도와주는 것입니다.

 

그럼 코딩 컨벤션은 무엇인가?

 

코딩 스타일이나 코딩 표준 가이드라인을 의미한다. 재밌는건 이 표준이라는게 기업마다 조금씩 다르다 ㅎㅎ

예시로 Google 스타일이나 Airbnb 스타일 같은게 있다.

 

Prettier도 ESLINT와 비슷한데, Prettier은 여기에 줄 간격, 줄 길이 같은 규칙을 설정하여 자동으로 정렬해준다.

Prettier은 그런 포맷을 맞춰주기 때문에 Code Formatter라고 한다.

 

규칙을 설정해 놓고 Editor의 Auto Save기능을 활용하면 저장을 할 때, 안 맞게 작성했던 코드들이 자동으로 인덴트된다.

반응형

문자열 내에 원하는 문자 혹은 문자열이 포함되어 있는지 확인하는 함수이다.

 

ES6부터 지원한다하니 쓰기 전에 잘 확인해보시길

 

var original = "abcd" 내에 ab가 있는지 확인하려면

 

original.includes("ab");

 

이렇게하면 return 값이 있으면 true, 없으면 false로 반환한다.

 

 

반응형

+ Recent posts