[내일배움캠프 TIL] 25일차

Jaehyeon Ye·2022년 12월 2일
0

오늘 새로 배운 것

map 메서드

콜백함수에 있는 함수 내 로직을 배열의 첫번째 요소부터 돌리면서 새로운 객체를 return

클로져(Clojure)

MDN에서 클로저의 정의
=> 함수와 그 함수가 선언된 렉시컬 환경과의 조합

렉시컬 스코프(Lexical Scope)

JS 엔진은 함수를 어디서 '호출(실행)'했는지가 아니라 함수를 어디 '정의'했는지에 따라 상위 스코프를 결정한다.

또한, JS는 함수 기준으로 스코프를 생성하지 중괄호{} 기준으로 생성하지 않는다.

그럼 클로저 대체 왜 써야되나???

상태를 안전하게 변경하고 유지하는 JS의 강력한 기능이기 때문에 필요하다면 적극 활용해야한다.
의도치 않는 상태 변경을 막기 위해서(상태를 안전하게 은닉한다) 닫아서 지킨다. 뭘 지킨다? 상태를.
내가 이해한대로라면, 상위 스코프의 전역변수에 의해 중간에 얼마든지 상태가 바뀔 수 있고 전역변수를 쓰지 않고 함수 내 지역변수로 상태를 관리하려고 한다면 상태를 리턴후 다시 상위 함수를 호출될 때 다시 선언, 할당된 상태로 초기화되는 문제가 있다.

즉시 실행함수

const counter = (function () {
  let counter = 0; 
  return function (aux) {
    counter = aux(counter); 
    return counter;
  };
})();

위의 경우와 같이 상태를 리턴하는 대신, 상위 함수 안에 있는 하위 함수를 즉시 실행함수 형태로 감싼 뒤 상위 함수가 하위 함수를 리턴하게 하고 하위 함수가 콜 스택에서 빠진 상위 함수 실행 컨텍스트의 렉시컬 환경에 유지되어있는 상태를 참조함으로써 문제를 해결할 수 있다.

함수형 프로그래밍 특징

외부 상태 변경이나 가변 데이터를 피하고 불변성 지향
외부 상태의 변경으로 프로그램 오류 날 수 있음
예상치 못한 외부 영향 오류 피하고 프로그램 안정성을 높일 수 있음
그래서 클로저를 활용

// 함수를 인수로 전달받고 함수를 반환하는 고차 함수
// 이 함수는 카운트 상태를 유지하기 위한 자유 변수 counter를 기억하는 클로저를 반환한다.
function makeCounter(aux) {
  // 카운트 상태를 유지하기 위한 자유 변수
  let counter = 0;
  // 클로저를 반환
  return function () {
    //인수로 전달받은 보조 함수에 상태 변경을 위임한다.
    counter = aux(counter);
    return counter;
  };
} // 보조 함수
function increase(n) {
  return ++n;
}
// 보조 함수
function decrease(n) {
  return --n;
}
// 함수로 함수를 생성
// makeCounter함수는 보조 함수를 인수로 전달받아 함수를 반환한다.
const increaser = makeCounter(increase);
console.log(increaser());
console.log(increaser());
// increaser 함수와는 별개의 독립된 렉시컬 환경을 갖기 떄문에 카운터 상태가 연동되지 않는다.
const decreaser = makeCounter(decrease);
console.log(decreaser());
console.log(decreaser());
// 그럼 어떻게 해야 하나요?
// -> key : makeCounter 함수를 1번만 호출할

위의 코드에서의 문제점은 새롭게 반환하는 클로저가 각각 독립적인 렉시컬 환경을 가지고 있어 increase, decrease 함수의 상태 공유(연동)가 안됨

// 함수를 인수로 전달받고 함수를 반환하는 고차 함수
// 이 함수는 카운트 상태를 유지하기 위한 자유 변수 counter를 기억하는 클로저를 반환한다.
const counter = (function () {
  // 카운트 상태를 유지하기 위한 자유 변수
  let counter = 0; //counter에 즉시 실행함수를 넣어서 리턴을 바로
  // 클로저를 반환
  return function (aux) {
    //인수로 전달받은 보조 함수에 상태 변경을 위임한다.
    counter = aux(counter); //aux라는 인수로 전달받은 함수가 들어가는 클로저가 반환
    return counter;
  };
})();
// 보조 함수
function increase(n) {
  return ++n;
}
// 보조 함수
function decrease(n) {
  return --n;
}
// 함수로 함수를 생성
// makeCounter함수는 보조 함수를 인수로 전달받아 함수를 반환한다.
console.log(counter(increase));
console.log(counter(increase));
// 자유 변수를 공유
console.log(counter(decrease));
console.log(counter(decrease));

