Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

20장 strict mode, 21장 빌트인 객체 #15

Merged
merged 3 commits into from
Jan 20, 2025
Merged

20장 strict mode, 21장 빌트인 객체 #15

merged 3 commits into from
Jan 20, 2025

Conversation

joeuns
Copy link
Collaborator

@joeuns joeuns commented Jan 16, 2025

날씨가 춥네요이.. 다들 따뜻하게 입으십쇼! ☕️

Copy link
Member

@zziglet zziglet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

깔끔한 정리본에 감탄하구 갑니다. 수고하셨습니다~🍥☺️

Comment on lines +64 to +80
그때에는! **즉시 실행 함수로 전체 스크립트에 적용 가능**

```jsx
(function () {
"use strict";

function strictFunction() {
let x = 10; // Strict Mode 적용
}

function nonStrictFunction() {
y = 20; // ReferenceError: y is not defined
}
})();
```

파일 내 모든 코드가 동일한 규칙(Strict Mode) 아래에서 실행되므로, **일관성과 안정성이 보장**됨.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

프로젝트 전체 x,
함수별 적용 x,
꼭 strict mode가 필요한 파일에만 적용하는 것을 권장
한다는 의미일까나요..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

프로젝트 전체에 적용하는 것은 이전 구 버전 코드 때문에 위험하고,
파일 내에서 특정 함수에만 적용하는 것도 헷갈릴 수 있으니

