\(@^0^@)/

[TDL] 07/19 Today's-Done-List 본문

TDL

[TDL] 07/19 Today's-Done-List

minjuuu 2022. 7. 19. 23:01
728x90

- 유데미 알고리즘 자료 구조 소개

어떤 자료구조를 사용할까?

  • 지도 혹은 위치 정보 관련 작업
    => 그래프

  • 어레이지만 앞단으로 신속하게 삽입할 수 있고 끝단에서 쉽게 제거할 수 있는 정렬된 리스트가 필요하다면?
    => 연결 리스트

  • 연결된 HTML을 걷어내는 웹 작업 혹은 항공사나 호텔의 웹사이트로부터 데이터를 걷어내는 작업
    => 트리 

  • 우선순위의 태스크들을 작성하는 스케줄러를 작성해야 한다면? 
    => 이진 힙 또는 우선순위 큐

 

  • JS에서의 클래스 문법은 기본적으로 진정한 객체 지향이 아니라,
    프로토타입 기반 상속자 혹은 프로토타이핑이라 불리는 무엇인가를 이용하는 것이다
  • 클래스들은 인스턴스로 알려진 객체를 생성하기 위한 청사진이며
  • 이런 클래스들은 "new"키워드를 통해 생성되거나 인스턴스화 된다.
  • 생성자 함수는 클래스가 인스턴스화 될 때 동작하는 특별한 함수이다.
    "new"를 통해 a라는 클래스를 인스턴스화 시키게 되면 a의  컨스트럭터가 먼저 동작하게 된다.
  • 인스턴스 메서드는 메서드 혹은 객체와 유사한 방식으로 클래스에 추가될 수 있으며,
    클래스 메서드는 "static" 키워드와 함께 추가될 수 있다.

- 인프런 함수형 프로그래밍 강의

순수 함수의 다형성과 실용성

function _filter(list, predi) {
  let new_list = [];
  for (let i = 0; i < list.length; i++) {
    if (predi(list[i])) {
      new_list.push(list[i]);
    }
  }
  return new_list;
}

function _map(list, mapper) {
  let new_list = [];
  for (let i = 0; i < list.length; i++) {
    new_list.push(mapper(list[i]));
  }
  return new_list;
}

위의 코드에서 겹치는 for loop 부분을 _each 함수를 생성하여 중복을 제거해보자.

 

function _filter(list, predi) {
  let new_list = [];
  _each(list, function(val) {
    if (predi(val)) new_list.push(val);
  });
  return new_list;
}

function _map(list,mapper) {
  let new_list = [];
  _each(list, function(val) {
    new_list.push(mapper(val));
  });
  return new_list;
}

function _each(list, iter) {
  for(let i = 0; i < list.length; i++) {
    iter(list[i]);
  }
  return list;
}

이렇게 중복되는 코드를 제거하고, 명령형 함수들을 감출수록 더 간결하고 에러가 날 확률이 낮은 코드가 된다.


map, filter, foreach 함수가 있음에도 왜 굳이 저런 식으로 함수를 생성해서 사용하는가?

자바스크립트의 내장 함수인 map, filter forEach는 함수가 아니라 메서드이다.
메서드란 순수 함수가 아니고, 객체의 상태에 따라 결과가 달라지는 특징을 갖고 있다.
그래서 직접 만든 함수와는 작은 차이가 있지만, 생각보다 여러 가지 면에서 차이가 있음.

메서드는 객체 지향 프로그래밍이다.
해당 클래스에 정의되어있기 때문에, 해당 클래스의 인스턴스에서만 사용할 수 있다.
즉, map이라는 메서드는 배열이 아니면 사용할 수 없다는 뜻.
애초에 배열에서 사용하려고 map, filter, forEach 같은 함수들을 만든 건데 무슨 말이냐고 할 수 있지만
자바스크립트에는 배열이 아닌데, 배열이라고 여겨지는 유사 배열 객체들이 매우 많다.


예를 들면 제이쿼리 객체!

이렇게만 보면 배열에 index와 length가 있어서 배열로 볼 수도 있지만 사실 이것은 배열이 아닌 유사 배열 객체이다.
이것이 만약 배열이라면, 내장 메서드에 적용했을 때 값이 나타나야 하는데

