JavaScript
자바스크립트를 사용하는 가장 주된 목표는, HTML, CSS를 동적으로 DOM API를 사용하여 바꾸기 위함입니다. 또한 ECMAScript는 JavaScript의 표준을 정의하는 곳입니다.
이의 역할에 대해 간단히 서술해 보도록 하겠습니다.
- 요소의 추가 및 삭제
- CSS및 HTML요소의 스타일 변경 : 내용 및 모양 동적 제어
- 사용자와의 상호작용 : 사용자 입력, 계산
- 폼의 유효성 검증
- 마우스와 키보드 이벤트에 대한 스크립트 실행
- 웹 브라우저 제어 및 쿠키 등의 설정과 조회
- 웹 서버와의 통신
또한 자바스크립트는 loosely typed이고, dynamic language입니다. 이는 딱 어느 타비으로 선언하자 마자 정해지는 것이 아니라, 변수에 값이 할당될 때 마다 그 타입이 바뀝니다.
let은 blocked-scoped local variable을 만듭니다.
function varTest() {
var x = 1;
{
var x = 2; // same variable
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
{
let x = 2; // different variable
console.log(x); // 2
}
console.log(x); // 1
}
Hoisting
호이스팅이란 함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것을 말합니다.
- JS Parser가 함수 실행 전 해당 함수를 한 번 훑습니다.
- 함수 안에 존재하는 변수/함수선언에 대한 정보를 기억하고 있다가 실행시킵니다.
- 유효 범위 : 함수 블록 안에서 유효
- 즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것입니다.
- 실제로 코드가 끌어올려지는건 아니며, 자바스크립트 Parser 내부적으로 끌어올려서 처리하는 것입니다.
- 실제 메모리에서는 변화가 없습니다.
myname = "asdf";
console.log(myname);
// console.log(myname2);
var myname = "HEEE";
let myname2 = "HEEE2";
// asdf
선언만 끝어 올리는 것이므로, myname = "asdf"을 안해주게 되면, 그냥 undefined가 나오게 됩니다.
foo();
// foo2();
function foo() {
// 함수 선언문
console.log("hello");
}
var foo2 = function () {
// 함수 표현식
console.log("hello2");
};
// hello
또한 함수 선언문과 함수 표현식에서의 호이스팅은 함수 선언문만 가능합니다.
이렇게 돌아가는 원리를 JS Parser가 내부의 호이스팅을 했을 때의 코드를 보여드리겠습니다. 이는 위의 코드와 완전히 동일하게 동작합니다.
// var foo2;
function foo() {
console.log("hello");
}
foo();
foo2();
foo2 = function() {
console.log("hello2");
}
이렇게 되기 때문입니다. foo2()를 호출하면 아무것도 선언이 안되었는데 호출하는것은 말도 안되기 때문에 할 수 없습니다. 중요한 개념입니다. 변수에 할당된 함수표현식은 끌어 올려지지 않기 때문에 이때는 변수의 스코프 규칙을 그대로 따릅니다!
function printName(firstName) {
var result = inner();
console.log(typeof inner);
console.log("name is " + result);
function inner() {
return "inner value!";
}
}
printName();
// function
// name is inner value!
이 코드에서는 함수 내부에서도 호이스팅이 발생하는데 다음과 같이 호이스팅이 발생하게 됩니다.
function printName(firstName) {
var result;
function inner() {
return "inner value";
}
result = inner();
console.log(typeof inner);
console.log("name is" + result);
}
printName();
이제는 함수 표현식에서의 호이스팅에 대해서 알아보겠습니다.
function printName(firsname) {
var inner = function() {
return "inner value"
}
var result = inner();
console.log("name is " + result);
}
printName(); // "name is inner value"
이런 코드는 당연히 돌아가겠지만 아래와 같은 코드는 당연히 돌아가지 않습니다.
function printName(firstname) {
console.log(inner);
var result = inner();
console.log("name is " + result);
var inner = function () {
return "inner value";
};
}
printName();
그 이유는 당연히, 선언문만 올라가서 함수인지 inner라는 변수는 모를 것입니다. 그래서 printName에서 "inner is not defined"라는 ㅇ오류가 나오지 않고, "inner is not a function"이라는 TypeError가 나오는 이유도 이에 있습니다. printName이 실행되는 순간 (Hoisting에 의해) inner는 'undefined'으로 지정되기 때문입니다. inner가 undefined라는 것은 즉, 아직은 함수로 인식이 되지 않고 있다는 것만을 의미합니다. 근데 이를 let이나 const로 설정하면 Hoisting조차 되지 않기 때문에 ReferenceError: inner is not defined라고 나오겠죠??
또한 마지막으로
/** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 --- */
// 1. [Hoisting] 변수값 선언
var myName;
var yourName;
// 2. [Hoisting] 함수선언문
function myName() {
console.log("yuddomack");
}
function yourName() {
console.log("everyone");
}
// 3. 변수값 할당
myName = "hi";
yourName = "bye";
console.log(typeof myName); // > "string"
console.log(typeof yourName); // > "string"
다음과 같은 상황에서 값이 할당 안되어 있었기 때문에 둘다 string으로 나오지만 갑싱 할당 되어 있었다면. 이는 함수가 될 것입니다.
'Web > Advanced Web Programming' 카테고리의 다른 글
Java Script - this 바인딩 (0) | 2022.06.04 |
---|---|
고급 웹 프로그래밍 - 정리 - 2 (0) | 2022.06.04 |
Advanced Web Programming - CSS (2) (0) | 2022.04.04 |
Advanced Web Programming - CSS (1) (0) | 2022.04.03 |
Advanced Web Programming - 멀티미디어 태그 (0) | 2022.03.15 |