파일 단위로 모듈화를 통해 자연스럽게 적용시키는 것이 가장 좋지 않을까.. 라는 생각입니다!

}());
```

## strict mode 적용에 의한 변화
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strict mode를 생각하면 가장 먼저 떠오르는 건
변수 또는 함수 이름에 예약어를 사용할 수 없도록 잡아주는 점인 것 같아요

이 밖에도 다양한 변화가 있을 것 같습니다!


![image.png](1.png)

그 후 래퍼 객체의 처리가 종료되면 래퍼객체의 [[StringData]] 내부슬롯에 할당된 원시값으로 원래의 상태(원시값)을 갖도록 되돌리고, 래처 객체는 가바지컬렉션의 대상이 된다.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
그 후 래퍼 객체의 처리가 종료되면 래퍼객체의 [[StringData]] 내부슬롯에 할당된 원시값으로 원래의 상태(원시값)을 갖도록 되돌리고, 래처 객체는 가바지컬렉션의 대상이 된다.
그 후 래퍼 객체의 처리가 종료되면 래퍼객체의 [[StringData]] 내부슬롯에 할당된 원시값으로 원래의 상태(원시값)을 갖도록 되돌리고, 래퍼 객체는 가바지컬렉션의 대상이 된다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zziglet 우리의 오타 수호자...🤍


## 빌트인 전역 함수

- eval(쓰지말자)
Copy link
Member

@zziglet zziglet Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eval is evil,,,그런데, 뭔가 이유를 명확하게 다 알지 못 하는 느낌이라 지피티의 도움을! 받아봤습니다리

  1. 보안 문제

eval()은 전달된 문자열을 코드로 실행합니다. 만약 외부 입력이나 사용자 데이터를 eval()에 전달하면, 악의적인 코드를 실행할 가능성이 있습니다. 예를 들어:

const userInput = "alert('Hacked!')";
eval(userInput);

이 코드는 사용자가 입력한 문자열을 실행하므로, 악성 코드가 쉽게 삽입될 수 있습니다. 이런 식의 공격은 코드 인젝션(Code Injection)이라고 불리며, 보안 취약점을 초래합니다.

  1. 성능 저하
    eval()은 JavaScript 엔진이 최적화할 수 없는 코드를 실행합니다. 정적으로 분석할 수 없는 코드는 실행 중에 해석되어야 하므로, 실행 속도가 느려질 수 있습니다.

  2. 디버깅 및 유지보수 어려움
    eval()로 실행된 코드는 소스 코드에 명시적으로 존재하지 않으므로 디버깅이 어렵습니다. 또한, 코드의 흐름을 파악하기 힘들어 유지보수가 복잡해집니다.

  3. 대체 방법이 존재
    대부분의 경우 eval() 없이도 동일한 기능을 구현할 수 있습니다. 예를 들어, 객체 접근을 동적으로 처리하려면 eval() 대신 아래와 같은 방식을 사용할 수 있습니다:

객체 접근 예제

const obj = { a: 10, b: 20 };
const key = "a";

// eval 사용: 위험
// const value = eval(`obj.${key}`);

// 안전한 대체 방법
const value = obj[key];
console.log(value); // 10
  1. Strict 모드와 함께 사용 시 문제 발생

Strict 모드에서 eval()은 일부 동작이 제한됩니다. 예를 들어, eval() 내부에서 정의된 변수는 외부 스코프에서 접근할 수 없습니다.

'use strict';

eval("var x = 10;");
console.log(x); // ReferenceError: x is not defined

Copy link
Collaborator

@whddltjdwhd whddltjdwhd Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ES6에서 등장한 모듈 시스템을 적용해봅시다!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

얼마전 실무 코드에서 eval이 쓰이는걸 봤습니다...... 그때 기겁하고 코드를 자세히 읽어보니 evaluation(평가 값)에 대한 변수 이름으로써 eval을 적어둔거더라구요
const eval= result.value
eval 함수와 관계 없었지만 놀랬던 기억이 있어서 남기고 갑니다..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존에 몇천 줄짜리 js 코드를 그대로 <script> 태그 안에서 사용 중인 코드를 볼 일이 있었어요.
이러한 상황에서 추가 기능을 개발하거나 기존 기능을 개선한다면 어떻게 효과적으로 모듈화를 진행할 수 있을까요??

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function() 이 대안이 될 것 같네요
eval은 호출된 위치의 로컬 스코프에서 실행되어, 해당 스코프의 변수나 객체에 접근하고 수정할 수 있어서 문제가 발생합니다
반면 Function()은 항상 전역 스코프에서 실행되어 호출된 위치의 로컬 스코프에 접근할 수 없으므로, 현재 함수의 데이터에 영향을 미치지 않아요

let x = 10;
eval("x = 20"); //x=20으로 바뀜
console.log(x); // 20 출력
let x = 10;
let foo = Function("x = 20");
foo();
console.log(x); // 10 (로컬 변수에 영향을 주지 않음)

참고자료

Copy link
Collaborator

@whddltjdwhd whddltjdwhd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 추운 겨울, JS를 향한 조은님의 열정이 모두를 따뜻하게 만들어 주는 것 같네요. 고생하셨습니다~! 👍


**2. 전역 Strict Mode 적용이 코드 분리와 독립성을 해침**

Strict Mode를 전역에 적용하면, 프로젝트의 모든 코드가 같은 컨텍스트에서 실행된다.
Copy link
Collaborator

@whddltjdwhd whddltjdwhd Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"use strict"; // 전역에 Strict Mode 적용

// 오래된 외부 라이브러리
function oldLibraryFunction() {
    undeclaredVariable = 10; // Strict Mode에서는 선언되지 않은 변수 사용 시 오류 발생
    console.log("This is an old library function.");
}

oldLibraryFunction();

위와 같이 오래된 라이브러리가 같이 선언되지 않은 변수를 사용하고 있는 경우, 예기치 못한 오류를 맞이할 수 있겠네요!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그렇다면 바벨 같은 경우 use strict를 어떻게 변환할지 궁금하네요


- ES6 모듈은 Strict Mode 기본으로 적용 되어있음

- 코드에디터에 ESLint를 설치해도 같은 효과를 볼 수 있음
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strict mode는 런타임에 오류를 발견하지만, ESLint는 코드 실행 전에 발견할 수 있어서 더 좋은 것 같아요!
그리고 strict mode 에 비해 더 세세한 설정이 가능해서 요즘 프로젝트를 할 때 ESLint 적용이 필수인 것 같습니다ㅎㅎ

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

소웨공 시간에 들었던 static code analysis와 dynamic code analysis가 떠오르네요!

// ② 식별자 str은 암묵적으로 생성된 래퍼 객체를 가리킨다.
// 식별자 str의 값 'helLo는 래퍼 객체의 [[StringData]] 내부 슬롯에 할당된다.
// 래퍼 객체에 name 프로퍼티가 동적 추가된다.
str.name = "Lee";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

래퍼 객체와의 연결은 마치 오작교와도 같이 프로퍼티에 접근하거나 메서드를 호출할 때만 접근 가능하네요..!

Copy link
Member

@clicelee clicelee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조은님만의 색이 담긴 재미있는 글 잘 읽었습니다! 이해 잘 되게 열심히 정리하신게 느껴지네요!
고생 많았습니다~ 발표도 기대할게요!


- **실수 방지**: 변수 선언 없이 사용하거나 잘못된 코드를 작성하면 에러를 발생시킴.
- **보안 강화**: this 값이 의도치 않게 전역 객체를 참조하지 않도록 방지.
- **with 문 사용 금지**: 가독성과 디버깅을 어렵게 만드는 with 문을 금지.
Copy link
Member

@clicelee clicelee Jan 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

처음 볼 땐 with이 동적으로 범위를 확장한다는 점에서 유용해보였는데 책에서는 '안 좋다!' 고만 나와있어서 어떤 점이 안 좋은지 더 찾아보았습니다.
정리가 잘 된 한국어 블로그

또한 with이 사용되던 시절에 with 문과 values 메서드 충돌에 관해 해결하고자 하는 토론이 있습니다.
Array.prototype.values() compatibility hazard

문제
with(values) 형태로 작성된 코드가 존재하는데
여기서 values가 배열일 경우, with 문 내부의 values 참조가 values.values로 평가되는 문제가 발생함

with(values.values=values) 같은 핫픽스가 제안되었지만, 장기적으로 볼 때 안정적으로 운영하기 위해 with이 빠지게 되었나봅니다

이 토론 후반부에서 js에 with을 도입한 Brendan Eich가 자기 자신을 탓하는 부분도 있네요
재미있어서 가져와봤습니다 😙
Screenshot 2025-01-19 at 12 01 46 AM


## 빌트인 전역 함수

- eval(쓰지말자)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

얼마전 실무 코드에서 eval이 쓰이는걸 봤습니다...... 그때 기겁하고 코드를 자세히 읽어보니 evaluation(평가 값)에 대한 변수 이름으로써 eval을 적어둔거더라구요
const eval= result.value
eval 함수와 관계 없었지만 놀랬던 기억이 있어서 남기고 갑니다..

Comment on lines +95 to +109
2. **delete 연산자로 변수,함수, 매개변수를 삭제**

```jsx
(function () {
"use strict";

var x = 1;
delete x; // SyntaxError: Delete of an unqualified identifier in strict mode.

function foo(a) {
delete a; // SyntaxError: Delete of an unqualified identifier in strict mode.
}
delete foo; // SyntaxError: Delete of an unqualified identifier in strict mode.
})();
```
Copy link
Member

@clicelee clicelee Jan 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var로 선언된 변수는 전역 범위나 함수 범위에서 삭제할 수 없습니다
이 코드에서 "use strict"를 사용하지 않은 경우를 생각해본다면

function () {
     var x = 1;
     delete x; // false (실패)
     console.log(x); // 1 출력
}

이렇게 되어 delete를 통한 삭제 시도가 실패합니다
그럼에도 불구하고 이 책에서 이 예제를 작성한 이유는 SyntaxError: Delete of an unqualified identifier in strict mode. 라는 메세지가 명시적으로 출력된다는 점을 말하고 싶었나봅니다🤔

참고

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 신기하네요
그러면 var 변수를 남발하면 브라우저가 닫히기 전까지 메모리에서 절대 사라지지 않으니 의도치 않은 메모리 부족이 일어날 수도 있으려나요..?

Copy link
Member

@Turtle-Hwan Turtle-Hwan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다 :)

- 전역 객체는 개발자가 의도적으로 생성할 수 없다. 즉, 전역 객체를 생성할 수 있는 생성자 함수가 제공되지 않는다.
- 전역 객체의 프로퍼티를 참조할 때 window(또는 global)를 생략할 수 있다.
- 전역 객체는 0bject, String, Number, Boolean, Function, Array, RegExp, Date, Math, Promise 같은 모든 표준 빌트인 객체를 프로퍼티로 가지고 있다.
- 자바스크립트 실행 환경(브라우저 환경 또는 Node js 환경)에 따라 추가적으로 프로퍼티와 메서드를 갖는다. 브라우저 환경에서는 DOM, BOM, Canvas, XMLHttpRequest, fetch, requestAnimationFrame, SVG, Web Storage, Web Component, Web Worker 같은 클라이언트 사이드 Web AP를 호스트 객체로 제공하고 Node js 환경에서는 Node js 고유의 API를 호스트 객체로 제공한다.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- 자바스크립트 실행 환경(브라우저 환경 또는 Node js 환경)에 따라 추가적으로 프로퍼티와 메서드를 갖는다. 브라우저 환경에서는 DOM, BOM, Canvas, XMLHttpRequest, fetch, requestAnimationFrame, SVG, Web Storage, Web Component, Web Worker 같은 클라이언트 사이드 Web AP를 호스트 객체로 제공하고 Node js 환경에서는 Node js 고유의 API를 호스트 객체로 제공한다.
- 자바스크립트 실행 환경(브라우저 환경 또는 Node js 환경)에 따라 추가적으로 프로퍼티와 메서드를 갖는다. 브라우저 환경에서는 DOM, BOM, Canvas, XMLHttpRequest, fetch, requestAnimationFrame, SVG, Web Storage, Web Component, Web Worker 같은 클라이언트 사이드 Web API를 호스트 객체로 제공하고 Node js 환경에서는 Node js 고유의 API를 호스트 객체로 제공한다.


## 빌트인 전역 함수

- eval(쓰지말자)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존에 몇천 줄짜리 js 코드를 그대로 <script> 태그 안에서 사용 중인 코드를 볼 일이 있었어요.
이러한 상황에서 추가 기능을 개발하거나 기존 기능을 개선한다면 어떻게 효과적으로 모듈화를 진행할 수 있을까요??

@clicelee clicelee requested a review from songeunseo January 19, 2025 09:13
Copy link
Member

@zziglet zziglet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스터디 도중~

Comment on lines +39 to +47
- **프로토타입 메서드**는 인스턴스에서 호출되는 메서드로, 인스턴스와 관련된 동작을 처리.
```jsx
const numObj = new Number(1.5); // Number 인스턴스 생성
console.log(numObj.toFixed(2)); // "1.50" (소수점 2자리까지 문자열 반환)
```
- **정적 메서드**는 클래스(혹은 객체)에서 직접 호출되어, 인스턴스와 상관없이 동작.
```jsx
console.log(Number.isInteger(0.5)); // false (정수인지 검사)
console.log(Number.isInteger(2)); // true (정수 확인)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스터디 도중 필기
new로 생성한 애가 프로토타입 메서드?
-> 이건 아니다!

const numObj = 1.5;
이렇게 선언한 인스턴스도 호출 가능

Comment on lines +136 to +139
- isNaN
- parseFloat
- parseInt
- encodeURI / decodeURI
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isNaN이 빌트인 전역 함수였군요!! Number.isNaN()도 있다는 것!
encodeURI는 뭔가 Web API일 것 같은데 이것도 빌트인 전역 함수군요

@clicelee clicelee merged commit a3a5450 into main Jan 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants