https://developer.mozilla.org/ko/docs/Web/JavaScript
🚨 JavaScript는 "인터프리트 Java"가 아닙니다.(Like 인도와 인도네시아)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<script src="scripts/main.js"></script>
<body></body>
</html>
바로 위체 코드 처럼 <script src="..."></script> 가 body 태그 위에 있는 경우
HTML 파싱을 멈추고 스크립트를 실행한다.
이렇게 되면 body가 파싱되지 않아 DOM 요소 조작이 불가능한 상황이 발생할 수 있다.
이때 defer 옵션을 쓰면, 모든 페이지 요소가 로딩 된 후 스크립트가 로딩 및 실행되어
DOM 요소에 대한 조작이 가능하다.
<script src="/examples/scripts/script_src.js" defer></script>

호이스팅이 뭐냐...고 물으면 이 한짤로 그냥 요약이 가능하다.
myName = "Chris";
function logName() {
console.log(myName);
}
logName();
var myName;
원래 변수를 선언하고 초기화를 해서 값을 할당하는 순서가 맞다.
위 코드처럼, JS의 var 변수는, 초기화 및 할당 부터 하고 뒤늦게 선언을 해도,
선언이 최상단 Context로 끌어 올려져, 코드가 정상 작동한다.
그러나 동일한 코드에서 let으로 변수를 선언하게 되면 Reference Error 가 발생하게 된다.


var 키워드는 undefined로 초기화 되지만,
let 키워드 같은 경우 선언과 초기화가 분리되어 진행된다.
선언단계에서 스코프에 변수를 등록하지만, 초기화는 변수 선언문에 도달했을 때 이루어진다.
이때 초기화 이전에 변수에 접근하게 되면 변수가 초기화 되지 않았기에 Reference Error 발생.
즉 변수를 위한 메모리 공간이 아직 확보되지 않은 상황에서 TDZ에서는 변수를 참조할 수 없어서
참조 에러가 발생
추가로 const 도 마찬가지.
_더 쉽게 비유하자면(by gpt)
var는 학교 출석부에 이름만 미리 적어놓고, 빈 자리를 차지하는 것
→ “누구 자리 있긴 한데 아직 앉진 않았어.”
let과 const는 출석부에 이름만 적어놓고, 실제로 교실 의자는 들어올 때 만들어지는 것
→ “아직 의자가 없으니 앉으려 하면 문제!”_
var는 재선언이 되고, let은 재선언이 안된다.
var myName = "Chris";
var myName = "Bob";
이건 되지만
let myName = "Chris";
let myName = "Bob";
이건 안된다. let으로 선언한 변수에 다른 값을 집어넣고 싶다면
let myName = "Chris";
myName = "Bob";
이렇게 키워드를 빼고 할당을 해야한다.
사실 var를 쓸 이유가 더이상 없어졌기 때문에 JS 코드를 짜면서 var 변수를 쓸일은 거의 없다.
select.onchange = function() {
const choice = select.value;
let days = 31; // 기본 31일 지정
// ADD CONDITIONAL HERE
if(choice === "February"){days = 28}
else if(choice === "April" || choice === "June" || choice === "September" ||
choice === "November") {days = 30}
createCalendar(days, choice);
}
for(let i = 10; i >= 0; i--){
var para = document.createElement('p');
// para.textContent = i !== 0 ? "Countdown" + i : "blast off";
if(i === 10) {para.textContent = "Countdown" + i}
else if (i !== 0) {para.textContent = i}
else {para.textContent = "blast off"}
output.appendChild(para);
function funcDeclarations() {
return 'A function declaration';
}
funcDeclarations();
var funcExpression = function () {
return 'A function expression';
}
funcExpression();
결론부터 보면 함수 선언문은 호이스팅에 영향을 받고, 함수 표현식은 호이스팅에 영향 X
function logMessage() {
return 'worked';
}
var sumNumbers;
logMessage(); // 'worked'
sumNumbers(); // Uncaught TypeError: sumNumbers is not a function
sumNumbers = function () {
return 10 + 20;
};
이러한 성질을 활용해서 함수 표현식은 클로저, Callback의 개념으로 추후 연결예정!
var arr = ["a", "b", "c"];
arr.forEach(function () {
// ...
});

int main(void) {
if (1) {
int a = 5;
printf("a = %d\n", a); // a = 5
}
printf("a = %d\n", a); // use of undeclared identifier 'a'
return 0;
}
C언어 같은경우 블록레벨 스코프 이기에, 중괄호로 구분되어 해당 블록 밖에서는 블록 안쪽의 a를 참조할 수 없다.
function a_func(){
if(1){
var a = 5;
console.log("a = ",a); // a = 5
}
console.log("a = ",a) // a = 5 (블록이 서로 다르더라도 참조 가능)
}
a_func();
반면 js는 a_func 라고 하는 함수 레벨로 스코프가 묶이기에 if 문 블록 밖에서도 블록 안쪽의 a 참조가 가능.
위에서 봤던 let과 const는 참고로 블록 레벨 스코프.
이용가능한 이벤트들, event Handler 갖고 있음.
이벤트 핸들러 = 이벤트 리스너
<button onclick="alert('Hello, this is my old-fashioned event handler!');">
Press me
</button>
버튼을 클릭하면 1씩 카운트가 증가하는 로직,
다만 HTML과 JS가 섞이기 때문에 유지 보수성이 떨어진다.
HTML은 마크업을, JS는 Interaction 을 담당해야 하는데 둘이 섞여 있음
<!-- HTML은 구조만 담당 -->
<button id="myButton">Press me</button>
<script>
const btn = document.getElementById("myButton");
btn.addEventListener("click", () => {
alert("Hello, this is a modern event handler!");
});
</script>
위 코드처럼 addEventListener 방식으로 분리하는게 가장 Best Practice
이벤트 버블링
이벤트 버블링은 하위 요소에서 발생한 이벤트가 상위 요소로 전달되는 것.

이벤트 캡쳐링
이벤트 캡쳐링은 이벤트 버블링과 반대 방향으로 진행

호이스팅 비유가 너무 취저예요