console.log(
  document.querySelectorAll("*").map(function(node) {
    return node.nodeName
  })
);

document.querySelectorAll(" * ")의 결과가 배열이 아니기 때문에 위와 같은 에러를 받는다.


이것이 객체지향의 특징이다.
해당 클래스에 준비되어 있지 않은 메서드는 사용할 수 없기에, 다형성을 지원하기에 어려운 부분이 있다.

하지만, 위에서 따로 만들었던 함수들은 함수가 기준이 되는 프로그래밍 방법인 함수형 프로그래밍은 함수를 먼저 만들고, 그 함수에 맞는 데이터를 구성해서 함수에게 적용하는 식으로 프로그래밍된다.
작은 차이라고 생각할 수 있는 부분이지만, 이러한 차이로 인해서 굉장히 높은 다형성을 만들 형태가 된다.

function _map(list,mapper) {
  let new_list = [];
  _each(list, function(val) {
    new_list.push(mapper(val));
  });
  return new_list;
}

function _each(list, iter) {
  for(let i = 0; i < list.length; i++) {
    iter(list[i]);
  }
  return list;
}

console.log(
  _map(document.querySelectorAll('*'), function(node) {
    return node.nodeName;
  })
);

기존의 map 메서드에는 사용할 수 없는 것도 함수형으로 프로그래밍으로는 구현할 수 있음.

즉, 순수 함수로 구현하는 것이 기존의 메서드보다 다형성과 실용성 면에서 좋은 부분들이 있다는 것.


커링 currying

커링은 함수와 인자를 다루는 기법으로,
함수에 인자를 하나씩 적용해나가다가 필요한 인자가 모두 채워지면 함수 본체를 실행하는 기법이다.

자바스크립트에서 currying을 지원하진 않지만, 일급 함수가 지원되고 평가 시점을 마음대로 다룰 수 있기 때문에 currying과 같은 기법을 구현할 수 있다.

function _curry(fn) {
  return function(a, b) {
    return arguments.length == 2 ? fn(a, b) : function(b) { return fn(a, b); };
  }
}

let add = _curry(function(a, b) {
  return a + b;
});

let add5 = add(5);
console.log( add5(5) );    // 10

console.log( add(2)(8) );  // 10
console.log( add(6)(4) );  // 10
  • arguments가 2개라면
    • add를 실행했을 때 위의 curry함수가 실행되고 arguments가 2개라면 a, b를 각각 받아서 더해준다.
  • arguments가 2개가 아니라면
    • function(b) { return fn(a, b); };가 add5가 되며, 처음 들어온 인자인 a에 5가 담겨, a에 들어온 상태로 계속 기억되며 클로저가 발생된다.
    • 그리고 다시 한번 add5를 add5(5)로 실행할 때,  function(b)에 5가 들어오면서 맨 처음 저장했던 a를 받아와서 fn(a, b)를 리턴해주면 5 + 5 = 10이 된다.

- 제로베이스 JS 프로젝트 강의

webrtc를 활용한 영상 채팅

https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API

 

WebRTC API - Web APIs | MDN

WebRTC (Web Real-Time Communication) is a technology that enables Web applications and sites to capture and optionally stream audio and/or video media, as well as to exchange arbitrary data between browsers without requiring an intermediary. The set of sta

developer.mozilla.org

  • WebRTC (Web Real-Time Communication)는 웹 애플리케이션과 사이트에서 오디오 및/또는 비디오 미디어를 캡처하고 선택적으로 스트리밍 할 수 있을 뿐만 아니라 중개자 없이 브라우저 간에 임의의 데이터를 교환할 수 있도록 하는 기술이다.
  • WebRTC는 다양한 용도로 사용됩니다. Media Capture 및 Streams API와 함께 오디오 및 비디오 회의, 파일 교환, 화면 공유, ID 관리, DTMF (터치톤 전화 걸기) 신호. 특별한 드라이버나 플러그인 없이 피어 간의 연결이 가능하며, 중간 서버 없이도 종종 가능합니다.
  • 두 피어 간의 연결은 RTCPeerConnection인터페이스로 표시됩니다. 연결이 설정되고 사용하여 열리면 RTCPeerConnection미디어 스트림( MediaStream들) 및/또는 데이터 채널( RTCDataChannel들)을 연결에 추가할 수 있습니다.

 