클로저를 반환할 때 increase와 decrease를 한꺼번에 반환할 수 있게 counter 함수로 호출

캡슐화(Encapsulation)

프로퍼티 : 객체 상태
메서드 : 프로퍼티를 참조하고 조작할 수 있는 동작
객체 내부의 특정 프로퍼티나 메서드를 감추는 것

객체의 상태변경 방지함으로 정보 보호
객체 간 의존성(결합도 - coupling) 낮춤

인스턴스의 프로퍼티 값을 함부로 열람하거나 수정하지 못하도록하는 것
JS의 필드는 기본적으론 public(은닉x)

public 필드를 private 필드로 만드는 방법

필드명 앞에 #을 붙임
constructor에만 하면 안되고 클래스 바로 안쪽 처음에 정의해야함

this를 쓰는 이유를 알았다

function Person(name, age) {
  this.name = name; //public
  let _age = age; //private
  this.sayHi = function () {
    console.log(`Hi! My name is ${this.name}. I am ${_age}.`);
  };
}
const me = new Person('Choi', 33);
me.sayHi(); // Hi!, My name is Choi. I am 33.
console.log(me.name); // Choi
console.log(me._age); // undefined
const you = new Person('Lee', 30);
you.sayHi(); // Hi! My name is Lee. I am 30.
console.log(you.name); // Lee
console.log(you.age); // undefined

위의 코드에서 보듯이, 외부의 생성자 함수에서도 인스턴스를 생성하는 함수의 프로퍼티에 접근할 수 있게 하기 위해서(public) 프로퍼티를 this로 써주는 거였다. 만약에 let으로 프로퍼티를 선언하고 할당했으면 외부 인스턴스에서 이 프로퍼티에 접근할 수 없기 때문에(private) undefined가 나는 거였다


onclick 과 addEventListener

프로퍼티가 덮어씌워지는 문제 때문에 하나의 이벤트에 복수의 핸들러를 할당할 수 없고 이를 해결하기 위한 특별한 메서드로 addEventListener와 removeEventListener(핸들러 삭제)가 나옴. 단, addEventListener같은 메서드를 사용할 때는 요소의 타입을 명시해주어야 함.

(예: element.addEventListener('type', 객체))


OSI 7계층

국제 표준화 기구(ISO)에서 OSI 7계층 모델을 만들어서 네트워크 기본 구조를 가이드
TCP/IP는 5계층 OSI보다 먼저 있었던 검증된 체계고 OSI와 크게 다르지 않은 게 OSI는 TCP/IP보다 계층을 더 세분화한 것. 그래서 TCP/IP를 공부하기 전에 OSI 7계층을 살펴보는 것

1~7계층
물리계층,데이터 링크 계층,네트워크 계층,전송 계층,세션 계층,표현 계층,응용 계층 / physical layerx,data link,network,transport,session,presentation,application
1~4계층() / 5~7계층(응용 계층)

IP주소 - 집주소 / MAC주소 - 장치가 생산될 때 제조사에서 할당해주는 고유번호. LAN카드에 내장된 주소.(주민등록번호 같은 거)

라우터가 ip에 mac주소를 맵핑
네트워크 상에서 IP주소를 가지고 통신하는 것처럼 보이지만 실제로는 네트워크 장비끼리 서로 MAC주소를 알려주면서 연결된다.
네트워크 계층에서 해당 ip면 전송 계층으로 올려준다.

TCP : 오류방지, 데이터 신뢰도 높은 프로토콜
UDP : 데이터 손실이 있더라도(중간에 끊기더라도) 데이터를 지속적으로 전송/비디오

면접에서는 7계층과 TCP/IP의 차이에 대해 물어볼 수 있고 심화적으로 물어볼 수 있음. 패킷이 중요

하루를 돌아보며...

클로저... 뭔가 이해될 것 같으면서도 찜찜한... 계속 보고 보고 하다보면 확실히 이해가 되는 날이 오겠지

profile
FE Developer

0개의 댓글