딥다이브 스터디 20,21(strict mode, 빌트인 객체)

김영현·2023년 10월 11일
1

엄격 모드(strict mode)

엄근진하게 코드를 평가해주는 모드다. 개발자가 실수하는걸 용납하지 않을 것이다.
우리는 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문 사용하면 에러. => 왜 있는거지..
  • 일반함수의 this는 undefined바인딩
  • 매개벼수에 전달된 인수를 재할당하여도 arguments객체에는 반영x

빌트인 객체

JS의 객체는 크게 3가지로 나눌 수있다.

  • 표준 빌트인 객체 : 전역 공통 기능을 제공하는 객체. 어떤 스코프에서든 부를수있다. (Object, Array, String....)
  • 호스트 객체 : DOM,BOM,Canvas,fetch등....실행환경에서 추가로 제공하는 API
  • 사용자 정의 객체 : 사용자가 직접 정의한 객체

표준 빌트인 객체

40여개가 존재함. 다 작성하긴 그렇고...
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엔진이 어떤 객체보다 먼저 생성하는 특수한 친구다.
환경마다 가리키는 이름이 다르다.

  • nodejs : global
  • 브라우저 : window, self, frames, 전역this

ES(2020)11이후에는 globalThis라는 게 생겼는데, 모든 환경에서 동일하다.

전역객체는 객체의 3종류중 두개. 표준 빌트인 객체, 호스트 객체를 프로퍼티로 갖는다.
프로퍼티를 호출할땐, 전역객체를 생략해도 작동한다.
=> setTimeout같은 메소드를 전역에서 사용할 수있는 이유가 이것 때문이다.
또한 var변수와 전역함수도 프로퍼티로 갖는다.(let, const는 아님)

setTimeout()
parseInt()...
  • 빌트인 전역 프로퍼티(전역객체의 프로퍼티) : Infinity, NaN, undefined
  • 빌트인 전역 함수 : 하나씩 살펴보자
  1. eval() : 쓰지말자.
  2. isFinite() : 무한이면 false, 유한수면 true. 숫자로 타입변환 한다.
  3. isNaN() : NaN인지 검사후 불리언 타입 반환. 숫자로 타입변환 함
  4. parseFloat() : 문자열 인수를 부동 소수점 숫자=실수 로 해석하여 반환
parseFloat("5.14") => // 5.14
  1. parseInt() : 문자열 인수를 정수로 해석하여 반환. 두번째 인수로 진법을 전달 할수있고, 첫번째 인수를 해당 진법으로 인식하여 반환한다.
parseInt("10", 2) // 2. 반환은 언제나 10진수다
// 16진수는 0x, 0X로 시작한다면 두번째 인수가 없어도 16진수로 해석한다. 나머지는 x
  1. encodeURI(), decodeURI() : 완전한 URI를 문자열로 전달받아 이스케이프 처리를 위해 인코딩한다.
    (A-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) #)제외
    이스케이프 처리란 어떤 시스템에서도 공유하는 ASCII문자열로 변환하는 과정을 말한다.
    예를들어 naver.com?name=kim&lang=eng&kor라는 문자열을 예시로 들면'kim'뒤의 '&'는 하나의 파라미터가 끝나고 다음 파라미터가 온다는 것이다.
    하지만 'eng&kor'처럼 문자열 자체에 약속된 기호가 포함된다면 url을 인식하는데 지장이 생김.
    => url을 약속된 언어로 바꿔준다.
  2. encodeURIComponent(), decode...
    6번과 비슷하지만, 얘는 URI의 구성요소를 인수로 받는다.
const uriComp = "name=loevray&job=studnet";
//인수를 URI의 구성요소인 쿼리스트링의 일부로 간주한다.
//따라서 쿼리스트링 구분자 =, ?, & 까지 인코딩한다.
name%3Dloevray%26job%3Dstudnet

암묵적 전역

맨 위에서 보여준 예제. 선언하지 않은 변수가 존재하는 것처럼 되는 현상.
즉, 전역객체(window)에 동적 프로퍼티 할당이 이루어진다.
전역변수는 delete로 삭제되지 않지만, 암묵적 전역으로 할당된 변수는 삭제된다.
호이스팅도 일어나지 않는다.

profile
모르는 것을 모른다고 하기

0개의 댓글