https://developer.mozilla.org/en-US/docs/Web/API/MediaStream

 

MediaStream - Web APIs | MDN

The MediaStream interface represents a stream of media content. A stream consists of several tracks, such as video or audio tracks. Each track is specified as an instance of MediaStreamTrack.

developer.mozilla.org

  • MediaStream은 오디오, 비디오 트랙으로 구성된 미디어 콘텐츠 스트림입니다.
  • getTrack()을 통해서 MediaStreamTrack 객체를 반환시킬 수 있습니다.
  • MediaStreamTrack은 비디오와 오디오를 구별할 수 있고 트랙을 음소거시킬 수도 있습니다.

 

https://developer.mozilla.org/ko/docs/Web/API/RTCPeerConnection

 

RTCPeerConnection - Web API | MDN

RTCPeerConnection 인터페이스는 로컬 컴퓨터와 원격 피어 간의 WebRTC 연결을 담당하며 원격 피어에 연결하기 위한 메서드들을 제공하고, 연결을 유지하고 연결 상태를 모니터링하며 더 이상 연결

developer.mozilla.org

  • RTCPeerConnection 인터페이스는 로컬 컴퓨터와 원격 피어 간의 WebRTC 연결을 담당하며 원격 피어에 연결하기 위한 메서드들을 제공하고, 연결을 유지하고 연결 상태를 모니터링하며 더 이상 연결이 필요하지 않을 경우 연결을 종료합니다.
  • MediaStream으로 제작된 내용을 클라이언트 간에 연결을 하여 스트리밍 서비스를 제공해줄 수도 있습니다.

 

https://developer.mozilla.org/en-US/docs/Web/API/RTCSessionDescription

 

RTCSessionDescription - Web APIs | MDN

The RTCSessionDescription interface describes one end of a connection—or potential connection—and how it's configured. Each RTCSessionDescription consists of a description type indicating which part of the offer/answer negotiation process it describes

developer.mozilla.org

  • RTCSessionDescription인터페이스는 연결 또는 잠재적 연결의 한쪽 끝과 구성 방법을 설명합니다 
  • RTCSessionDescription 객체는 setLocalDescription()이라는 함수를 사용해서 로컬을 설정하고 수신 측의 signaling 채널로 보낼 수 있습니다.

 

https://developer.mozilla.org/ko/docs/Web/API/WebRTC_API/Signaling_and_video_calling

 

Signaling and video calling - Web API | MDN

WebRTC 는 리얼 타임 음성, 영상, 데이터 교환을 할 수 있는 완전한 p2p 기술이다. 다른 곳에서 논의한 것 처럼 서로 다른 네트워크에 있는 2개의 디바이스들을 서로 위치시키기 위해서는, 각 디바

developer.mozilla.org

  • 서로 다른 네트워크에 있는 2개의 디바이스들을 서로 연결하기 위해 하는 프로세스를 signaling이라 부릅니다.
  • 각 디바이스들을 상호 간에 동의된 서버(socket.io 혹은 websocket을 이용한 서버)에 연결시킵니다.

 

https://developer.mozilla.org/en-US/docs/Web/API/Navigator

 

Navigator - Web APIs | MDN

The Navigator interface represents the state and the identity of the user agent. It allows scripts to query it and to register themselves to carry on some activities.

developer.mozilla.org

  • navigator.mediaDevices : 사용 가능한 미디어 장치에 대한 정보를 가져오고, 사용자 컴퓨터 및 사용자 에이전트의 미디어에 대해 지원되는 제한 가능한 속성을 찾고, 사용하여 미디어에 대한 액세스를 요청 MediaDevices하는 데 사용할 수 있는 개체에 대한 참조를 반환합니다
  •  MediaDevices.getUserMedia() : 이 메서드 는 요청된 미디어 유형이 포함된 트랙 을 생성하는 미디어 입력을 사용할 수 있는 권한을 사용자에게 묻습니다
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
  /* use the stream */
})
.catch(function(err) {
  /* handle the error */
});

 

