엄근진하게 코드를 평가해주는 모드다. 개발자가 실수하는걸 용납하지 않을 것이다.
우리는 Vscode를 사용할때 ESlint나 Prettier같은 코드 검사 도구를 사용한다.
그거와 비슷한게 JS에 내장되어있다고 보면 된다.
개발자가 실수한 예제를 살펴보자.
function foo(){
x=10;
}
foo();
console.log(x) //?
어이없게도 결과는 undefined
다. JS는 선언되지않은 식별자를 우리 몰래 전역객체에 할당해버린다.
이러한 현상을 암묵적 전역이라한다.
strict mode
를 사용해야 비로소 에러를 내뿜는다.
"use strict";
//...코드 시작
이렇게 사용할수 있음.
참고로 엄격모드는 스코프를 가진다. 함수 내부나 스코프에서 선언하면, 내부에만 엄격해진다.
주의할점은 스코프 선두에 선언해야한다. 선두가 아니면 제대로 동작하지 않는다.
전역에 사용하는 건 지양한다.
=> 라이브러리가 non-strict mode
로 작성되어 있을수도 있다.
함수단위도 마찬가지다. 다른 함수에서 non-strict mode
면 오류를 일으킬수있다.
=> 헛짓 말고 그냥 스크립트 단위로 적용하자.
요즘은 모듈로 사용하니 괜찮다.
ReferenceError
delete
연산자로 변수,함수, 매개변수 삭제하면 SyntaxError
SyntaxError
with
문 사용하면 에러. => 왜 있는거지..undefined
바인딩arguments
객체에는 반영xJS의 객체는 크게 3가지로 나눌 수있다.
DOM,BOM,Canvas,fetch
등....실행환경에서 추가로 제공하는 API40여개가 존재함. 다 작성하긴 그렇고...
Math, Reflect, JSON
을 제외한 표준빌트인객체는 모두 인스턴스를 생성할수 있는 생성자 함수다.
또한 인스턴스 없이 호출가능한 빌트인 정적 메서드를 제공한다.
Array.isArray()
Object.create()
Number.isInteger()
표준 빌트인 객체로 생성한 인스턴스의 프로토타입은 빌트인 생성자함수.prototype
이다
String.prototype
Object.prototype
문자열, 숫자, 불리언 등은 원시값으로 존재한다.
근데 왜 String, Number, Boolean
등 표준 빌트인 생성자 함수가 존재할까?
const num = 10.5;
const str = "안녕하세요";
num.toFixed() // 11
str.length // 5
원시값은 객체가 아니다. 그런데, 점 표기법.
을 사용했다.
=> 일시적으로 내부에서 원시값 to 객체 변환이 이루어진다. 반환은 다시 원시값으로.
이때 생성되는 임시 객체를 래퍼 객체(랩하는 래퍼아님)이라 한다.
이때 래퍼객체가 빌트인 생성자함수.prototype의 메서드를 상속받아 사용해주는 것이다.
const str = "hello";
//String 래퍼객체의 [[StringData]]내부 슬롯에 hello가 할당된다.
str.name = "Lee"; //이 str은 암묵적으로 생긴 래퍼객체다. 따라서 오류가 발생하지 않는다.
//프로퍼티 할당이 끝낫으므로, 다시 [[StringData]]슬롯에 담겨있던 값을 str에 할당해준다.
//가비지 컬렉터가 래퍼객체를 회수해갔다.
console.log(str.name); // undefined. 래퍼객체가 새롭게 생기지만, 이전 래퍼객체는 이미 사라졌다.
이러한 과정이 숨어있었구만?
숫자, 불리언도 마찬가지다.
전역객체는, 코드가 실행되기도 전에 JS엔진이 어떤 객체보다 먼저 생성하는 특수한 친구다.
환경마다 가리키는 이름이 다르다.
global
window, self, frames, 전역this
ES(2020)11이후에는 globalThis
라는 게 생겼는데, 모든 환경에서 동일하다.
전역객체는 객체의 3종류중 두개. 표준 빌트인 객체, 호스트 객체를 프로퍼티로 갖는다.
프로퍼티를 호출할땐, 전역객체를 생략해도 작동한다.
=> setTimeout
같은 메소드를 전역에서 사용할 수있는 이유가 이것 때문이다.
또한 var변수와 전역함수도 프로퍼티로 갖는다.(let, const는 아님)
setTimeout()
parseInt()...등
Infinity, NaN, undefined
eval()
: 쓰지말자. isFinite()
: 무한이면 false, 유한수면 true. 숫자로 타입변환 한다.isNaN()
: NaN
인지 검사후 불리언 타입 반환. 숫자로 타입변환 함parseFloat()
: 문자열 인수를 부동 소수점 숫자=실수 로 해석하여 반환parseFloat("5.14") => // 5.14
parseInt()
: 문자열 인수를 정수로 해석하여 반환. 두번째 인수로 진법을 전달 할수있고, 첫번째 인수를 해당 진법으로 인식하여 반환한다.parseInt("10", 2) // 2. 반환은 언제나 10진수다
// 16진수는 0x, 0X로 시작한다면 두번째 인수가 없어도 16진수로 해석한다. 나머지는 x
encodeURI(), decodeURI()
: 완전한 URI를 문자열로 전달받아 이스케이프 처리를 위해 인코딩한다.naver.com?name=kim&lang=eng&kor
라는 문자열을 예시로 들면'kim'뒤의 '&'는 하나의 파라미터가 끝나고 다음 파라미터가 온다는 것이다.encodeURIComponent(), decode...
const uriComp = "name=loevray&job=studnet";
//인수를 URI의 구성요소인 쿼리스트링의 일부로 간주한다.
//따라서 쿼리스트링 구분자 =, ?, & 까지 인코딩한다.
name%3Dloevray%26job%3Dstudnet
맨 위에서 보여준 예제. 선언하지 않은 변수가 존재하는 것처럼 되는 현상.
즉, 전역객체(window)에 동적 프로퍼티 할당이 이루어진다.
전역변수는 delete
로 삭제되지 않지만, 암묵적 전역으로 할당된 변수는 삭제된다.
호이스팅도 일어나지 않는다.