🌟 엄격 모드 (strict-mode)
엄격모드가 나오게 된 배경
JS는 하위 호환성 문제로 이전 버전부터 수정되지 않고 쌓이며 지속되어 왔기 때문에 구버전에 쓰였던 JS는 JS언어 자체만의 문제들이 많다. 이런 문제는 ES4버전까지 계속 되었다.
그런데! 마침내 ES5 버전부터 기존의 JS를 개선하기 시작했다. 다만.. 여전히 하위 호환성 문제가 있기 때문에 ES5의 기본 모드에서는 이런 변경사항이 활성화 되지 않도록 설계되었다…ㅜㅜ
하지만 당연하게도 사람들은 이 전 JS 버전 말고 ES5 버전 부터 적용된 JS를 사용하고싶어했기때문에 use strict
라는 특별한 지시자를 사용해 엄격 모드(strict mode)를 활성화 했을 때만 이 변경사항이 활성화될 수 있도록 하였다.
그래서 이해하기 쉽게 스위치에 비유하여 말하자면 ES5버전 부터 사용할 수 있게하는 스위치가 나타났다(use strict). ‘ES4까지의 JS가 적용되게 할건지 말건지! 이걸 엄격 모드를 켤건지 말껀지!’ 라고 할 수 있다.
이렇게 엄격 모드를 실행한, 즉 ES5 이후의 JS만을 사용하는 것을 모던 자바스크립트라고 한다~
엄격모드 사용법
JS 코드 최상단에 'use strict'
코드에 넣어주면 모던 자바스크립트를 사용할 수 있다. (겹따옴표 홀따옴표 구분 안함)
엄격모드 취소하기
취소할 방법은 없다!! 엄격 모드를 선언한 JS파일 내부의 코드는 전부 적용된다!!
즉, 중간에 어느 한 부분만 적용 안하고 이런게 불가능 하다는 뜻.
그래서 함수 내에서만 적용 시키는 경우도 있다. 특정 함수 내부에서만 사용하는건 가능!
엄격 모드를 꼭 사용해야할까?
위 설명을 읽다보면 당연히 최신 업데이트 내용인 ES5부터 사용하는게 좋은 것 아닌가? 싶을 수 있지만 모던 자바스크립트는 '클래스’와 '모듈’이라 불리는 진일보한 구조를 제공한다. 이 둘을 사용하면 use strict
가 자동으로 적용되기 때문에 이 둘을 사용하고 있다면 스크립트에 "use strict"
를 붙일 필요가 없다.
결론은 코드를 클래스와 모듈을 사용해 구성한다면 "use strict"
를 생략해도 된다~ 라는 것.
🌟 전역 객체
설명
전역 객체를 사용하면 어디서나 사용 가능한 변수나 함수를 만들 수 있다. 말 그대로 전역에서 사용 가능한 객체인 것 이다.
브라우저 환경에선 전역 객체를 window
, Node.js 환경에선 global
라고 부르는데, 이처럼 각 호스트 환경마다 부르는 이름은 다르다.
그래서 최근 자바스크립트에서는 전역 객체의 이름을 모두 globalThis
로 통일하기로 하였다. (( 하지만 여전히 몇몇 브라우저는 아직 globalThis
를 지원하지 않기도 하고, 관습적으로 여전히 window
와 global
을 더 많이 사용함))
적용해보기
alert("Hello");
// 위와 동일하게 동작합니다.
window.alert("Hello");
이렇게, alert
와 같은 내장 함수는 전역 객체에 속해 있기 때문에, window
객체를 통해 접근할 수도 있고, 전역에서 직접 호출할 수도 있다.
뒤에서 더 자세하게 배우겠지만 브라우저에서 let
이나 const
가 아닌 var
로 선언한 전역 함수나 전역 변수는 전역 객체의 프로퍼티가 된다.
var gVar = 5;
alert(window.gVar); // 5 (var로 선언한 변수는 전역 객체 window의 프로퍼티가 됩니다)
이렇게 바로 전역 객체로 들어가버린다는 것. 하지만 모던 자바스크리브에서는 이런 방식을 지원하지 않기 때문에 추천하지 않는다.
(((중요))) 전역을 오염시키면 안된다!!
그게 무엇이 되었든 전역은 오염시키면 안되는데 우리가 사용하는 상황에서 전역은 window이므로 window를 오염시키면 안된다!
이런식으로 윈도우에 어떤 값을 담으면 안된다. 윈도우라는 전역 객체는 누구나 접근 가능하기 때문에 오염의 위험이 크다.
🌟 오래된 var
var는 오래된 코드 작성법이다. 앞으로 새로운 코드를 작성할 땐 var를 사용하지 말자!! 이 설명은 오래된 코드에서 var를 만났을 때 대비하기 위함임
var와 let은 유사하지만 var를 무작정 let으로 바꾸면 어마어마한 에러가 생길수도…
var는 블록 스코프가 없다
스코프 = 이 안에서만 볼 수 있다.
블록 스코프 = 내가 스코프를 지정하면 이 블록 안에서만 적용 될 수 있다.
var로 선언된 변수의 스코프는 함수 스코프 or 전역 스코프 이다.
즉, 함수 내부에서 선언한 var는 함수 스코프가 되지만 (함수 내부에서만 쓸 수 있지만) 그게 아닌 모든 경우는 전역 스코프가 적용된다.
if (true) {
var test = true; // 'let' 대신 'var'를 사용했습니다.
}
alert(test); // true(if 문이 끝났어도 변수에 여전히 접근할 수 있음)
for (var i = 0; i < 10; i++) {
// ...
}
alert(i); // 10, 반복문이 종료되었지만 'i'는 전역 변수이므로 여전히 접근 가능합니다.
like this ~~~~~ 반복문이든 if문이든 다 외부에서 접근 가능함;;
(let과 const는 블록스코프 이기 때문에 if문 안에서 작성된 코드는 if문 안에서만 접근 가능함)
하지만 var도 함수 안에 있다면 함수 스코프를 따름.
function sayHi() {
if (true) {
var phrase = "Hello";
}
alert(phrase); // 제대로 출력됩니다.
}
sayHi();
alert(phrase); // Error: phrase is not defined | 함수 밖에서는 호출이 안됨
var는 변수의 중복 선언을 허용한다.
(아주 난장판이구만~~)
let user;
let user; // SyntaxError: 'user' has already been declared
let은 위와 같이 중복 선언이 안됨. 에러남
var user = “pete”;
var user = “john”; // 이렇게 해도 에러가 발생하지 않음ㅋ
alert(user); //john
이렇게 똑같은 이름으로 선언을 해도 에러도 안나고 그냥 해당 변수에 재할당 되어버림..
선언하기 전에 사용할 수 있는 var
var의 선언은 함수에서 선언되었다면 함수가 시작할 때 처리되고, 전역에서 선언하였다면 스크립트가 시작될 때 처리된다.
즉, var로 선언한 변수는 선언된 위치와 상관 없이 항상 최상단에서 정의된다는 것!!
이렇게 6번째 줄에 var로 선언된 변수는 함수가 시작되는 부분. 즉 함수의 최상단에 정의가 되고,
이렇게 if 문 안에 있는 var로 선언된 변수도 최상단에 정의가 된다.
이렇게 변수가 깔어올려지는 현상을 '호이스팅(hoisting)’ 이라고 부른다.
하지만 중요한점!!!!!
선언은 호이스팅 되지만 할당은 호이스팅 되지 않는다!!!
예를들어
function sayHi() {
alert(phrase);
var phrase = "Hello";
}
sayHi();
var phrase = "Hello"
행에선 두 가지 일이 일어난다.
- 변수 선언(
var
) - 변수에 값을 할당(
=
)
변수의 선언은 함수가 실행되어 시작할 때 끌어올려져서(호이스팅 되어서) 처리가 되지만 ~~~~
변수의 할당은 호이스팅 되지 않기 때문에 제 위치에서 처리된다. 따라서 아래와 같이 동작한다.
즉시 실행 함수 표현식(IIFE)
(이것도 요즘 자주 안 씀)
즉시 실행 함수 표현식은 이름 그대로 함수를 정의와 동시에 호출 하는 함수이다.
기본적인 형식은 아래와 같다.
(function() {
// 함수 코드
})();
또는
(function() {
// 함수 코드
}());
IIFE의 예시를 바로 보자면
(function() {
let message = "Hello";
alert(message); // Hello
})();
위와 같다. 위 코드를 보면 함수를 바로 실행하였기 때문에 변수의 선언과 할당이 모두 이루어진 상태이다.
이렇게 사용하기 위해 만들어진 IIFE는 사실상 var의 스코프 기능이 블록 스코프가 아닌 점을 보완하기 위해 만들어졌다고 해도 과언이 아니다.
✳️ 호이스팅(hoisting) ✳️
변수는 3단계를 거쳐 선언이 된다.
- 선언 단계
- 초기화 단계
- 할당 단계
앞에 정리한 내용 처럼 var, let, const 모든 변수는 호이스팅이 된다. 그런데!!!!
var
:var
로 선언된 변수는 호이스팅 되면서 초기값인undefined
를 할당 받는다.let
,const
:let
과const
으로 선언된 변수는 호이스팅이 되지만, 초기값을 할당받지 않고, TDZ(Temporal Dead Zone)에 들어가게 된다.
console.log(a); // undefined (var는 호이스팅과 동시에 초기값이 할당되므로 출력이 됨.)
var a = 10;
console.log(b); // ReferenceError: Cannot access 'b' before initialization (let은 TDZ에 가 있음)
let b = 20;
그렇기 때문에 위와 같은 결과가 나오게 된다.
TDZ (Temporal Dead Zone) 영역
Temporal Dead Zone 즉 일시적 사각지대는 변수의 선언단계와 초기화 단계 그 사이를 말한다.
TDZ 아무것도 선언 되어 있지 않은 공간.
let과 const는 tdz에 들어가있기 때문에 아무런 값도 출력 되지 않는다.
함수의 호이스팅
함수도 호이스팅이 된다!!
근데 함수는
본문 전체가 호이스팅 됨!!!
sum()
function sum() {
consol.log('hi');
}
그래서 위와 같이 sum
이라는 함수를 함수정의 전에 호출하여도 함수를 실행한 결과인 ‘hi’가 잘 출력이 된다.
그래서 최종적으로 위 사진과 같이 변수명과 함수 본문 전체 가 호이스팅 된다고 할 수 있다.
그럼 함수 안에 선언된 변수는 어디로 갈까?
일단, 함수 내에 선언된 변수들은 모두 함수 스코프의 최상단으로 호이스팅이 된다.
그런데 함수 안의 내용은 함수를 실행하기 전까지는 절대 존재하지 않는다.
함수 실행 전에는 이렇게.
그렇기 때문에 함수 안의 변수는 함수가 실행된 순간 함수 스코프의 최상단으로 호이스팅이 되는 것 이다.
그럼 빨간 네모는 위에 함수가 실행이 한번 되었으니까 저 z라는 변수를 찾아 나타낼 수 있을까?
답은 아니다.
왜냐하면 함수 안쪽에서 선언 된 변수이기 때문에 쓰지 못한다는 말도 맞지만, 함수는 실행과 동시에 실행하는 임무를 다하고 메모리를 위해 사라지기 때문에 z 변수가 없어서 가져오지 못한다는 말이 좀 더 맞다고.
null 과 undefined
개발자들 사이에서 관습적으로 undefined는 애초에 건들이지 않은 그런 값을 말함. 개발자가 일부러 비워서 할당한것이 아닌 그냥 아무것도 건들이지 않은 태초의 상태.
그 누구도 손을 대지 않은 상태.
null은 개발자가 의도해서 비워둔 상태.
🌟 데이터 타입 (자료형)
자바스크립트의 변수는 동적 타입. 언제든 타입이 바뀔 수 있다.
이런 변수를 정적 타입으로 쓸 수 있는게 타입 스크립트.
js에는 8가지의 기본 자료형이 있다.
숫자형
말 그대로 숫자. 정수와 소수점을 포함한 숫자.
Infinity, -Infinity, NaN (not a number)도 특수 숫자 값이다.
Biglnt (비긴트)
위 값보다 훨씬 더 큰 값을 써야할 때 쓰는게 비긴트.
이런식으로 숫자 뒤에 n만 쓰면 사용할 수 있다. 다만 거의 거의 쓸 일이 없다.
문자형
문자열을 따옴표로 묶음.
셋 다 가능
백틱은 이런식으로 문자 안에 변수를 삽입할 때 사용된다.
문자 사이에 변수를 끼워 넣는 것을 인터폴레이션이라고 한다.
불린형
true랑 false
중요
자, 식 으로 끝나는건 값을 반환한다.
연산자, 연산식 같은거
JS에서 값을 반환하는 것과 안하는게 있는데 이걸 구분하는게 매우 중요.
값을 반환하지 않는건 ‘문’
블럭문, if문, else문, while문 같은..
‘null’값
null은 어떤 자료형에도 포함되지 않는다.
객체와 심볼
객체를 이해하는것이 매우 중요하다.
객체 → object
위에는 원시 자료형.
심볼은 라이브러리 개발자들이 많이 씀. 절대로 고유한 값이기 때문에 라이브러리 사용자와 이름이 겹칠 이유가 없기 때문에.
함수와 배열의 자료형
함수와 배열의 자료형은 객체에 포함이 된다.
typeof 연산자
연산’자’ = 값을 반환한다.
내가 넣은 인수의 자료형을 반환해준다.
Math = 빌트인 객체
따라서 타입은 object로 나옴.
그지같이 null 은 null타입이지만 object로 나옴. 그 하위 버전 호환땜에…
이처럼 타입오브는 좀 문제점이 있다.
제대로 타입을 선별할 수 있는 방법도 있는데 담에 배워보자.
'🦁부트캠프 > 🐯 JS 수업 정리' 카테고리의 다른 글
[Javascript] 옵셔널 체이닝(Optional Chaining) 이란? (1) | 2024.12.15 |
---|---|
[Javascript] 가비지 컬렉션 (Garbage Collection) 이란? (0) | 2024.12.07 |
Vite를 사용하는 이유 (0) | 2024.12.01 |
Ajax와 비동기 통신 (0) | 2024.11.23 |
[10 / 29] JS란? | 코드 구조 | 변수와 상수 (3) | 2024.11.10 |