Function.prototype.bind() : 이 bind() 메서드는 호출될 때 this키워드가 제공된 값으로 설정되고 새 함수가 호출될 때 제공된 인수 앞에 주어진 인수 시퀀스가 ​​있는 새 함수를 만듭니다.

window.URL.createObjectURL :
-
고유한 blob URL을 포함하는 문자열을 반환합니다. 즉, URL blob:은 스키마로 사용되며 그 뒤에 브라우저에서 개체를 고유하게 식별하는 불투명 문자열이 따라옵니다.
- URL.createObjectURL() 정적 메서드는 매개변수에 지정된 개체를 나타내는 URL이 포함된 문자열을 만듭니다.

window.URL.revokeObjectURL() : 이전에 만든 개체 URL을 취소합니다


학습한 코드를 실행하였더니, 처음부터 에러가 떠서 실행이 되지 않았음.

코드를 살펴보니, MediaDevices.getUserMedia() 메서드에서 user권한을 요청받는 것인데,
user가 audio와 video 권한을 수락한다면 videoAudio를 인자로 넘겨 success를 실행시키는 함수이다.

인자로 넘겨받은 videoAudio가 무엇인가 하면

사용 가능한 미디어 장치에 대한 데이터가 들어있는 값이다.


나도 해당 api들을 사용해본 적이 없어서, 공식문서를 참조하며 에러를 수정하였다.
우선 에러를 해석해보았음. 

typeError : Failed to execute 'createObjectURL' on 'URL' : Overload resolution failed

typeError: 'URL'에서 'createObjectURL' 실행 실패: 과부하 해결 실패

createObjectURL에 대해 알아보기 위해서 mdn에 들어가 보았다.
https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL

 

URL.createObjectURL() - Web APIs | MDN

The URL.createObjectURL() static method creates a string containing a URL representing the object given in the parameter.

developer.mozilla.org

그리고, 이러한 경고문구를 발견하였음.


그렇다면 어떻게 해야 할까? 
https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/srcObject

 

HTMLMediaElement.srcObject - Web APIs | MDN

The srcObject property of the HTMLMediaElement interface sets or returns the object which serves as the source of the media associated with the HTMLMediaElement.

developer.mozilla.org

해당 코드와 같이 코드를 리팩터링 해보자.

success(audioVideo) {
      this.btnRecord.removeAttribute('disabled')
      window.stream = audioVideo
      if ('srcObject' in this.playedVideo) {
        this.playedVideo.srcObject = audioVideo
      } else {
        this.playedVideo.src = window.URL.createObjectURL(audioVideo)
      }
    }

이렇게 해주었더니, 에러 없이 잘 작동한다.

700기존의 error 났던 화면
에러 수정 후, 초기 렌더 화면

 

에러 수정 후,  녹화하여 재생한 화면


- 컴퓨터 공학 CS50


저녁 회고 (만족도: 9)

이번 js 프로젝트를 학습하면서, 잘 몰랐던 api도 에러가 나면 docs를 통해 에러를 수정할 수 있는 나를 보며
그래도 조금씩 성장하고 있다는 생각에 뿌듯하고 만족스러운 시간이었다.
조금 더 다양한 api들을 학습하고 실습해보고 싶다는 생각이 들었다.
조만간 개인적인 포폴용 블로그 또는 간단한 토이 프로젝트를 구상해서 조금씩 만들어 볼 계획이다.

저녁에는 2-3시간이라서 그런지 집중력이 괜찮은 편인데, 오후에는 너무 집중을 못한다.
내일부터는 조금 더 집중을 하도록 하자. 차라리 3시간 학습 -> 1시간 휴식 -> 3시간 학습 이런 식으로라도 해보자.
순간 집중력?을 기르려고 노력해보자.


[ 출처 : JavaScript 알고리즘 & 자료구조 마스터클래스,
자바스크립트로 알아보는 함수형 프로그래밍 (ES5) ]

728x90

'TDL' 카테고리의 다른 글

[TDL] 07/21 Today's-Done-List  (0) 2022.07.22
[TDL] 07/20 Today's-Done-List  (0) 2022.07.21
[TDL] 07/18 Today's-Done-List  (0) 2022.07.18
[TDL] 07/17 Today's-Done-List  (0) 2022.07.17
[TDL] 07/16 Today's-Done-List  (0) 2022.07.17