Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[오혜성] 챕터 5: 최신 자바스크립트 문법과 기능 #29

Merged
merged 1 commit into from
Oct 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 177 additions & 0 deletions 챕터_5/오혜성.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
# 최신 자바스크립트 문법과 기능

## 모듈

- ES6 (2015)

- 책에서 나오는 예제 중, 아래 방법이 있는데
가능한 것은 알겠지만 좋다고는 생각이 들지 않음

```js
const foo;
const bar;
const baz;

export {foo, bar, baz};
// 선언한 곳에서 해당 요소가 내보내지는 요소인지 알 수 있는 방법이 인지하기 더 쉽다고 생각함
// ex. export const foo;
```

- nomodule
```js
<script nomodule />
```
- 브라우저에 모듈이 아님을 알려줌
- 폴리필에 유용

- 외부 소스 모듈

```js
import { something } from 'https://module.foo.com';
```

- 동적으로 모듈 가져오기

```js
const onClick = () => {
const module = await import("/module");
module.foo('dynamic');

// default export는?
module.default('여기');
}
```

- 요청된 모듈의 네임스페이스 객체에 대한 프로미스 객체를 반환
- 이 프로미스 객체는 모듈 자체와 모든 모듈 의존성을 가져온 후
- 인스턴스화하고 평가한 뒤에 만들어짐


> 여기서 말하는 인스턴스화와 평가는 어떤 것일까?
>
> 인스턴스화
> > 스코프를 만들고, 선언된 것들에 대한 바인딩이 생성
> > 해당 시점에서는 값이 할당되지 않음
> > 즉 코드 실행은 일어나지 않고, 구조만 준비됨
>
> 평가 (Evaluation)
> > 모듈의 코드가 위에서 아래로 순차적으로 실행
> > 변수 값 할당, 함수 본문 생성, 클래스 정의 등
> > 해당 과정은 모듈이 처음 로드될 때 한 번만 실행, 이후 같은 모듈을 다시 import하더라도 평가된 결과를 재사용함

```js
// module.js
export let count = 0;
export function increment() {
count++;
}

// main.js
import { count, increment } from './module.js';
console.log(count); // 0
increment();
console.log(count); // 1

import { count as newCount } from './module.js';
console.log(newCount); // 1 (같은 인스턴스를 참조)
```

> https://javascript.info/modules-intro#a-module-code-is-evaluated-only-the-first-time-when-imported
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules
> https://javascript.info/modules-intro#module-level-scope

- 화면에 보이면 가져오기
- IntersectionObserver
> 다들 추상화한 훅을 만들어 사용하시겠지만..
> framer-motion을 사용하시면 useInView 훅이 있음
> https://www.framer.com/motion/use-in-view/?srsltid=AfmBOoqABYI17UD24TzhmtKKwAoNVbfo1TSe5rE_rhXwIYSaigNSK0q_
>
> 내부적으로 IntersectionObserver와 WeekMap으로 최적화함
>
> https://github.com/framer/motion/blob/main/packages/framer-motion/src/utils/use-in-view.ts
> https://github.com/framer/motion/blob/main/packages/framer-motion/src/render/dom/viewport/index.ts
Comment on lines +83 to +92
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오오 유용한 정보 감사합니다 👍


## 모듈의 이점

- 한 번만 실행
- 기본 `<script>`는 DOM에 추가될 때마다 실행되지만, 모듈 스크립트는 한 번만
- 의존성 트리의 가장 내부에 위치한 모듈이 먼저 실행됨

- 자동으로 지연 로드
- `<script defer>` 안해도 됨

## 클래스

- ES6부터 지원

- 게터, 세터

```js
class Foo {

set setName (name) {
this.name = name;
}

get getName() {
return this.name;
}
}
```

- TC39에서 function 키워드의 남용을 줄이려고 노력했다고 함
> 왜?
> 현대적이고 표현력있는 언어로 발전시키고 싶었다고 함

- private
- `#`으로 비공개 멤버를 만들 수 있음
- `private` 키워드와의 차이점은?


> `private` 키워드는 타입스크립트에서만 지원
> 자바스크립트로 트랜스파일되면 private 키워드는 없어짐

> `#`은 `private`과 다르게 상속된 클래스에서도 접근할 수 없음
```js
class Animal {
#name;
private age;
}

class Dog extends Animal {
function foo () {
this.#name; // can't
this.age; // can
}
}
```

- 정적 멤버

```js
class Foo {
static name = 'foo';
}

Foo.name; // foo
```

> OpenAPI를 이용해서 api 유틸 생성을 자동화한 경험이 있는데
> https://heyapi.dev/
> 이 도구는 정적 메서드를 이용한 클래스로 만들지 옵션을 제공
>
> 사용하는 곳에서 맥락을 이해하기 쉬울 거 같아서, 사용하고 있음

```js
class AdminController {
static function getName() {}
}

class MentorController {
static function getMentorInfo() {}
}

// 사용하는 곳에서
const foo = await MentorController.getMentorInfo();
```

Loading