일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 모던 자바스크립트 Deep Dive
- Vue3 Router
- 모던 자바스크립트 Deep Dive TIL
- Vue3
- 인프런 자바스크립트 알고리즘 문제풀이
- KDT 프로그래머스
- KDT 프로그래머스 데브코스 프론트엔드
- frontend roadmap study
- K_Digital Training
- useEffect return
- 리팩토링 회고
- 모던 javascript Deep Dive
- 프로그래머스 데브코스 프론트엔드 TIL
- 머쓱이
- 모던 자바스크립트 TIL
- 프로그래머스 K_Digital Training
- 프로그래머스 데브코스
- 프로그래머스 K_Digital Training 프론트엔드
- TypeScript 문법 소개
- react customHook 예시
- useRef 지역 변수
- 백준 js
- 프로그래머스 데브코스 프론트엔드
- Frontend Roadmap
- 개발자 특강
- react 프로젝트 리팩토링
- 우테캠 회고록
- 모던 자바스크립트 딥다이브
- 투포인터알고리즘 js
- 백준 node.js
- Today
- Total
프론트엔드 개발자의 기록 공간
[JavaScript DeepDive] 20~21장 본문
📖 학습 목차
- 20장_strict mode란?
- 21장_빌트인 객체
✅ strict mode란?
일단 strict mode를 알아보기 전에 아래의 코드를 보자.
function foo() {
x = 10;
}
foo();
console.log(x); // 10
foo 함수 내에서 선언하지 않은 x변수에 값 10을 할당했다. 이때 자바스크립트 엔진은 x 변수가 어디에 선언되었는지 스코프 체인을 통해 검색하기 시작한다.
하지만 전역 스코프까지 x 변수의 선언이 존재하지 않기 때문에 ReferenceError를 발생시킬 것 같지만
자바스크립트 엔진은 암묵적으로 전역 객체에 x 프로퍼티를 동적 생성한다. 이때 x는 전역 변수처럼 사용할 수 있다. 이러한 현상을 암묵적 전역이라 한다.
암묵적 전역은 변수가 아니다. 따라서 호이스팅은 발생하지 않는다.
function foo() {
console.log(x); // ReferenceError
x = 10;
}
foo();
자바스크립트는 유연한 언어라서 문제가 있는 코드라도 에러를 발생시키지 않는 경우가 종종 발생한다.
이러한 엄격하지 않은 모드를 sloppy mode(느슨한 모드)라고 부른다.
ES5에 추가된 strict mode(엄격한 모드)는 자바스크립트 언어의 문법을 좀 더 엄격히 적용하여 오류를 발생시킬 가능성이 높거나 자바스크립트 엔진의 최적화 작업에 문제를 일으킬 수 있는 코드에 대해 명시적인 에러를 발생시킨다. 즉 엄격하게 문법을 검사한다는 의미로 받아들이면 된다.
- 기존에는 조용히 무시되던 에러들을 throwing합니다.
- JavaScript 엔진의 최적화 작업을 어렵게 만드는 실수들을 바로잡습니다. 가끔씩 엄격 모드의 코드는 비-엄격 모드의 동일한 코드보다 더 빨리 작동하도록 만들어집니다.
- 엄격 모드는 ECMAScript의 차기 버전들에서 정의 될 문법을 금지합니다.
✍ strict mode의 적용
strict mode를 적용하려면 전역의 선두 또는 함수 몸체의 선두에 'use strict';를 추가한다.
전역의 선두에 추가하면 스크립트 전체에 strict mode가 적용된다.
'use strict';
function foo() {
x = 10; // ReferenceError: x is not defined
}
foo();
함수 몸체의 선두에 추가하면 해당 함수와 중첩 함수에 strict mode가 적용된다.
function foo() {
'use strict';
x = 10; // ReferenceError: x is not defined
}
foo();
전역과 함수 단위에 strict mode의 적용을 피하자!
전역에 strict mode 스크립트를 적용하면 외부 서드파티 라이브러리를 사용하는 경우 라이브러리가
non-strict mode인 경우도 있기 때문에 전역에 적용하는 것은 바람직하지 않다.
또한 함수도 어떤 함수는 non-strict mode일 수도 있고, 모든 함수에 strict mode를 사용하는 것은 번거롭기 때문에 피하자.
그러면 어디에 적용시키느냐?!
// 즉시 실행 함수의 선두에 strict mode 적용
(function () {
'use strict';
// Do something...
}());
필요한 로직에만 즉시 실행 함수로 스크립트 전체를 감싸서 스코프를 구분하고 즉시 실햄 함수의 선두에 strict mode를 적용한다.
✍ arguments 객체의 strict mode 적용
(function (a) {
'use strict';
// 매개변수에 전달된 인수를 재할당하여 변경
a = 2;
// 변경된 인수가 arguments 객체에 반영되지 않는다.
console.log(arguments); // { 0: 1, length: 1 }
// 그냥 변수에는 적용
console.log(a); // 2
}(1));
✅ 빌트인 객체
자바스크립트 객체는 다음과 같이 크게 3개의 객체로 분류할 수 있다.
- 표준 빌트인 객체
- ECMAScript 사양에 정의된 객체를 말하며, 애플리케이션 전역의 공통 기능을 제공한다. (bject, String, Number, Boolean, Symbol, Date, Math, RegExp 등 40여 개 제공) 표준 빌트인 객체는 자바스크립트 실행 환경(브라우저, node.js 환경)과 관계없이 언제나 전역 변수처럼 참조할 수 있다.
- 호스트 객체
- ECMAScript 사양에 정의되어 있지 않지만 자바스크립트 실행 환경(브라우저, node.js 환경)에서 추가로 제공하는 객체를 말한다. 브라우저 환경에서는 DOM, BOM, XMLHttpRequest, fetch등 과 같은 클라이언트 사이드 Web API를 호스트 객체로 제공하고, Node.js환경에서는 Node.js고유의 API를 호스트 객체로 제공한다.
- 사용자 정의 객체
- 표준 빌트인 객체와 호스트 객체러험 기본 제공되는 객체가 아닌 사용자가 직접 정의한 객체를 말한다.
✍ 원시값과 래퍼 객체
표준 빌트인 객체 String, Number, Boolean등은 생성자 함수로 호출하여 인스턴스를 생성할 수 있다.
const strObj = new String("Lee"); // String {"Lee"}
console.log(typeof strObj); // object
const numObj = new Number(123); // Number {123}
console.log(typeof numObj); // object
이렇게 만들어진 표준 빌트인 객체는 인스턴스 없이도 호출 가능한 빌트인 정적 메서드를 제공한다.
// Number 생성자 함수에 의한 Number 객체 생성
const numObj = new Number(1.5); // Number {1.5}
// toFixed는 Number.prototype의 프로토타입 메서드다.
// Number.prototype.toFixed는 소수점 자리를 반올림하여 문자열로 반환한다.
console.log(numObj.toFixed()); // 2
// isInteger는 Number의 정적 메서드다.
// Number.isInteger는 인수가 정수(integer)인지 검사하여 그 결과를 Boolean으로 반환한다.
console.log(Number.isInteger(0.5)); // false
하지만 문자열이나 숫자, 불리언등의 원시값이 있는데도 객체로 생성하는 표준 빌트인 생성자 함수가 존재하는 이유는 무엇일까??
원시값은 객체가 아니므로 프로퍼티나 메서드를 가질 수 없는데도 원시값인 문자열이 마치 객체처럼 동작한다.
const str = 'hello';
// 원시 타입인 문자열이 프로퍼티와 메서드를 갖고 있는 객체처럼 동작한다.
console.log(str.length); // 5
console.log(str.toUpperCase()); // HELLO
이는 원시값에 대해 마치 객체처럼 마침표 표기법(또는 대괄호 표기법)으로 접근하면 자바스크립트 엔진이 일시적으로 원시값을 연관된 객체로 변환해 주기 때문이다.
즉, 원시값을 객체로 사용하면 자바스크립트 엔진은 암묵적으로 연관된 객체를 생성하여 객체 프로퍼티에 접근하거나 메서드를 호출하고 다시 원시값으로 되돌린다.
이처럼 원시값에 대해 객체처럼 접근하면 생성되는 임시 객체를 래퍼 객체라한다.
👨💻 자바스크립트에서 객체를 크게 빌트인, 호스트, 사용자 정의 객체로 구분되는 것과 원시 값과 래퍼 객체에
대해서 개념을 처음 알 수 있었다. 위에서 언급한 것처럼 "문자열이나 숫자, 불리언 등의 원시 값이 있는데도 왜 객체로 쓸까?"를 생각해 본 적이 있었지만, 깊게 고민하거나 굳이 생각할 필요성을 못 느꼈었다. 왜냐하면 length 등을 동일하게 사용할 수 있었고, 차이점을 못 느꼈기 때문이다. 하지만 동일하게 사용할 수 있었던 이유가 "래퍼 객체"라는 개념으로 인해 사용할 수 있었다는 것을 알 수 있던 계기가 되었다.
'모던 자바스크립트 Deep Dive' 카테고리의 다른 글
[JavaScript DeepDive] 23장_실행 컨텍스트 (0) | 2022.02.19 |
---|---|
[JavaScript DeepDive] 22장_this (0) | 2022.02.18 |
[JavaScript DeepDive] 19장_프로토타입 (0) | 2022.02.16 |
[JavaScript DeepDive] 18장_함수와 일급 객체 (0) | 2022.02.14 |
[JavaScript DeepDive] 17장_생성자 함수에 의한 객체 생성 (2) | 2022.02.14 |