Skip to content

Commit

Permalink
와5시간넘게잘수있어
Browse files Browse the repository at this point in the history
  • Loading branch information
qilip authored Jan 31, 2024
1 parent 72db253 commit 825e934
Show file tree
Hide file tree
Showing 2 changed files with 224 additions and 0 deletions.
Binary file added 05회차(20장~22장)/image/shin-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
224 changes: 224 additions & 0 deletions 05회차(20장~22장)/신상민.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
# 스터디 5회차 - 20장 ~ 22장

# 20장

‘use strict’

## 20.1 strict mode란?

react strictMode도 엄격하긴 하지만 다릅니다 *싫어하는 사람이 많았다는건 같습니다*

- ES5부터 도입된 ‘엄격 모드’
- ES6의 클래스와 모듈은 기본적으로 strict mode가 적용된다.

## 20.2 strict mode의 적용

전역의 맨 앞 또는 함수 몸체의 선두에 `'use strict';` 추가

각 범위와 하위에 대해 적용된다. 코드의 선두에 위치시키지 않으면 제대로 동작하지 않는다.

```
TMI)
TypeScript의 경우
- tsconfig에 alwaysStrict: true
- 명령줄 옵션으로 --alwaysStrict
를 적용시키면 모든 파일 상단에 'use strict'; 를 적용시킨다.
```

## 20.3 전역에 strict mode를 적용하는 것은 피하자

전역에 적용한 strict mode는 스크립트 단위로 적용된다. 하지만 strict mode 스크립트와 non-strict mode 스크립트를 혼용할 경우 오류를 발생시킬 수 있다. 외부 스크립트가 non-strict mode일 경우도 있기 때문.

아마존도 그런 적이 있다.

