<script>
script 태그는 자바스크립트를 실행시키기 위해 사용하는 태그이다. 태그 내부에 인라인으로 자바스크립트를 작성할 때에는 HTML파싱 순서대로 파싱 및 실행되지만, 만약 외부 스크립트를 연결하고 있는 경우 해당 스크립트를 다운로드, 파싱, 실행 순서로 진행된다.
HTML에서 아무것도 안 붙인 <script>로 외부 자바스크립트 파일을 읽게 될 시, 문서를 파싱하다가 진행하던 파싱을 멈추고 스크립트를 로드 및 실행한 후, 다시 파싱을 진행하게 된다. 각각의 <script>를 만날 때마다 같은 과정이 일어나게 되고, 결국 HTML이 로드되는 시간은 길어지게 된다.
<script async>
하지만 async 속성이 붙으면 script의 로드가 비동기적으로 동작하게 된다. 예를 들어, HTML을 파싱하던 중 async script를 만나게 되면, 파싱을 멈추지 않고 비동기적으로 script를 로드하게 된다. 이후 script가 다운로드가 된 순서대로 실행되고, 이 때는 HTML 파싱 작업이 멈추게 된다.
async의 경우, script가 DOM을 참조하고 있을 때, 아직 파싱이 완전히 끝난 것이 아니므로 해당 요소를 찾지 못하는 오류가 발생할 수 있다. 또한, 실행순서를 컨트롤 할 수 없기 때문에, 스크립트 의존성이 있는 경우에는 async를 사용하지 않는 것이 좋다.
다르게 말하면, 스크립트 의존성이 없고, DOM을 참조하지 않는 스크립트는 오히려 async로 로드하는 것이 더 좋다! 왜냐하면, 일반 script 태그는 스크립트를 만날 때마다, 하던 작업을 멈추고 스크립트를 로드 및 실행하기 때문이다.
<script defer>
script에 defer 속성이 붙게 되면, async의 경우와 마찬가지로 script를 만날 때, 파싱을 멈추지 않고 로드한다. 하지만 그 이후가 다르다. defer 속성이 붙으면, HTML 파싱이 끝난 직후, 코드 상 만난 순서대로 한번에 실행한다. 그러므로, 실행순서를 개발자가 컨트롤할 수 있고, HTML 파싱이 끝난 이후에 스크립트를 실행하기 때문에 DOM 조작도 가능하다.
정리
- <script> 태그를 사용할 때, 일반적으로 동기적으로 HTML 파싱 및 실행을 한다.
- <script async> 태그는 비동기적으로 스크립트를 로드한다. 또한 이때, 다운로드가 된 순서대로 실행된다.
- <script defer> 태그도 비동기적으로 스크립트를 로드한다. 이후 HTML 파싱이 끝났을 때, 코드상 만났었던 순서대로 한번에 스크립트를 실행시킨다.
- 그러므로 defer를 이용하면 script에서 안전하게 DOM을 조작할 수 있다.
기본 자료형과 참조 자료형
기본 자료형
기본 자료형은 변수에 값이 그대로 저장된다.
예를 들면 다음 코드와 같다.
let a = 1;
let b = 10;
a = b;
b = 5;
console.log(a) // 10
console.log(b) // 5
b값을 a에 저장한 후, b값을 다른 값으로 바꿔주는 간단한 예제이다.
코딩에 대해서 잘 모르는 분들도 조금만 설명한다면 충분히 납득할 수 있는 수준이다.
하지만 참조 자료형의 동작은 초심자가 이해하기 다소 어렵다.
참조 자료형
let arr1 = [1];
const arr2 = [10];
arr1 = arr2;
arr2.push(20);
console.log(arr1); // [10, 20]
console.log(arr2); // [10, 20]
이 예제의 동작을 간단하게 정리하면,
- arr1, arr2를 각각 [1], [10]으로 초기화
- arr2의 배열을 arr1에 저장
- arr2 배열에 20을 추가
- 각각 배열의 내용을 출력
이렇게 정리할 수 있다.
쉽게 기본 자료형처럼 생각해본다면, 출력은 arr1이 [10], arr2가 [10, 20]이 되어야할 것이다.
하지만 실제 출력은 다르다.
arr1과 arr2 모두 [10, 20]의 값을 가지게 된다.
왜 값이 똑같이 나오는걸까?
결론부터 얘기하면, 자바스크립트에서 변수에 객체를 저장할 때 메모리의 주소값을 저장하기 때문이다.
이 내용을 기억하면서, 코드를 따라가보자.
중요한 부분은 arr1 = arr2 부분이다
변수에 객체(배열)를 저장할 때는, 메모리의 주소값을 저장한다고 했었다. 그리고 이 메모리의 주소값을 통해, 배열에 접근할 수 있다.
이 내용을 기억하고 다시 코드를 보면, arr1 = arr2이 무엇을 뜻하는지 알 수 있다.
arr1 = arr2 부분에서 저장하는 것은 사실 배열을 가리키는 주소값이다. arr1과 arr2 모두 같은 주소값을 바라보고 있게 되는 것이다.
같은 주소값을 바라본다는 것은 곧, 같은 객체에 접근한다는 말이다.
즉, arr2에서 배열에 값을 추가했더라도, arr1도 같은 배열에 접근하게 되므로 같은 값을 가지게된다.
'TIL' 카테고리의 다른 글
JS 프로그래머스 Lv. 1 풀이 (최대한 내장 메서드 이용 X) (0) | 2024.10.25 |
---|---|
[TIL - 5] CSS - 3 (0) | 2024.10.20 |
[TIL - 4] CSS - 2 (0) | 2024.10.17 |
[TIL - 3] HTML 기초 - 3 + CSS (1) | 2024.10.16 |
[TIL - 2] HTML 기초 - 2 (1) | 2024.10.15 |