오늘은 기초적인 내용이지만 헷갈려서 정확히 알지 못했던 변수 사용법에 대해 정리해 보려고 합니다.
상황
자바스크립트 모듈 a.js, b.js, data.js 가 있습니다.
a.js 와 b.js 는 무언가 기능을 하는 친구고
data.js 에는 let fruit = "delicious"; 라는 변수가 export 되었습니다.
각 모듈은 html 에서 type="module" 이 적용된 script 입니다.
궁금증은,
"a.js 에서 import 한 fruit 변수를 재할당 할 경우 그 변동된 값이 b.js 에서도 반영되는가?"
였습니다.
해답
자바스크립트 ES6 모듈(commonJS 는 안된다고 합니다)에서 export로 내보낸 변수는,
라이브 바인딩(live binding)이 적용되기 때문에,
한 모듈에서 변수의 값을 변경하면 이 변경된 값이 다른 모듈에서도 반영된다고 합니다!
즉, export된 변수는 공유되며, 한 모듈에서의 변경사항이 다른 모듈에도 실시간으로 적용된다고 볼 수 있겠습니다.
당연한 내용이었던 것 같지만 이 부분에 대한 확신이 없었는데 확실히 알게 되었습니다.
추가내용
a.js 에서 많은 작업을 하는데, 그 중 foo 라는 객체를 export 했고, b.js 에서 foo 를 import 했습니다.
그런데 b.js 는 a.js 와 다른 html 에 적용되어 있었습니다.
제가 예상한 동작은 a.js 의 많은 내용 중 foo 라는 객체만 import 한 것이기 때문에,
foo 객체만 잘 가져와서 쓸 수 있을 줄 알았습니다.
그런데 a.js 의 다른 기능 중에서 참조 에러가 발생했습니다.
분명 객체 하나만 import 했는데, 다른 기능들도 한번 실행이 되는 것인가?
결론은, 이렇게 특정 객체만 import 해도 a.js 의 다른 부분이 로드되고 실행된다고 합니다.
이럴 경우의 해법은,
1. 모듈화
사용하려던 객체 foo 를 따로 foo.js 를 만들어서 거기에 저장하고 export 한 뒤,
다른 모듈에서 이를 import 해서 쓰면 해당 문제는 사라집니다.
2. 조건적 코드 실행
아래 처럼 특정 페이지에서만 실행할 코드를 묶어주면,
당연히 해결됩니다. 그렇지만 1번 방법이 훨씬 좋아보입니다!
// index.js
if (window.location.pathname.includes('index.html')) {
// index.html 페이지에서만 실행할 코드
}
export const sharedObject = {
key: 'value'
};
=
'javascript' 카테고리의 다른 글
[240507 TIL] Object.is (0) | 2024.05.07 |
---|---|
[240504 WIL] query params (0) | 2024.05.04 |
[240502 TIL] domContentLoaded (0) | 2024.05.02 |
[240501 TIL] AbortController (0) | 2024.05.01 |
[240430 TIL] HTMLCollection, NodeList (0) | 2024.04.30 |