비전공 프론트엔드 2년차 개발자 멘티 일지: 1주차 - 으아 떨려...
독학으로 공부를 계속하다 회사에 다닌 지 1년이 넘은 현시점에서, 스스로를 객관적으로 돌이켜보기 위해서 멘토링을 신청하게 되었다!
멘토링을 하면서 느낀 경험을 1주일 단위 회고 형식으로 진행해보려 한다.
첫 번째 주차의 회고를 진행해보겠다 (24.04.30 ~ 24.05.06)
일단.. 다시 공부가 필요한 것들 복습하자
돌이켜 생각해보면 잘 몰랐던 것들은 계속 모르거나 헷갈리고 있다. (나 자신을 똥 멍청이라 생각한다ㅠ.. 그래도 천재가 되기 위해서 차근차근 복습해보자)
깊은 복사와 얕은 복사의 차이
얕은 복사(Shallow Copy)는 원본 객체의 최상위 수준의 속성들을 복사하고, 내부의 객체는 참조를 공유한다. 즉, 내부 객체에 대한 변경은 복사된 객체와 원본 객체 양쪽에 모두 영향을 주고, 최상위 수준의 속성이 필요한 경우에 사용한다.
- Object.assign()을 이용한 얕은 복사
const item = {
a: '메론',
price: {
small: '20000',
large: '30000',
},
};
const copyItem = Object.assign({}, item);
copyItem.price.small = '22000';
console.log(item === copyItem); // false
console.log(item.price.small === copyItem.price.small); //true
- Spread 연산자를 이용한 얕은 복사
const item = {
a: '메론',
price: {
small: '20000',
large: '30000',
},
};
const copyItem = { ...item };
console.log(item === copyItem); // false
console.log(item.price.small === copyItem.price.small); //true
깊은 복사(Deep Copy)는 원본 객체의 모든 속성들을 재귀적으로 복사해 원본 객체와 완전한 독립이다.(원본과의 참조가 완전히 끊어진 객체) 내부 객체까지 새로운 객체로 복사되어, 다른 객체에 영향을 주지 않고 복잡한 구조를 가진 객체를 다루기위해 사용한다.
- JSON.parse, JSON.stringify를 이용한 깊은 복사
const item = {
a: '메론',
price: {
small: '20000',
large: '30000',
},
place: ['강남점', '역삼점', '송파점'],
};
const copyItem = JSON.parse(JSON.stringify(item));
copyItem.price.small = '24000';
copyItem.place.push('잠실점');
console.log(item === copyItem); //false
console.log(item.price.small === copyItem.price.small); //false
console.log(item.place === copyItem.place); //false
console.log(item); // {"a": "메론","price": {"small": "20000","large": "30000"},"place": ["강남점","역삼점","송파점"]}
console.log(copyItem); // {"a": "메론","price": {"small": "24000","large": "30000"},"place": ["강남점","역삼점","송파점","잠실점"]}
- 재귀 함수를 이용해 깊은 복사
- lodash 라이브러리 cloneDeep 사용 해서 깊은 복사
왜 모던 웹에서 불변성을 지켜야할까?
내가 뭐라고 했는지 정확히 기억나지 않지만, 불변성을 지켜야 의도하지 않은 데이터 변경을 막을 수 있다고 했던 것 같다. 비슷하긴 하지만 찾아보니 더 다양한 내용이 있다는 걸 알게되었다~!
- 불변성을 유지하면 상태 변경을 추적하고 이전 상태로 되돌리는 것이 수월해 관리하는 데 도움이 된다.
- 불변성을 유지하면 코드의 동작이 예측 가능해 디버깅에 수월하다.
- 불변성 덕분에 변경이 없는 객체 또는 배열을 공유할 수 있고, 메모리를 절약해 변경 감지를 위한 추가적인 비용을 줄일 수 있다.
- 불변성은 다중 스레드 환경에서 데이터 공유를 안전하게 만들기 때문에, 여러 스레드가 동시에 데이터를 변경하려고 할 때와 같이 예기치 않은 결과를 방지하고 동기화 문제를 피할 수 있다.
- 순수 함수(동일한 입력에 대해 항상 동일한 출력을 반환하는 함수이다. 외부 상태에 의존하지 않고, 상태를 변경하지 않아 영향을 미치지 않아서 부작용이 없다)와 함께 사용 가능하다.
실행 컨텍스트에 대해서
실행 컨텍스트 공부 엄청했다ㅠㅠ.. 그런데 말을 못하겠어.. 일단 영어단어도 너무너무 어렵고.. 하지만 더 공부해서 그림까지 완벽하게 그려보도록 하겠다.
해당하는 자료들은 책에도 너무너무 많고. 동영상도 너무 많다. 내가 여기에 기록하지 않고 좋은 자료를 첨부하도록 하겠다! => 솔직히 이거 2개만 다 이해하면 당신은 JS엔진
콜 스택과 실행 컨텍스트는 어떤 연관이 있을까??
실행 컨텍스트와 콜 스택은 서로 상호 작용하여 코드의 실행 흐름을 관리한다. 함수가 호출되면 해당 함수의 실행 컨텍스트가 콜 스택에 푸시(Push)되고, 해당 함수의 실행이 완료되면 콜 스택에서 팝(Pop)된다. 이러한 과정을 통해 자바스크립트 엔진은 코드의 실행 순서를 유지하고 실행 중인 함수의 상태를 추적한다.
실행 컨텍스트는 실행 환경을 추상화하고 관리하며, 콜 스택은 실행 중인 실행 컨텍스트의 순서를 관리하여 코드의 실행 흐름을 유지
자바스크립트 한 함수의 생명주기 (with 실행 컨텍스트)
생성(Create) => 호출(Call) => 실행(Execute) => 완료(Complete)
함수가 정의되어, 메모리가 로드되고 함수 객체가 생성된다. 함수 객체는 코드와 스코프 체인을 포함한 실행 컨텍스트를 생성 (생성)
함수가 호출되면 새로운 실행 컨텍스트가 생성되는데, 이 실행 컨텍스트는 함수의 변수, 매개변수, 스코프 체인 등을 포함하며, 콜 스택에 푸시된다. (호출)
실행 컨텍스트가 활성화되면 함수의 코드가 실행되고, 그 동안 변수의 값이 변경되고, 새로운 함수가 호출되거나 반환될 수 있다. (실행)
함수의 실행이 완료되면 실행 컨텍스트가 콜 스택에서 팝되고, 메모리에서 제거되어 함수의 결과가 반환됨 (완료)
이벤트 루프(Event Loop)
콜 스택과 백그라운드(Task Queue 또는 Microtask Queue)를 모니터링하고, 이벤트 루프가 비어있을 때 백그라운드에서 실행된 작업(Task Queue)을 콜 스택으로 이동시켜주는데, Task Queue에 있는 작업들은 비동기적인 작업의 결과뿐만 아니라, 이벤트 핸들러나 타이머 콜백 등도 포함된다.
또한 마이크로테스크 큐(Microtask Queue)를 모니터링하여 콜 스택의 작업이 완료된 후에 마이크로테스크를 우선적으로 처리합니다.
마이크로테스크와 매크로테스크 차이점은??
솔직히!! 콜스텍에 대해서 공부하면서 보았는데..ㅠㅠ 말로 대답하려니 엄~~청 햇갈려서 대답 못했다ㅠㅠ.. 다시 복습하자!!!
우선 마이크로테스크(Microtask)와 매크로테스크(Macrotask)는 자바스크립트 비동기 처리에 사용되는 용어다!
실행 시점의 차이
- 매크로테스크: 매크로테스크는 브라우저의 이벤트 루프에서 처리되는 비동기 작업으로, 주로 큐(Queue)에 들어간 이벤트 핸들러(DOM 이벤트 핸들러)나 타이머 콜백(setTimeout, setInterval) 등이 해당된다.
- 마이크로테스크: 매크로테스크보다 더 높은 우선순위를 가지며, Promise의 then, catch, finally 메서드와 같은 비동기 작업이 해당된다. 마이크로테스크는 현재 매크로테스크 큐의 처리가 끝나고 다음 태스크를 실행하기 전에 처리된다.
실행 순서의 차이
- 매크로테스크: 이벤트 루프의 한 사이클이 완료된 후에 실행된다. 현재 실행 중인 코드 블록이 완료되지 않아도 처리된다.
- 마이크로테스크: 매크로테스크보다 더 높은 우선순위를 가지므로, 현재 실행 중인 코드 블록이 완료된 후에 처리된다. 따라서 마이크로테스크는 매크로테스크보다 먼저 실행됩니다.
스코프체인과 스코프
스코프(Scope)는 변수와 함수에 대한 접근성 및 가시성을 결정하는 개념으로 자바스크립트에서는 스코프를 정적으로 지정한다. 코드가 실행되기 전에 어디서 변수나 함수에 접근할 수 있는지 결정된다. 스코프는 코드의 블록(함수, if문, for문 등) 내에서 변수와 함수에 접근할 수 있는 범위를 정의한다.
스코프체인(Scope Chain)은 변수와 함수에 대한 접근을 결정하기 위한 메커니즘으로, 변수나 함수를 참조할 때 해당 식별자를 검색하는 순서를 결정한다. 일반적으로 스코프체인은 현재 실행 중인 컨텍스트의 변수 객체와 그 부모 컨텍스트의 변수 객체를 연결한 체인이다.
간단하게 생각하면 스코프는 해당 코드의 범위를 의미 하고 스코프체인은 자기 자신의 스코프를 제외한 자신과 가장 가까운 변수 객체의 모든 스코프들이라고 생각한다!
함수 스코프와 블록 스코프
내가 뭐라고했더라.. ㅋㅋㅋ 함수선언 내부 범위가 함수 스코프고 블록 스코프는 함수를 제외한 변수, 객체의 내부 범위가 블록 스코프라고 했다. 뭐 얼추만 비슷하기에 정확히 알아보자!
함수 스코프는 변수가 선언된 함수 내에서만 유효한 스코프로 함수 내에서 선언된 변수는 함수 내에서만 접근할 수 있다. 함수 스코프 내부에서 선언된 변수는 내부에서만 유효하기 때문에 함수 외부에서는 접근할 수 없다
블록 스코프는 변수가 선언된 블록 내에서만 유효한 스코프로, 블록은 중괄호 {}로 묶인 코드 영역을 의미한다. 블록 스코프는 주로 if, for, while과 같은 제어문의 블록 내에서 변수를 선언할 때 사용되고 블록 스코프 내부의 변수는 블록 내에서만 유효하면 블록 외부에서는 접근할 수 없다
간단하게 요약하면 함수 스코프는 변수가 선언된 함수 내에서만 유효하고, 블록 스코프는 변수가 선언된 블록 내에서만 유효하다.
생성자 함수의 this, 메서드의 this
메서드(Method)에서의 this는 해당 메서드가 속한 객체를 가리키고 메서드가 호출된 객체에 바인딩된다. 이를 통해 메서드는 자신이 속한 객체의 속성에 접근할 수 있다.
const obj = {
name: 'Jihoon',
greet: function () {
console.log('Hello, ' + this.name);
},
};
obj.greet(); // 출력: "Hello, Jihoon"
생성자 함수(Constructor Function)에서의 this는 새로 생성되는 객체를 가리킨다. 생성자 함수는 new 키워드를 사용하여 호출될 때마다 새로운 객체가 생성되고, 이 객체가 this에 바인딩된다.
function Person(name) {
this.name = name;
this.greet = function () {
console.log('Hello, ' + this.name);
};
}
const Jihoon = new Person('Jihoon');
Jihoon.greet(); // 출력: "Hello, Jihoon"
일급 함수(First-class Function)
사이드 이팩트가 없고 부작용이 없는 순수함수는 들어보았지만, 1급 함수에 대한 개념은 잡혀있지 않았다. 과연 뭘까?
일급 함수는 프로그래밍 언어에서 함수를 일반 값과 동등하게 취급하는 것을 의미하고 아래 조건을 만족한다.
1. 변수에 할당하여 함수를 변수로 사용할 수 있다.
const myFunc = function () {
console.log('Hello, world!');
};
myFunc(); // 출력: "Hello, world!"
2. 함수를 다른 함수의 매개변수로 전달할 수 있다.
function greet(func) {
func();
}
greet(function () {
console.log('Hello, world!');
}); // 출력: "Hello, world!"
3. 함수가 다른 함수의 반환값으로 사용될 수 있다.
function createFunc() {
return function () {
console.log('Hello, world!');
};
}
const myFunc = createFunc();
myFunc(); // 출력: "Hello, world!"
5월 첫째 주 회고
멘토링 처음 받아본 한주 회고 시작!
이번 주 좋은 것과 나쁜 것
- 휴일이 많아서 회사에서 못한 부분을 개인 시간에 진행할 수 있었다.
- 멘토링을 본격적으로 시작하기전 사람들과 사람들을 많이 만나고, 이야기를 나누는 시간을 가져서 체력적으로 좀 피곤했다.
이번주 진행했던 학습/개발 내용은??
- 사내의 Devextreme 으로 구성된 것을 Mui + react-hook-form + zod 를 이용하는 것으로 바꾸고 있으며, Custom UI를 만들고 있다.
- 사내 동료들에게 실행컨텍스트, 콜스택, 클로저의 개념에 대해서 발표하는 시간을 가졌다.
- 코어 자바스크립트 1~3장 읽으며 멘토링을 준비하였다.
가장 고민했던 부분은 무엇이었나요?
- 제네릭을 효율적으로 쓰는 방법? 그리고 어떠한 상황에 써야 되는지 고민 진행 중입니다.
- 사내 프로젝트에서 상태관리가 너무 복잡하게 되어있어서, 이것을 top-down, bottom-up 방식을 동시에 써야 할지 고민 중입니다.
- 동아리에서 youdontknowjs 의 클로저 부분을 읽고 자료를 정리해야 되는데, 어떤 내용을 중점으로 다룰지 고민 중입니다.
아쉬운 부분을 개선하는 데 필요한 것은 무엇인가요?
- 어떤 것을 집중해서 맡은 것을 끝내려는 집중력이 필요합니다.
- 여러 가지를 동시에 해내는 것은 불가능하다고 생각하니, 여유를 가지는 것도 중요하다고 생각합니다
- 다양한 회사에서 원하는 JD 파악을 해야 합니다.
다음 주는 어떻게 보낼 예정인가요?
- 멘토링이 끝난 당일과 다음날은 복습 위주로 진행할 것입니다
- 동아리에서 맡은 역할이 있어서 해결할 예정입니다. (클로저, react hook에 대한 자료정리)
- 동아리에서 진행하는 행사 계획에 대한 회의를 진행할 것 입니다
- 앞의 복습내용을 바탕으로 코어 자바스크립트 4~6장을 읽을 예정입니다
- 5/9 우당탕탕 책방이라는 모임에서 CSS 라이브러리에 관한 이야기를 진행해서 준비할 예정입니다.
메타인지
메타인지를 위해서 자기평가를 진행해보았다. 내가 어떠한 사람이 되고 싶을까? 생각했을 때 모든 형태가 고르게 있는 것도 중요하겠지만 기술적인 부분과 팀 내부의 역할(역량)을 키우는 것이 내 성향에 적합하다고 생각한다.
해당하는 메타인지하는 사이트는 여기를 참고하면 됩니다👇👇
자기 객관화에 짱이다..
Technology - Evangelizes: 연구 조사, 개념 증명(POC)을 만들고, 새로운 기술을 팀에 소개
- 사내 기술 스터디 운영중
- 외부 활동으로 스터디 하는 내용들 사내에 공유 및 개인 시간에 사내 로직 적용해보고 회의를 통해 기술 도입(react-hook-form, react-query, zustand, zod, uuid v4 등등)
- 사내에서 발생한 일(빌드 속도, 오류, 캐싱, 성능)을 파악해서 정리 ⇒ 발생할 수 있는 이유를 분석 ⇒ 개선점 분석 후 FE 사수에게 제안 ⇒ 팀 발표 진행
- 시스템에서 맡은 부분의 지식은 있지만, 접근해보지 않은 Socket, Qr, DocuSign, DevOps Tool, Server, Network에 대한 이해도가 낮음
- 추구하는 방향은 Creates입니다. 팀에서 사용하는 데 문제가 있거나, 더 좋은 성능과 효과를 위해서 진행할 수 있는 방향이 있으면 제안하고 디자인하고 만들 의향이 있고, 제가 추구하는 공동의 편의성에 적합한 개념이라고 생각합니다
System - Designs: 중형에서 대형 사이즈의 기능을 기술 부채를 제거하면서 디자인하고 구현
- 사내에 도입되어있는 devextreme를 제거해 디자이너와 MUI를 이용한 디자인시스템 논의 후 구현
- 사내에서 사용하는 jQuery 문법으로 동작하는 DOM 직접 접근 방식을 Virtual DOM을 이용해 접근하도록 코드 수정하고 라이브러리 충돌 문제 해결
- 하지만 프로덕션의 운영을 해본 경험과 결정에 대한 책임 경험 없음
- 추구하는 방향은 Evolves입니다. 미래의 요구사항을 미리 파악하거나, 대응할 수 있도록 넓은 시야를 가져서 빠르고 정확하게 대응하고 싶습니다.
People - Supports: 다른 팀원들을 적극적으로 지원하고 성공할 수 있도록 돕습니다
- 사실 Mentors와 고민을 했습니다. 사내에 FE에 신입 2명이 입사해서, 하지만 Mentor로 정확히 명하기 어렵고, 제가 공부한 내용에 대한 가이드 역할만 해주어서 Supports를 선택했습니다.
- 제가 이 역할에서 Manages가 되고 싶습니다. 사람의 역량을 끌어올리고, 분배하고, 공동의 목표를 긍정적인 방향으로 진행하는 것을 추구하기 때문입니다.
- 지금은 팀원에게 방향을 잡아주고 적응을 할 수 있도록 안내해주고 있습니다.
Process - Challenges: 팀 프로세스를 개선할 수 있는 방법을 찾고 시도해봅니다.
- 사내 입사했을 때 개발에 관한 Jira & Atlassian의 체계가 잡혀있지 않았습니다. 배포하는 과정, 테스트 과정, 개발하는 과정의 시간 시점을 분리하는 것을 제안하였고, 각자의 역할에 대해 분석해 발표를 진행했습니다.
- putty를 이용해 배포하는 과정에서 많은 시간이 소비되는 문제점을 파악했습니다. 해당 과정을 변경하는 작업을 사내에서 진행했습니다.
- 추구하는 방향은 Adjusts입니다. 서로 대화를 통한 피드백으로 공동의 프로세스의 긍정적 방향을 위해 조정하고 제안하고 싶습니다. 이러한 변화를 통해 불필요한 시간을 사전에 제거하고 더 많은 소통의 환경을 만들고 싶습니다
Influence - Team: 특정 부분만이 아니라 팀 전체에 영향을 끼칩니다
- 사내는 nodejs 기반이다. 백앤드는 nest, 프론트엔드는 react/vite 바쁘거나, 코드의 문제점이 있으면 백앤드 코드를 살펴보고 백앤드에 제안을합니다. 그런 과정을 통해 문제해결 시간을 단축합니다.
- Figma, XD를 다뤄본 경험이 있습니다. 이를 토대로 디자이너, 퍼블리셔에게 요구사항을 전달할 때 보다 필요하지 않은 시간 소비를 최대한 줄인 채로 문재해결을 진행하고 있습니다.
- 추구하는 방향은 Community입니다. 사내에서뿐만 아니라 개인적으로 선호하는 기술스택(vanilla-extract, zustand)등 과 같은 다양한 개발 생태계에 관심을 가지고 참여하고 싶습니다.