[627531 - Lighnting deals on Amazon shows only closed teasers](https://bugzilla.mozilla.org/show_bug.cgi?id=627531)

스코프 구분이 필요한 경우 즉시 실행 함수로 감싸고 그 안에 strict mode를 적용한다.

## 20.4 함수 단위로 strict mode를 적용하는 것도 피하자

strict mode 바깥의 선언과 strict mode 안쪽의 사용 등 예측하기 힘든 오류가 발생할 수 있다.

## 20.5 strict mode가 발생시키는 에러

- 암묵적 전역: 선언하지 않은 변수를 참조 ReferenceError

- 변수, 함수 매개변수의 삭제 SyntaxError

- 매개변수 이름의 중복 SyntaxError

- with 문의 사용 SyntaxError

with문은 전달된 객체를 스코프 체인에 추가한다 : 동일한 객체의 프로퍼티를 반복해서 사용할 때 객체 이름을 생략할 수 있지만 성능과 가독성이 나빠지므로 사용하지 않는것이 좋다

## 20.6 strict mode 적용에 의한 변화

- 일반 함수의 this: 함수를 생성자 함수가 아닌 일반 함수로 호출하면 this를 사용할 필요가 없기 때문에 undefined가 바인딩된다.
- arguments 객체: 매개변수에 전달된 인수를 재할당해서 변경해도 arguments 객체에 반영되지 않는다.

```
TMI)
MDN에 따르면 엔진 최적화에 따라 성능 개선이 있을 수 있다고 한다.
아래 코드를 실행시켜보면 더 빠르다. (this 바인딩)
(출처: https://stackoverflow.com/questions/38411552/why-use-strict-improves-performance-10x-in-this-example)
```

```jsx
String.prototype.count = function(char) {
var n = 0;
for (var i = 0; i < this.length; i++)
if (this[i] == char) n++;
return n;
};

String.prototype.count_strict = function(char) {
"use strict";
var n = 0;
for (var i = 0; i < this.length; i++)
if (this[i] == char) n++;
return n;
};
// Here is how I measued speed, using Node.js 6.1.0

var STR = '0110101110010110100111010011101010101111110001010110010101011101101010101010111111000';
var REP = 1e4;

console.time('proto');
for (var i = 0; i < REP; i++) STR.count('1');
console.timeEnd('proto');

console.time('proto-strict');
for (var i = 0; i < REP; i++) STR.count_strict('1');
console.timeEnd('proto-strict');
```

# 21장 빌트인 객체

## 21.1 자바스크립트 객체의 분류

자바스크립트 객체는 다음과 같이 크게 3개의 객체로 분류할 수 있다.

- 표준 빌트인 객체 standard built-in objects/native objects/global objects
- 호스트 객체 host objects
- 사용자 정의 객체 user-defined objects

## 21.2 표준 빌트인 객체

*Global Objects*

[표준 내장 객체 - JavaScript | MDN](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects)

영어 이름이…

> The term "global objects" (or standard built-in objects) here is not to be confused with **the global object**. Here, "global objects" refer to **objects in the global scope**.
Math, Reflect, JSON을 제외한 표준 빌트인 객체는 모두 인스턴스를 생성할 수 있는 생성자 함수 객체다. 생성자 함수 객체가 아닌 표준 빌트인 객체(Math, Reflect, JSON)은 정적 메서드만 제공한다.

~~Math.floor(), JSON.stringify()~~

## 21.3 원시값과 래퍼 객체

원시 값(문자열, 숫자, 불리언)은 객체가 아니므로 프로퍼티나 메서드를 가질 수 없는데도 원시값은 마치 객체처럼 동작한다.

이들 원시값에 대해 마치 객체처럼 마침표 표기법(or 대괄호 표기법)으로 접근하면 자바스크립트 엔진이 암묵적으로 연관된 객체를 생성해 생성된 객체로 처리하고 다시 원시값으로 되돌린다. 래퍼 객체의 처리가 종료되면 래퍼 객체는 가비지 컬렉션의 대상이 된다.

> 문자열, 숫자, 불리언 값에 대해 객체처럼 접근하면 생성되는 임시 객체를 래퍼 객체wrapper object라 한다.
ES6 심벌도 래퍼 객체를 생성한다. 단 심벌은 리터럴 표기법으로 생성할 수 없고 Symbol 함수를 통해 생성해야 하므로 다른 원시값과는 차이가 있다.

## 21.4 전역 객체

Global object (아까 그거랑은 다름)

> 코드가 실행되기 이전 단계에 자바스크립트 엔진에 의해 어떤 객체보다도 먼저 생성되는 특수한 객체, 어떤 객체에도 속하지 않은 최상위 객체
- ES11에서는 globalThis가 환경과 상관 없이 전역 객체를 가리킨다
- 브라우저: this, window, self, frames
- Node.js: this, global

전역 객체는 표준 빌트인 객체와 환경에 따른 호스트 객체(클라이언트 Web API, Node.js 호스트 API), 그리고 var 키워드로 선언한 전역 변수와 전역 함수를 프로퍼티로 갖는다.

- 전역 객체는 개발자가 의도적으로 생성할 수 없다. (생성자 함수가 제공되지 않는다)
- 전역 객체의 프로퍼티를 참조할때 window(global)를 생략할 수 있다.
- let이나 const로 선언한 전역 변수는 var와 다르게 보이지 않는 개념적인 블록(전역 렉시컬 환경의 선언적 환경 레코드) 내에 존재한다
- 브라우저 환경의 모든 자바스크립트 코드는 하나의 전역 객체 window를 공유한다.

### 21.4.1 빌트인 전역 프로퍼티

- Infinity, NaN, undefined

### 21.4.2 빌트인 전역 함수

- eval: 기존의 스코프를 런타임에 동적으로 수정, strict mode에서는 자체적인 스코프를 생성

- 전달받은 문자열에 let, const가 있을경우 암묵적 strict mode

- 일단 느리고, 사용자 입력을 eval로 실행하는건 해킹 자유이용권을 뿌리는거니 쓰지말자

체험해보고 싶다면 지금 바로 >> Root Me <<

[Challenges/Web - Server : Node - Eval [Root Me : Hacking and Information Security learning platform]](https://www.root-me.org/en/Challenges/Web-Server/Node-Eval)

- isFinite, isNaN, parseFloat, parseInt, encodeURI, decodeURI, encodeURIComponent, decodeURIComponent

### 21.4.3 암묵적 전역

뜬금없이 `y = 9999999` 같은걸 넣으면 엔진은 window.y = 20 으로 해석해 전역 객체에 프로퍼티를 동적 생성한다.

전역 객체의 프로퍼티이므로 마치 전역 변수처럼 동작하게 된다. 하지만 변수가 아니므로 변수 호이스팅이 발생하지 않고, delete 연산자로 삭제할 수 있다.

# 22장 this

![Untitled](image/shin-1.png)

~~what is this~~

## 22.1 this 키워드

> this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수self-referencing variable다. this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
자바나 C++에서 this는 항상 클래스가 생성하는 인스턴스를 가리킨다. 하지만 자바스크립트의 this는 함수가 호출되는 방식에 따라 this 바인딩이 동적으로 결정된다. 또한 strict mode 역시 this 바인딩에 영향을 준다.

strict mode가 적용된 일반 함수 내부의 this에는 undefined가 바인딩된다. (일반 함수 내에서 this를 사용할 필요가 없기 때문에)

## 22.2 함수 호출 방식과 this 바인딩

- 랙시컬 스코프: 함수 정의가 평가되어 함수 객체가 생성되는 시점에 상위 스코프 결정
- this 바인딩: 함수 호출 시점에 결정

### 22.2.1 일반 함수 호출

> 기본적으로 this에는 전역 객체global object가 바인딩된다.
strict mode가 적용된 경우 undefined가 바인딩된다.

메서드 내부에 정의한 중첩 함수 또는 메서드에게 전달한 콜백 함수가 일반 함수로 호출될 때 this가 전역 객체를 바인딩하는건 문제가 있다. 그래서 this 바인딩을 다른 변수에 할당하여 사용하거나, `Function.prototype.apply`, `Function.prototype.call`, `Function.prototype.bind` 메서드를 사용해 this를 명시적으로 바인딩 할 수 있다. 또는 **화살표 함수를 사용해서 this 바인딩을 일치(상위 스코프의 this)시킬 수 있다.**

*킹갓짱짱화살표함수*

### 22.2.2 메서드 호출

> 메서드 내부의 this에는 메서드를 호출한 객체 (메서드를 호출할 때 메서드 이름 앞의 마침표 연산자 앞에 기술한 객체가 바인딩된다. (메서드를 소유한 객체가 아닌 메서드를 **호출**한 객체에 바인딩된다)
### 22.2.3 생성자 함수 호출

> 생성자 함수 내부의 this에는 생성자 함수가 (미래에) **생성할 인스턴스**가 바인딩된다.
### 22.2.4 Function.prototype.apply/call/bind 메서드에 의한 간접 호출

> apply와 call 메서드의 본질적인 기능은 함수를 호출하는 것이다. 함수를 호출하면서 첫 번째 인수로 전달한 특정 객체를 호출한 함수의 this에 바인딩한다.
- apply는 호출할 함수의 인수를 배열로 묶어서 전달한다
- call은 쉼표로 구분한 리스트 형식으로 전달한다

대표적인 용도는 유사 배열 객체에 배열 메서드를 사용하는 경우다.

```jsx
const arr = Array.prototype.slice.call(arguments);
```

> bind 메서드는 첫 번째 인수로 전달한 값으로 this 바인딩이 교체된 함수를 새롭게 생성해 반환한다.
```jsx
setTimeout(callbackFunction.bind(this), 100); // this를 바인딩
```

0 comments on commit 825e934

Please sign in to comment.