From 2f303b6221d326176ab47dd665009be0d8466947 Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sat, 16 May 2026 01:28:25 +0900 Subject: [PATCH 01/19] docs: translate object-methods article to Korean Co-authored-by: Cursor --- .../04-object-methods/article.md | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md index 44d2eeff9c..fb41d92371 100644 --- a/1-js/04-object-basics/04-object-methods/article.md +++ b/1-js/04-object-basics/04-object-methods/article.md @@ -32,19 +32,11 @@ user.sayHi = function() { user.sayHi(); // 안녕하세요! ``` -<<<<<<< HEAD 함수 표현식으로 함수를 만들고, 객체 프로퍼티 `user.sayHi`에 함수를 할당해 주었습니다. 이제 객체에 할당된 함수를 호출하면 user가 인사를 해줍니다. 이렇게 객체 프로퍼티에 할당된 함수를 *메서드(method)* 라고 부릅니다. -======= -Here we've just used a Function Expression to create a function and assign it to the property `user.sayHi` of the object. - -Then we can call it as `user.sayHi()`. The user can now speak! - -A function that is a property of an object is called its *method*. ->>>>>>> upstream/master 위 예시에선 `user`에 할당된 `sayHi`가 메서드이죠. @@ -58,13 +50,8 @@ let user = { *!* // 함수 선언 function sayHi() { -<<<<<<< HEAD alert("안녕하세요!"); }; -======= - alert("Hello!"); -} ->>>>>>> upstream/master // 선언된 함수를 메서드로 등록 user.sayHi = sayHi; @@ -94,11 +81,7 @@ user = { // 단축 구문을 사용하니 더 깔끔해 보이네요. user = { *!* -<<<<<<< HEAD sayHi() { // "sayHi: function()"과 동일합니다. -======= - sayHi() { // same as "sayHi: function(){...}" ->>>>>>> upstream/master */!* alert("Hello"); } @@ -107,11 +90,7 @@ user = { 위처럼 `function`을 생략해도 메서드를 정의할 수 있습니다. -<<<<<<< HEAD 일반적인 방법과 단축 구문을 사용한 방법이 완전히 동일하진 않습니다. 객체 상속과 관련된 미묘한 차이가 존재하는데 지금으로선 이 차이가 중요하지 않기 때문에 넘어가도록 하겠습니다. -======= -To tell the truth, the notations are not fully identical. There are subtle differences related to object inheritance (to be covered later), but for now they do not matter. In almost all cases, the shorter syntax is preferred. ->>>>>>> upstream/master ## 메서드와 this @@ -181,24 +160,14 @@ let user = { let admin = user; user = null; // user를 null로 덮어씁니다. -<<<<<<< HEAD admin.sayHi(); // sayHi()가 엉뚱한 객체를 참고하면서 에러가 발생했습니다. -======= -*!* -admin.sayHi(); // TypeError: Cannot read property 'name' of null -*/!* ->>>>>>> upstream/master ``` `alert` 함수가 `user.name` 대신 `this.name`을 인수로 받았다면 에러가 발생하지 않았을 겁니다. ## 자유로운 this -<<<<<<< HEAD 자바스크립트의 `this`는 다른 프로그래밍 언어의 `this`와 동작 방식이 다릅니다. 자바스크립트에선 모든 함수에 `this`를 사용할 수 있습니다. -======= -In JavaScript, keyword `this` behaves unlike most other programming languages. It can be used in any function, even if it's not a method of an object. ->>>>>>> upstream/master 아래와 같이 코드를 작성해도 문법 에러가 발생하지 않습니다. From f43ac7a3b42c8c881932f3dae0f738a2a5cac522 Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sat, 16 May 2026 01:28:31 +0900 Subject: [PATCH 02/19] docs: translate constructor-new article to Korean Co-authored-by: Cursor --- .../06-constructor-new/article.md | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/1-js/04-object-basics/06-constructor-new/article.md b/1-js/04-object-basics/06-constructor-new/article.md index d6a36085ed..b78ff84cfd 100644 --- a/1-js/04-object-basics/06-constructor-new/article.md +++ b/1-js/04-object-basics/06-constructor-new/article.md @@ -1,10 +1,6 @@ # new 연산자와 생성자 함수 -<<<<<<< HEAD 객체 리터럴 `{...}` 을 사용하면 객체를 쉽게 만들 수 있습니다. 그런데 개발을 하다 보면 유사한 객체를 여러 개 만들어야 할 때가 생기곤 합니다. 복수의 사용자, 메뉴 내 다양한 아이템을 객체로 표현하려고 하는 경우가 그렇죠. -======= -The regular `{...}` syntax allows us to create one object. But often we need to create many similar objects, like multiple users or menu items and so on. ->>>>>>> upstream/master `'new'` 연산자와 생성자 함수를 사용하면 유사한 객체 여러 개를 쉽게 만들 수 있습니다. @@ -68,17 +64,10 @@ let user = { 생성자의 의의는 바로 여기에 있습니다. 재사용할 수 있는 객체 생성 코드를 구현하는 것이죠. -<<<<<<< HEAD 잠깐! 모든 함수는 생성자 함수가 될 수 있다는 점을 잊지 마시기 바랍니다. `new`를 붙여 실행한다면 어떤 함수라도 위에 언급된 알고리즘이 실행됩니다. 이름의 '첫 글자가 대문자'인 함수는 `new`를 붙여 실행해야 한다는 점도 잊지 마세요. 공동의 약속이니까요. ````smart header="new function() { ... }" 재사용할 필요가 없는 복잡한 객체를 만들어야 한다고 해봅시다. 많은 양의 코드가 필요할 겁니다. 이럴 땐 아래와 같이 코드를 익명 생성자 함수로 감싸주는 방식을 사용할 수 있습니다. -======= -Let's note once again -- technically, any function (except arrow functions, as they don't have `this`) can be used as a constructor. It can be run with `new`, and it will execute the algorithm above. The "capital letter first" is a common agreement, to make it clear that a function is to be run with `new`. - -````smart header="new function() { ... }" -If we have many lines of code all about creation of a single complex object, we can wrap them in an immediately called constructor function, like this: ->>>>>>> upstream/master ```js // create a function and immediately call it with new @@ -92,11 +81,7 @@ let user = new function() { }; ``` -<<<<<<< HEAD 위 생성자 함수는 익명 함수이기 때문에 어디에도 저장되지 않습니다. 처음 만들 때부터 단 한 번만 호출할 목적으로 만들었기 때문에 재사용이 불가능합니다. 이렇게 익명 생성자 함수를 이용하면 재사용은 막으면서 코드를 캡슐화 할 수 있습니다. -======= -This constructor can't be called again, because it is not saved anywhere, just created and called. So this trick aims to encapsulate the code that constructs the single object, without future reuse. ->>>>>>> upstream/master ```` ## new.target과 생성자 함수 @@ -107,11 +92,7 @@ This constructor can't be called again, because it is not saved anywhere, just c `new.target` 프로퍼티를 사용하면 함수가 `new`와 함께 호출되었는지 아닌지를 알 수 있습니다. -<<<<<<< HEAD 일반적인 방법으로 함수를 호출했다면 `new.target`은 undefined를 반환합니다. 반면 `new`와 함께 호출한 경우엔 `new.target`은 함수 자체를 반환해줍니다. -======= -It is undefined for regular calls and equals the function if called with `new`: ->>>>>>> upstream/master ```js run function User() { @@ -189,13 +170,8 @@ alert( new SmallUser().name ); // 원숭이 `return`문이 있는 생성자 함수는 거의 없습니다. 여기선 튜토리얼의 완성도를 위해 특이 케이스를 소개해보았습니다. -<<<<<<< HEAD ````smart header="괄호 생략하기" 인수가 없는 생성자 함수는 괄호를 생략해 호출할 수 있습니다. -======= -````smart header="Omitting parentheses" -By the way, we can omit parentheses after `new`: ->>>>>>> upstream/master ```js let user = new User; // <-- 괄호가 없음 From 45477dc853e341e074231de0184e2fac2dbb62f6 Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sat, 16 May 2026 01:28:38 +0900 Subject: [PATCH 03/19] docs: translate constructor-new task (two-functions-one-object) to Korean Co-authored-by: Cursor --- .../06-constructor-new/1-two-functions-one-object/task.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md index fc4b2c0715..92ced0f619 100644 --- a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md +++ b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md @@ -4,11 +4,7 @@ importance: 2 # 함수 두 개로 동일한 객체 만들기 -<<<<<<< HEAD `new A()==new B()`가 성립 가능한 함수 `A`와 `B`를 만드는 게 가능할까요? -======= -Is it possible to create functions `A` and `B` so that `new A() == new B()`? ->>>>>>> upstream/master ```js no-beautify function A() { ... } From 1652412caf668f001cf98e3734d5046b8037a406 Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sat, 16 May 2026 01:28:46 +0900 Subject: [PATCH 04/19] docs: translate constructor-new task (calculator-constructor) to Korean Co-authored-by: Cursor --- .../06-constructor-new/2-calculator-constructor/task.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md index 5bdaa79abd..0529b5f49a 100644 --- a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md +++ b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md @@ -6,15 +6,9 @@ importance: 5 아래와 같은 세 개의 메서드를 가진 생성자 함수, `Calculator`를 만들어보세요. -<<<<<<< HEAD - `read()` -- `prompt` 함수를 이용해 사용자로부터 값 두 개를 받고, 이를 객체 프로퍼티에 저장합니다. - `sum()` -- 프로퍼티에 저장된 값 두 개를 더한 후 반환합니다. - `mul()` -- 프로퍼티에 저장된 값 두 개를 곱한 후 반환합니다. -======= -- `read()` prompts for two values and saves them as object properties with names `a` and `b` respectively. -- `sum()` returns the sum of these properties. -- `mul()` returns the multiplication product of these properties. ->>>>>>> upstream/master 예시: From 111dccacf21ebd11a2ef07cc3f65c3941b16fae4 Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sat, 16 May 2026 01:28:53 +0900 Subject: [PATCH 05/19] docs: translate optional-chaining article to Korean Co-authored-by: Cursor --- .../07-optional-chaining/article.md | 185 ++++-------------- 1 file changed, 36 insertions(+), 149 deletions(-) diff --git a/1-js/04-object-basics/07-optional-chaining/article.md b/1-js/04-object-basics/07-optional-chaining/article.md index 63c0c2e803..e8d59f10ca 100644 --- a/1-js/04-object-basics/07-optional-chaining/article.md +++ b/1-js/04-object-basics/07-optional-chaining/article.md @@ -3,38 +3,24 @@ [recent browser="new"] -<<<<<<< HEAD 옵셔널 체이닝(optional chaining) `?.`을 사용하면 프로퍼티가 없는 중첩 객체를 에러 없이 안전하게 접근할 수 있습니다. ## 옵셔널 체이닝이 필요한 이유 -======= -The optional chaining `?.` is a safe way to access nested object properties, even if an intermediate property doesn't exist. - -## The "non-existing property" problem ->>>>>>> upstream/master 이제 막 자바스크립트를 배우기 시작했다면 옵셔널 체이닝이 등장하게 된 배경 상황을 직접 겪어보지 않았을 겁니다. 몇 가지 사례를 재현하면서 왜 옵셔널 체이닝이 등장했는지 알아봅시다. -<<<<<<< HEAD 사용자가 여러 명 있는데 그중 몇 명은 주소 정보를 가지고 있지 않다고 가정해봅시다. 이럴 때 `user.address.street`를 사용해 주소 정보에 접근하면 에러가 발생할 수 있습니다. ```js run let user = {}; // 주소 정보가 없는 사용자 -======= -As an example, let's say we have `user` objects that hold the information about our users. - -Most of our users have addresses in `user.address` property, with the street `user.address.street`, but some did not provide them. - -In such case, when we attempt to get `user.address.street`, and the user happens to be without an address, we get an error: - -```js run -let user = {}; // a user without "address" property ->>>>>>> upstream/master alert(user.address.street); // TypeError: Cannot read property 'street' of undefined ``` -<<<<<<< HEAD +이는 예상된 결과입니다. 자바스크립트는 이런 식으로 동작합니다. `user.address`가 `undefined`이므로 `user.address.street`를 가져오려는 시도는 에러를 발생시킵니다. + +실제 개발 환경에서는 이런 상황에서 에러 대신 `undefined`를 반환받는 것이 더 나은 경우가 많습니다. + 또 다른 사례론 브라우저에서 동작하는 코드를 개발할 때 발생할 수 있는 문제가 있습니다. 자바스크립트를 사용해 페이지에 존재하지 않는 요소에 접근해 요소의 정보를 가져오려 하면 문제가 발생하죠. ```js run @@ -42,97 +28,72 @@ alert(user.address.street); // TypeError: Cannot read property 'street' of undef let html = document.querySelector('.my-element').innerHTML; ``` -명세서에 `?.`이 추가되기 전엔 이런 문제들을 해결하기 위해 `&&` 연산자를 사용하곤 했습니다. - -예시: -======= -That's the expected result. JavaScript works like this. As `user.address` is `undefined`, an attempt to get `user.address.street` fails with an error. +이 경우에도 요소가 존재하지 않으면 `null의` `.innerHTML` 프로퍼티에 접근하려 했기 때문에 에러가 발생합니다. 요소가 없는 것이 정상적인 상황일 때도 있는데, 이럴 때는 에러를 피하고 그냥 `html = null`을 결과로 받아들이고 싶을 것입니다. -In many practical cases we'd prefer to get `undefined` instead of an error here (meaning "no street"). +어떻게 하면 될까요? -...and another example. In Web development, we can get an object that corresponds to a web page element using a special method call, such as `document.querySelector('.elem')`, and it returns `null` when there's no such element. +가장 직관적인 해결책은 프로퍼티에 접근하기 전에 `if`문이나 조건부 연산자 `?`를 사용해 값을 확인하는 것입니다. 다음과 같이 말이죠. -```js run -// document.querySelector('.elem') is null if there's no element -let html = document.querySelector('.elem').innerHTML; // error if it's null ``` - -Once again, if the element doesn't exist, we'll get an error accessing `.innerHTML` property of `null`. And in some cases, when the absence of the element is normal, we'd like to avoid the error and just accept `html = null` as the result. - -How can we do this? - -The obvious solution would be to check the value using `if` or the conditional operator `?`, before accessing its property, like this: - -```js let user = {}; alert(user.address ? user.address.street : undefined); ``` -It works, there's no error... But it's quite inelegant. As you can see, the `"user.address"` appears twice in the code. +에러 없이 잘 동작하네요. 하지만 코드가 꽤 볼품없습니다. 보시다시피 "user.address"가 코드에 두 번이나 등장합니다. -Here's how the same would look for `document.querySelector`: +`document.querySelector`를 사용한 예시는 다음과 같은 모습일 것입니다. -```js run +``` let html = document.querySelector('.elem') ? document.querySelector('.elem').innerHTML : null; ``` -We can see that the element search `document.querySelector('.elem')` is actually called twice here. Not good. +요소 검색을 위한 `document.querySelector('.elem')`이 실제로 두 번이나 호출된 것을 볼 수 있습니다. 좋지 않은 방법이죠. -For more deeply nested properties, it becomes even uglier, as more repetitions are required. +프로퍼티가 더 깊이 중첩되어 있다면 코드는 반복이 늘어나 더 지저분해질 것입니다. -E.g. let's get `user.address.street.name` in a similar fashion. +비슷한 방식으로 `user.address.street.name`을 가져와 보겠습니다. ```js -let user = {}; // user has no address +let user = {}; // 주소 정보가 없는 사용자 alert(user.address ? user.address.street ? user.address.street.name : null : null); ``` -That's just awful, one may even have problems understanding such code. +정말 끔찍하네요. 이런 코드는 이해하기조차 어려울 수 있습니다. -There's a little better way to write it, using the `&&` operator: ->>>>>>> upstream/master +명세서에 `?.`이 추가되기 전엔 이런 문제들을 해결하기 위해 `&&` 연산자를 사용하곤 했습니다. +예시 : ```js run let user = {}; // 주소 정보가 없는 사용자 -<<<<<<< HEAD alert( user && user.address && user.address.street ); // undefined, 에러가 발생하지 않습니다. ``` 중첩 객체의 특정 프로퍼티에 접근하기 위해 거쳐야 할 구성요소들을 AND로 연결해 실제 해당 객체나 프로퍼티가 있는지 확인하는 방법을 사용했었죠. 그런데 이렇게 AND를 연결해서 사용하면 코드가 아주 길어진다는 단점이 있습니다. -======= -alert( user.address && user.address.street && user.address.street.name ); // undefined (no error) -``` -AND'ing the whole path to the property ensures that all components exist (if not, the evaluation stops), but also isn't ideal. +보시다시피 프로퍼티 이름이 코드 내에서 여전히 중복되기 때문입니다. 예를 들어 위 코드에서는 `user.address`가 세 번이나 등장합니다. -As you can see, property names are still duplicated in the code. E.g. in the code above, `user.address` appears three times. - -That's why the optional chaining `?.` was added to the language. To solve this problem once and for all! ->>>>>>> upstream/master +바로 이런 문제를 완전히 해결하기 위해 옵셔널 체이닝(optional chaining) `?.`이 자바스크립트에 추가되었습니다! ## 옵셔널 체이닝의 등장 -<<<<<<< HEAD `?.`은 `?.`'앞'의 평가 대상이 `undefined`나 `null`이면 평가를 멈추고 `undefined`를 반환합니다. -======= -The optional chaining `?.` stops the evaluation if the value before `?.` is `undefined` or `null` and returns `undefined`. ->>>>>>> upstream/master **설명이 장황해지지 않도록 지금부턴 평가후 결과가 `null`이나 `undefined`가 아닌 경우엔 값이 '있다' 혹은 '존재한다'라고 표현하겠습니다.** -<<<<<<< HEAD 이제 옵셔널 체이닝을 사용해 `user.address.street`에 안전하게 접근해봅시다. -======= -In other words, `value?.prop`: -- works as `value.prop`, if `value` exists, -- otherwise (when `value` is `undefined/null`) it returns `undefined`. -Here's the safe way to access `user.address.street` using `?.`: ->>>>>>> upstream/master +즉, `value?.prop`은 다음과 같이 평가됩니다. + +* `value`가 존재하면 `value.prop`처럼 동작합니다. + +* 그렇지 않은 경우(`value`가 `undefined`나 `null`일 때)에는 `undefined`를 반환합니다. + +이제 `?.`을 사용해 `user.address.street`에 안전하게 접근해 봅시다. + ```js run let user = {}; // 주소 정보가 없는 사용자 @@ -140,19 +101,18 @@ let user = {}; // 주소 정보가 없는 사용자 alert( user?.address?.street ); // undefined, 에러가 발생하지 않습니다. ``` -<<<<<<< HEAD `user?.address`로 주소를 읽으면 아래와 같이 `user` 객체가 존재하지 않더라도 에러가 발생하지 않습니다. -======= -The code is short and clean, there's no duplication at all. -Here's an example with `document.querySelector`: +코드가 짧고 깔끔해졌으며, 중복도 전혀 없습니다. -```js run -let html = document.querySelector('.elem')?.innerHTML; // will be undefined, if there's no element +`document.querySelector`를 사용한 예시를 살펴봅시다. + +```javascript +let html = document.querySelector('.elem')?.innerHTML; // 요소가 존재하지 않으면 undefined가 됩니다. ``` -Reading the address with `user?.address` works even if `user` object doesn't exist: ->>>>>>> upstream/master +`user?.address`로 주소를 읽으면 아래와 같이 `user` 객체가 존재하지 않더라도 에러가 발생하지 않고 잘 동작합니다. + ```js run let user = null; @@ -163,26 +123,16 @@ alert( user?.address.street ); // undefined 위 예시를 통해 우리는 `?.`은 `?.` '앞' 평가 대상에만 동작되고, 확장은 되지 않는다는 사실을 알 수 있습니다. -<<<<<<< HEAD 참고로 위 예시에서 사용된 `user?.`는 `user`가 `null`이나 `undefined`인 경우만 처리할 수 있습니다. `user`가 `null`이나 `undefined`가 아니고 실제 값이 존재하는 경우엔 반드시 `user.address` 프로퍼티는 있어야 합니다. 그렇지 않으면 `user?.address.street`의 두 번째 점 연산자에서 에러가 발생합니다. -======= -E.g. in `user?.address.street.name` the `?.` allows `user` to safely be `null/undefined` (and returns `undefined` in that case), but that's only for `user`. Further properties are accessed in a regular way. If we want some of them to be optional, then we'll need to replace more `.` with `?.`. ->>>>>>> upstream/master ```warn header="옵셔널 체이닝을 남용하지 마세요." `?.`는 존재하지 않아도 괜찮은 대상에만 사용해야 합니다. -<<<<<<< HEAD 사용자 주소를 다루는 위 예시에서 논리상 `user`는 반드시 있어야 하는데 `address`는 필수값이 아닙니다. 그러니 `user.address?.street`를 사용하는 것이 바람직합니다. -실수로 인해 `user`에 값을 할당하지 않았다면 바로 알아낼 수 있도록 해야 합니다. 그렇지 않으면 에러를 조기에 발견하지 못하고 디버깅이 어려워집니다. -======= -For example, if according to our code logic `user` object must exist, but `address` is optional, then we should write `user.address?.street`, but not `user?.address?.street`. - -Then, if `user` happens to be undefined, we'll see a programming error about it and fix it. Otherwise, if we overuse `?.`, coding errors can be silenced where not appropriate, and become more difficult to debug. ->>>>>>> upstream/master +이렇게 하면 실수로 `user`가 `undefined`가 되었을 때 이를 알려주는 에러가 발생하므로 바로 확인하고 수정할 수 있습니다. 반대로 `?.`을 남용하면, 적절치 않은 상황에서도 에러가 조용히 무시되어 버리기 때문에 디버깅이 더욱 어려워집니다. ``` ````warn header="`?.`앞의 변수는 꼭 선언되어 있어야 합니다." @@ -192,43 +142,25 @@ Then, if `user` happens to be undefined, we'll see a programming error about it // ReferenceError: user is not defined user?.address; ``` -<<<<<<< HEAD `user?.anything`을 사용하려면 `let`이나 `const`, `var`를 사용해 `user`를 정의해야 하죠. 이렇게 옵셔널 체이닝은 선언이 완료된 변수를 대상으로만 동작합니다. -======= -The variable must be declared (e.g. `let/const/var user` or as a function parameter). The optional chaining works only for declared variables. ->>>>>>> upstream/master ```` ## 단락 평가 `?.`는 왼쪽 평가대상에 값이 없으면 즉시 평가를 멈춥니다. 참고로 이런 평가 방법을 단락 평가(short-circuit)라고 부릅니다. -<<<<<<< HEAD 그렇기 때문에 함수 호출을 비롯한 `?.` 오른쪽에 있는 부가 동작은 `?.`의 평가가 멈췄을 때 더는 일어나지 않습니다. -======= -So, if there are any further function calls or operations to the right of `?.`, they won't be made. - -For instance: ->>>>>>> upstream/master ```js run let user = null; let x = 0; -<<<<<<< HEAD user?.sayHi(x++); // 아무 일도 일어나지 않습니다. -======= -user?.sayHi(x++); // no "user", so the execution doesn't reach sayHi call and x++ ->>>>>>> upstream/master alert(x); // 0, x는 증가하지 않습니다. ``` -<<<<<<< HEAD ## ?.()와 ?.[] -======= -## Other variants: ?.(), ?.[] ->>>>>>> upstream/master `?.`은 연산자가 아닙니다. `?.`은 함수나 대괄호와 함께 동작하는 특별한 문법 구조체(syntax construct)입니다. @@ -246,7 +178,6 @@ let userAdmin = { let userGuest = {}; *!* -<<<<<<< HEAD user1.admin?.(); // 관리자 계정입니다. user2.admin?.(); */!* @@ -255,19 +186,6 @@ user2.admin?.(); 두 상황 모두에서 user 객체는 존재하기 때문에 `admin` 프로퍼티는 `.`만 사용해 접근했습니다. 그리고 난 후 `?.()`를 사용해 `admin`의 존재 여부를 확인했습니다. `user1`엔 `admin`이 정의되어 있기 때문에 메서드가 제대로 호출되었습니다. 반면 `user2`엔 `admin`이 정의되어 있지 않았음에도 불구하고 메서드를 호출하면 에러 없이 그냥 평가가 멈추는 것을 확인할 수 있습니다. -======= -userAdmin.admin?.(); // I am admin -*/!* - -*!* -userGuest.admin?.(); // nothing happens (no such method) -*/!* -``` - -Here, in both lines we first use the dot (`userAdmin.admin`) to get `admin` property, because we assume that the `user` object exists, so it's safe read from it. - -Then `?.()` checks the left part: if the `admin` function exists, then it runs (that's so for `userAdmin`). Otherwise (for `userGuest`) the evaluation stops without errors. ->>>>>>> upstream/master `.`대신 대괄호 `[]`를 사용해 객체 프로퍼티에 접근하는 경우엔 `?.[]`를 사용할 수도 있습니다. 위 예시와 마찬가지로 `?.[]`를 사용하면 객체 존재 여부가 확실치 않은 경우에도 안전하게 프로퍼티를 읽을 수 있습니다. @@ -278,13 +196,9 @@ let user1 = { firstName: "Violet" }; -<<<<<<< HEAD let user2 = null; // user2는 권한이 없는 사용자라고 가정해봅시다. let key = "firstName"; -======= -let user2 = null; ->>>>>>> upstream/master alert( user1?.[key] ); // Violet alert( user2?.[key] ); // undefined @@ -296,17 +210,11 @@ alert( user2?.[key] ); // undefined delete user?.name; // user가 존재하면 user.name을 삭제합니다. ``` -<<<<<<< HEAD ```warn header="`?.`은 읽기나 삭제하기에는 사용할 수 있지만 쓰기에는 사용할 수 없습니다." `?.`은 할당 연산자 왼쪽에서 사용할 수 없습니다. -======= -````warn header="We can use `?.` for safe reading and deleting, but not writing" -The optional chaining `?.` has no use on the left side of an assignment. ->>>>>>> upstream/master -For example: +예시: ```js run -<<<<<<< HEAD // user가 존재할 경우 user.name에 값을 쓰려는 의도로 아래와 같이 코드를 작성해 보았습니다. user?.name = "Violet"; // SyntaxError: Invalid left-hand side in assignment @@ -320,32 +228,11 @@ user?.name = "Violet"; // SyntaxError: Invalid left-hand side in assignment 1. `obj?.prop` -- `obj`가 존재하면 `obj.prop`을 반환하고, 그렇지 않으면 `undefined`를 반환함 2. `obj?.[prop]` -- `obj`가 존재하면 `obj[prop]`을 반환하고, 그렇지 않으면 `undefined`를 반환함 3. `obj?.method()` -- `obj`가 존재하면 `obj.method()`를 호출하고, 그렇지 않으면 `undefined`를 반환함 -======= -let user = null; - -user?.name = "John"; // Error, doesn't work -// because it evaluates to: undefined = "John" -``` - -```` - -## Summary - -The optional chaining `?.` syntax has three forms: - -1. `obj?.prop` -- returns `obj.prop` if `obj` exists, otherwise `undefined`. -2. `obj?.[prop]` -- returns `obj[prop]` if `obj` exists, otherwise `undefined`. -3. `obj.method?.()` -- calls `obj.method()` if `obj.method` exists, otherwise returns `undefined`. ->>>>>>> upstream/master 여러 예시를 통해 살펴보았듯이 옵셔널 체이닝 문법은 꽤 직관적이고 사용하기도 쉽습니다. `?.` 왼쪽 평가 대상이 `null`이나 `undefined`인지 확인하고 `null`이나 `undefined`가 아니라면 평가를 계속 진행합니다. `?.`를 계속 연결해서 체인을 만들면 중첩 프로퍼티들에 안전하게 접근할 수 있습니다. -<<<<<<< HEAD `?.`은 `?.`왼쪽 평가대상이 없어도 괜찮은 경우에만 선택적으로 사용해야 합니다. 꼭 있어야 하는 값인데 없는 경우에 `?.`을 사용하면 프로그래밍 에러를 쉽게 찾을 수 없으므로 이런 상황을 만들지 말도록 합시다. -======= -Still, we should apply `?.` carefully, only where it's acceptable, according to our code logic, that the left part doesn't exist. So that it won't hide programming errors from us, if they occur. ->>>>>>> upstream/master From 8cacda3ec55b85152e8a7225ae3dcb8e7374124e Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sat, 16 May 2026 01:28:59 +0900 Subject: [PATCH 06/19] docs: translate symbol article to Korean Co-authored-by: Cursor --- 1-js/04-object-basics/08-symbol/article.md | 89 +++------------------- 1 file changed, 11 insertions(+), 78 deletions(-) diff --git a/1-js/04-object-basics/08-symbol/article.md b/1-js/04-object-basics/08-symbol/article.md index 1e484b6707..f9941efda1 100644 --- a/1-js/04-object-basics/08-symbol/article.md +++ b/1-js/04-object-basics/08-symbol/article.md @@ -1,22 +1,18 @@ # 심볼형 -<<<<<<< HEAD 자바스크립트는 객체 프로퍼티 키로 오직 문자형과 심볼형만을 허용합니다. 숫자형, 불린형 모두 불가능하고 오직 문자형과 심볼형만 가능하죠. 지금까지는 프로퍼티 키가 문자형인 경우만 살펴보았습니다. 이번 챕터에선 프로퍼티 키로 심볼값을 사용해 보면서, 심볼형 키를 사용할 때의 이점에 대해 살펴보도록 하겠습니다. -======= -By specification, only two primitive types may serve as object property keys: -- string type, or -- symbol type. +- 문자형 또는 +- 심볼형 -Otherwise, if one uses another type, such as number, it's autoconverted to string. So that `obj[1]` is the same as `obj["1"]`, and `obj[true]` is the same as `obj["true"]`. +숫자형 등 다른 자료형을 키로 사용하면 문자형으로 자동 변환됩니다. 따라서 `obj[1]`은 `obj["1"]`과 같고, `obj[true]`는 `obj["true"]`와 같습니다. -Until now we've been using only strings. +지금까지는 프로퍼티 키가 문자형인 경우만 살펴보았습니다. -Now let's explore symbols, see what they can do for us. ->>>>>>> upstream/master +이제 심볼에 대해 알아보면서 심볼형 키를 사용할 때의 이점에 대해 살펴보겠습니다. ## 심볼 @@ -25,29 +21,18 @@ Now let's explore symbols, see what they can do for us. `Symbol()`을 사용하면 심볼값을 만들 수 있습니다. ```js -<<<<<<< HEAD // id는 새로운 심볼이 됩니다. let id = Symbol(); ``` 심볼을 만들 때 심볼 이름이라 불리는 설명을 붙일 수도 있습니다. 심볼 이름은 디버깅 시 아주 유용합니다. -======= -let id = Symbol(); -``` - -Upon creation, we can give symbols a description (also called a symbol name), mostly useful for debugging purposes: ->>>>>>> upstream/master ```js // 심볼 id에는 "id"라는 설명이 붙습니다. let id = Symbol("id"); ``` -<<<<<<< HEAD 심볼은 유일성이 보장되는 자료형이기 때문에, 설명이 동일한 심볼을 여러 개 만들어도 각 심볼값은 다릅니다. 심볼에 붙이는 설명(심볼 이름)은 어떤 것에도 영향을 주지 않는 이름표 역할만을 합니다. -======= -Symbols are guaranteed to be unique. Even if we create many symbols with exactly the same description, they are different values. The description is just a label that doesn't affect anything. ->>>>>>> upstream/master 설명이 같은 심볼 두 개를 만들고 이를 비교해보겠습니다. 동일 연산자(`==`)로 비교 시 `false`가 반환되는 것을 확인할 수 있습니다. @@ -62,15 +47,10 @@ alert(id1 == id2); // false 참고로 Ruby 등의 언어에서도 '심볼'과 유사한 개념을 사용하는데, 자바스크립트의 심볼은 이들 언어에 쓰이는 심볼과는 다르기 때문에 혼동하지 마시길 바랍니다. -<<<<<<< HEAD +요약하자면, 심볼은 이름(설명)을 선택적으로 붙일 수 있는 "유일무이한 원시값"입니다. 이제 심볼을 어디에 사용할 수 있는지 살펴봅시다. + ````warn header="심볼은 문자형으로 자동 형 변환되지 않습니다." 자바스크립트에선 문자형으로의 암시적 형 변환이 비교적 자유롭게 일어나는 편입니다. `alert` 함수가 거의 모든 값을 인자로 받을 수 있는 이유가 이 때문이죠. 그러나 심볼은 예외입니다. 심볼형 값은 다른 자료형으로 암시적 형 변환(자동 형 변환)되지 않습니다. -======= -So, to summarize, a symbol is a "primitive unique value" with an optional description. Let's see where we can use them. - -````warn header="Symbols don't auto-convert to a string" -Most values in JavaScript support implicit conversion to a string. For instance, we can `alert` almost any value, and it will work. Symbols are special. They don't auto-convert. ->>>>>>> upstream/master 아래 예시에서 `alert`는 에러를 발생시킵니다. @@ -83,12 +63,7 @@ alert(id); // TypeError: Cannot convert a Symbol value to a string 문자열과 심볼은 근본이 다르기 때문에 우연히라도 서로의 타입으로 변환돼선 안 됩니다. 자바스크립트에선 '언어 차원의 보호장치(language guard)'를 마련해 심볼형이 다른 형으로 변환되지 않게 막아줍니다. -<<<<<<< HEAD 심볼을 반드시 출력해줘야 하는 상황이라면 아래와 같이 `.toString()` 메서드를 명시적으로 호출해주면 됩니다. -======= -If we really want to show a symbol, we need to explicitly call `.toString()` on it, like here: - ->>>>>>> upstream/master ```js run let id = Symbol("id"); *!* @@ -96,12 +71,7 @@ alert(id.toString()); // Symbol(id)가 얼럿 창에 출력됨 */!* ``` -<<<<<<< HEAD `symbol.description` 프로퍼티를 이용하면 설명만 보여주는 것도 가능합니다. -======= -Or get `symbol.description` property to show the description only: - ->>>>>>> upstream/master ```js run let id = Symbol("id"); *!* @@ -113,12 +83,7 @@ alert(id.description); // id ## '숨김' 프로퍼티 -<<<<<<< HEAD -심볼을 이용하면 '숨김(hidden)' 프로퍼티를 만들 수 있습니다. 숨김 프로퍼티는 외부 코드에서 접근이 불가능하고 값도 덮어쓸 수 없는 프로퍼티입니다. -======= - -Symbols allow us to create "hidden" properties of an object, that no other part of code can accidentally access or overwrite. ->>>>>>> upstream/master +심볼을 이용하면 "숨김(hidden)" 프로퍼티를 만들 수 있습니다. 숨김 프로퍼티는 외부 코드에서 접근이 불가능하고 값도 덮어쓸 수 없는 프로퍼티입니다. 서드파티 코드에서 가지고 온 `user`라는 객체가 여러 개 있고, `user`를 이용해 어떤 작업을 해야 하는 상황이라고 가정해 봅시다. `user`에 식별자를 붙여주도록 합시다. @@ -138,15 +103,11 @@ alert( user[id] ); // 심볼을 키로 사용해 데이터에 접근할 수 있 그런데 문자열 `"id"`를 키로 사용해도 되는데 `Symbol("id")`을 사용한 이유가 무엇일까요? -<<<<<<< HEAD `user`는 서드파티 코드에서 가지고 온 객체이므로 함부로 새로운 프로퍼티를 추가할 수 없습니다. 그런데 심볼은 서드파티 코드에서 접근할 수 없기 때문에, 심볼을 사용하면 서드파티 코드가 모르게 `user`에 식별자를 부여할 수 있습니다. 상황 하나를 더 가정해보겠습니다. 제3의 스크립트(자바스크립트 라이브러리 등)에서 `user`를 식별해야 하는 상황이 벌어졌다고 해보죠. `user`의 원천인 서드파티 코드, 현재 작성 중인 스크립트, 제3의 스크립트가 각자 서로의 코드도 모른 채 `user`를 식별해야 하는 상황이 벌어졌습니다. -======= -As `user` objects belong to another codebase, it's unsafe to add fields to them, since we might affect pre-defined behavior in that other codebase. However, symbols cannot be accessed accidentally. The third-party code won't be aware of newly defined symbols, so it's safe to add symbols to the `user` objects. -Also, imagine that another script wants to have its own identifier inside `user`, for its own purposes. ->>>>>>> upstream/master +또한, 또 다른 스크립트가 자기만의 목적을 위해 `user` 안에 자체 식별자를 추가해야 하는 상황을 가정해 봅시다. 제3의 스크립트에선 아래와 같이 `Symbol("id")`을 이용해 전용 식별자를 만들어 사용할 수 있습니다. @@ -209,19 +170,13 @@ let user = { for (let key in user) alert(key); // name과 age만 출력되고, 심볼은 출력되지 않습니다. */!* -<<<<<<< HEAD // 심볼로 직접 접근하면 잘 작동합니다. alert( "직접 접근한 값: " + user[id] ); ``` -`Object.keys(user)`에서도 키가 심볼인 프로퍼티는 배제됩니다. '심볼형 프로퍼티 숨기기(hiding symbolic property)'라 불리는 이런 원칙 덕분에 외부 스크립트나 라이브러리는 심볼형 키를 가진 프로퍼티에 접근하지 못합니다. -======= -// the direct access by the symbol works -alert( "Direct: " + user[id] ); // Direct: 123 -``` +[Object.keys(user)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys)에서도 키가 심볼인 프로퍼티는 무시됩니다. 이는 "심볼형 프로퍼티 숨기기(hiding symbolic properties)" 원칙의 일환입니다. 만약 외부 스크립트나 라이브러리가 우리가 만든 객체를 반복문으로 순회하더라도, 심볼형 프로퍼티에 의도치 않게 접근하는 일은 발생하지 않습니다. + -[Object.keys(user)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) also ignores them. That's a part of the general "hiding symbolic properties" principle. If another script or a library loops over our object, it won't unexpectedly access a symbolic property. ->>>>>>> upstream/master 그런데 [Object.assign](mdn:js/Object/assign)은 키가 심볼인 프로퍼티를 배제하지 않고 객체 내 모든 프로퍼티를 복사합니다. @@ -266,20 +221,12 @@ alert( id === idAgain ); // true ```smart header="Ruby랑 비슷해 보이네요." Ruby 등의 몇몇 언어에선 이름이 같으면 심볼도 같습니다. -<<<<<<< HEAD 자바스크립트에선 전역 심볼에만 이런 특징이 적용됩니다. -======= -In JavaScript, as we can see, that's true for global symbols. ->>>>>>> upstream/master ``` ### Symbol.keyFor -<<<<<<< HEAD 전역 심볼을 찾을 때 사용되는 `Symbol.for(key)`에 반대되는 메서드도 있습니다. `Symbol.keyFor(sym)`를 사용하면 이름을 얻을 수 있습니다. -======= -We have seen that for global symbols, `Symbol.for(key)` returns a symbol by name. To do the opposite -- return a name by global symbol -- we can use: `Symbol.keyFor(sym)`: ->>>>>>> upstream/master 예시: @@ -295,11 +242,7 @@ alert( Symbol.keyFor(sym2) ); // id `Symbol.keyFor`는 전역 심볼 레지스트리를 뒤져서 해당 심볼의 이름을 얻어냅니다. 검색 범위가 전역 심볼 레지스트리이기 때문에 전역 심볼이 아닌 심볼에는 사용할 수 없습니다. 전역 심볼이 아닌 인자가 넘어오면 `Symbol.keyFor`는 `undefined`를 반환합니다. -<<<<<<< HEAD 전역 심볼이 아닌 모든 심볼은 `description` 프로퍼티가 있습니다. 일반 심볼에서 이름을 얻고 싶으면 `description` 프로퍼티를 사용하면 됩니다. -======= -That said, all symbols have the `description` property. ->>>>>>> upstream/master 예시: @@ -339,21 +282,11 @@ alert( localSymbol.description ); // name 심볼의 주요 유스 케이스는 다음과 같습니다. -<<<<<<< HEAD 1. 객체의 '숨김' 프로퍼티 -- 외부 스크립트나 라이브러리에 '속한' 객체에 새로운 프로퍼티를 추가해 주고 싶다면 심볼을 만들고, 이를 프로퍼티 키로 사용하면 됩니다. 키가 심볼인 경우엔 `for..in`의 대상이 되지 않아서 의도치 않게 프로퍼티가 수정되는 것을 예방할 수 있습니다. 외부 스크립트나 라이브러리는 심볼 정보를 갖고 있지 않아서 프로퍼티에 직접 접근하는 것도 불가능합니다. 심볼형 키를 사용하면 프로퍼티가 우연히라도 사용되거나 덮어씌워 지는 걸 예방할 수 있습니다. -======= -1. "Hidden" object properties. - - If we want to add a property into an object that "belongs" to another script or a library, we can create a symbol and use it as a property key. A symbolic property does not appear in `for..in`, so it won't be accidentally processed together with other properties. Also it won't be accessed directly, because another script does not have our symbol. So the property will be protected from accidental use or overwrite. ->>>>>>> upstream/master 이런 특징을 이용하면 원하는 것을 객체 안에 '은밀하게' 숨길 수 있습니다. 외부 스크립트에선 우리가 숨긴 것을 절대 볼 수 없습니다. 2. 자바스크립트 내부에서 사용되는 시스템 심볼은 `Symbol.*`로 접근할 수 있습니다. 시스템 심볼을 이용하면 내장 메서드 등의 기본 동작을 입맛대로 변경할 수 있습니다. [iterable 객체](info:iterable)에선 `Symbol.iterator`를, [객체를 원시형으로 변환하기](info:object-toprimitive)에선 `Symbol.toPrimitive`이 어떻게 사용되는지 알아보겠습니다. -<<<<<<< HEAD 사실 심볼을 완전히 숨길 방법은 없습니다. 내장 메서드 [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols)를 사용하면 모든 심볼을 볼 수 있고, 메서드 [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys)는 심볼형 키를 포함한 객체의 *모든* 키를 반환해줍니다. 그런데 대부분의 라이브러리, 내장 함수 등은 이런 메서드를 사용하지 않습니다. -======= -Technically, symbols are not 100% hidden. There is a built-in method [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) that allows us to get all symbols. Also there is a method named [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys of an object including symbolic ones. But most libraries, built-in functions and syntax constructs don't use these methods. ->>>>>>> upstream/master From 8e72eb2b45b2d57c5a60b56b2afce6d8fd294a1c Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sat, 16 May 2026 01:29:05 +0900 Subject: [PATCH 07/19] docs: translate object-toprimitive article to Korean Co-authored-by: Cursor --- .../09-object-toprimitive/article.md | 143 ++---------------- 1 file changed, 16 insertions(+), 127 deletions(-) diff --git a/1-js/04-object-basics/09-object-toprimitive/article.md b/1-js/04-object-basics/09-object-toprimitive/article.md index c443e6354b..49970a491a 100644 --- a/1-js/04-object-basics/09-object-toprimitive/article.md +++ b/1-js/04-object-basics/09-object-toprimitive/article.md @@ -3,56 +3,38 @@ `obj1 + obj2` 처럼 객체끼리 더하는 연산을 하거나, `obj1 - obj2` 처럼 객체끼리 빼는 연산을 하면 어떤 일이 일어날까요? `alert(obj)`로 객체를 출력할 때는 무슨 일이 발생할까요? -<<<<<<< HEAD 이 모든 경우에 자동 형 변환이 일어납니다. 객체는 원시값으로 변환되고, 그 후 의도한 연산이 수행됩니다. -======= -JavaScript doesn't allow you to customize how operators work on objects. Unlike some other programming languages, such as Ruby or C++, we can't implement a special object method to handle addition (or other operators). -In case of such operations, objects are auto-converted to primitives, and then the operation is carried out over these primitives and results in a primitive value. +Ruby나 C++ 같은 다른 프로그래밍 언어와 달리, 덧셈(이나 다른 연산)을 처리하기 위한 특별한 객체 메서드를 구현할 수 없죠. -That's an important limitation: the result of `obj1 + obj2` (or another math operation) can't be another object! +객체에 이런 연산을 수행하면 객체는 원시값으로 자동 변환되고, 이후 이 원시값들을 대상으로 연산이 수행되어 최종적으로 원시값이 반환됩니다. -E.g. we can't make objects representing vectors or matrices (or achievements or whatever), add them and expect a "summed" object as the result. Such architectural feats are automatically "off the board". +이는 아주 중요한 제한 사항입니다. `obj1 + obj2` (또는 다른 수학 연산)의 결과는 또 다른 객체가 될 수 없습니다! -So, because we can't technically do much here, there's no maths with objects in real projects. When it happens, with rare exceptions, it's because of a coding mistake. +예를 들어, 벡터나 행렬(또는 게임의 성과 등)을 나타내는 객체를 만들고, 이를 더해서 '합산된' 객체를 결과로 기대할 수는 없습니다. 이러한 구조적 시도는 애초에 불가능합니다. -In this chapter we'll cover how an object converts to primitive and how to customize it. +이처럼 기술적인 제약이 있기 때문에 실제 프로젝트에서 객체를 대상으로 수학 연산을 하는 경우는 없습니다. 극히 예외적인 상황을 제외하면, 이런 연산이 발생했다는 것은 곧 코딩 실수가 있었음을 의미합니다. -We have two purposes: +이번 챕터에서는 객체가 어떻게 원시값으로 변환되는지, 그리고 이 변환을 어떻게 커스터마이징할 수 있는지 알아보겠습니다. -1. It will allow us to understand what's going on in case of coding mistakes, when such an operation happened accidentally. -2. There are exceptions, where such operations are possible and look good. E.g. subtracting or comparing dates (`Date` objects). We'll come across them later. +우리가 이를 배우는 목적은 두 가지입니다. + +1. 코딩 실수로 인해 의도치 않게 객체 연산이 발생했을 때, 내부적으로 어떤 일이 벌어지는지 이해하기 위해서입니다. + +2. 이런 연산이 가능하며 심지어 유용하게 쓰이는 예외적인 상황이 있기 때문입니다. 날짜(`Date` 객체)를 빼거나 비교하는 경우가 대표적인데, 이에 대해서는 나중에 다루겠습니다. -## Conversion rules ->>>>>>> upstream/master 챕터에선 객체의 형 변환은 다루지 않았습니다. 원시형 자료가 어떻게 문자, 숫자, 논리형으로 변환되는지만 알아보았죠. 이젠 메서드와 심볼에 대한 지식을 갖추었으니 본격적으로 이 공백을 메꿔봅시다. -<<<<<<< HEAD 1. 객체는 논리 평가 시 `true`를 반환합니다. 단 하나의 예외도 없죠. 따라서 객체는 숫자형이나 문자형으로만 형 변환이 일어난다고 생각하시면 됩니다. 2. 숫자형으로의 형 변환은 객체끼리 빼는 연산을 할 때나 수학 관련 함수를 적용할 때 일어납니다. 객체 `Date`끼리 차감하면(`date1 - date2`) 두 날짜의 시간 차이가 반환됩니다. `Date`에 대해선 에서 다룰 예정입니다. 3. 문자형으로의 형 변환은 대개 `alert(obj)`같이 객체를 출력하려고 할 때 일어납니다. -======= -1. There's no conversion to boolean. All objects are `true` in a boolean context, as simple as that. There exist only numeric and string conversions. -2. The numeric conversion happens when we subtract objects or apply mathematical functions. For instance, `Date` objects (to be covered in the chapter ) can be subtracted, and the result of `date1 - date2` is the time difference between two dates. -3. As for the string conversion -- it usually happens when we output an object with `alert(obj)` and in similar contexts. ->>>>>>> upstream/master We can implement string and numeric conversion by ourselves, using special object methods. -<<<<<<< HEAD 특수 객체 메서드를 사용하면 숫자형이나 문자형으로의 형 변환을 원하는 대로 조절할 수 있습니다. 객체 형 변환은 세 종류로 구분되는데, 'hint'라 불리는 값이 구분 기준이 됩니다. 'hint'가 무엇인지는 [명세서](https://tc39.github.io/ecma262/#sec-toprimitive)에 자세히 설명되어 있는데, '목표로 하는 자료형' 정도로 이해하시면 될 것 같습니다. -======= -Now let's get into technical details, because it's the only way to cover the topic in-depth. - -## Hints - -How does JavaScript decide which conversion to apply? - -There are three variants of type conversion, that happen in various situations. They're called "hints", as described in the [specification](https://tc39.github.io/ecma262/#sec-toprimitive): ->>>>>>> upstream/master `"string"` : `alert` 함수같이 문자열을 기대하는 연산을 수행할 때는(객체-문자형 변환), hint가 `string`이 됩니다. @@ -85,11 +67,7 @@ There are three variants of type conversion, that happen in various situations. `"default"` : 연산자가 기대하는 자료형이 '확실치 않을 때' hint는 `default`가 됩니다. 아주 드물게 발생합니다. -<<<<<<< HEAD 이항 덧셈 연산자 `+`는 피연산자의 자료형에 따라 문자열을 합치는 연산을 할 수도 있고 숫자를 더해주는 연산을 할 수도 있습니다. 따라서 `+`의 인수가 객체일 때는 hint가 `default`가 됩니다. -======= - For instance, binary plus `+` can work both with strings (concatenates them) and numbers (adds them). So if a binary plus gets an object as an argument, it uses the `"default"` hint to convert it. ->>>>>>> upstream/master 동등 연산자 `==`를 사용해 객체-문자형, 객체-숫자형, 객체-심볼형끼리 비교할 때도, 객체를 어떤 자료형으로 바꿔야 할지 확신이 안 서므로 hint는 default가 됩니다. @@ -103,7 +81,6 @@ There are three variants of type conversion, that happen in various situations. 크고 작음을 비교할 때 쓰이는 연산자 `<`, `>` 역시 피연산자에 문자형과 숫자형 둘 다를 허용하는데, 이 연산자들은 hint를 'number'로 고정합니다. hint가 'default'가 되는 일이 없죠. 이는 하위 호환성 때문에 정해진 규칙입니다. -<<<<<<< HEAD 실제 일을 할 때는 이런 사항을 모두 외울 필요는 없습니다. `Date` 객체를 제외한 모든 내장 객체는 hint가 `"default"`인 경우와 `"number"`인 경우를 동일하게 처리하기 때문입니다. 우리도 커스텀 객체를 만들 땐 이런 규칙을 따르면 됩니다. ```smart header="`\"boolean\"` hint는 없습니다." @@ -111,53 +88,26 @@ hint는 총 세 가지입니다. 아주 간단하죠. 'boolean' hint는 존재하지 않습니다. 모든 객체는 그냥 `true`로 평가됩니다. 게다가 우리도 내장 객체에 사용되는 규칙처럼 `"default"`와 `"number"`를 동일하게 처리하면, 결국엔 두 종류의 형 변환(객체-문자형, 객체-숫자형)만 남게 됩니다. ``` -======= -In practice though, things are a bit simpler. - -All built-in objects except for one case (`Date` object, we'll learn it later) implement `"default"` conversion the same way as `"number"`. And we probably should do the same. - -Still, it's important to know about all 3 hints, soon we'll see why. ->>>>>>> upstream/master **자바스크립트는 형 변환이 필요할 때, 아래와 같은 알고리즘에 따라 원하는 메서드를 찾고 호출합니다.** -<<<<<<< HEAD 1. 객체에 `obj[Symbol.toPrimitive](hint)`메서드가 있는지 찾고, 있다면 메서드를 호출합니다. `Symbol.toPrimitive`는 시스템 심볼로, 심볼형 키로 사용됩니다. 2. 1에 해당하지 않고 hint가 `"string"`이라면, - `obj.toString()`이나 `obj.valueOf()`를 호출합니다(존재하는 메서드만 실행됨). 3. 1과 2에 해당하지 않고, hint가 `"number"`나 `"default"`라면 - `obj.valueOf()`나 `obj.toString()`을 호출합니다(존재하는 메서드만 실행됨). -======= -1. Call `obj[Symbol.toPrimitive](hint)` - the method with the symbolic key `Symbol.toPrimitive` (system symbol), if such method exists, -2. Otherwise if hint is `"string"` - - try calling `obj.toString()` or `obj.valueOf()`, whatever exists. -3. Otherwise if hint is `"number"` or `"default"` - - try calling `obj.valueOf()` or `obj.toString()`, whatever exists. ->>>>>>> upstream/master ## Symbol.toPrimitive 첫 번째 메서드부터 살펴봅시다. 자바스크립트엔 `Symbol.toPrimitive`라는 내장 심볼이 존재하는데, 이 심볼은 아래와 같이 목표로 하는 자료형(hint)을 명명하는 데 사용됩니다. ```js obj[Symbol.toPrimitive] = function(hint) { -<<<<<<< HEAD // 반드시 원시값을 반환해야 합니다. // hint는 "string", "number", "default" 중 하나가 될 수 있습니다. }; ``` 실제 돌아가는 예시를 살펴보는 게 좋을 것 같네요. `user` 객체에 객체-원시형 변환 메서드 `obj[Symbol.toPrimitive](hint)`를 구현해보겠습니다. -======= - // here goes the code to convert this object to a primitive - // it must return a primitive value - // hint = one of "string", "number", "default" -}; -``` - -If the method `Symbol.toPrimitive` exists, it's used for all hints, and no more methods are needed. - -For instance, here `user` object implements it: ->>>>>>> upstream/master ```js run let user = { @@ -176,16 +126,11 @@ alert(+user); // hint: number -> 1000 alert(user + 500); // hint: default -> 1500 ``` -<<<<<<< HEAD 이렇게 메서드를 구현해 놓으면 `user`는 hint에 따라 (자기 자신을 설명해주는) 문자열로 변환되기도 하고 (가지고 있는 돈의 액수를 나타내는) 숫자로 변환되기도 합니다. `user[Symbol.toPrimitive]`를 사용하면 메서드 하나로 모든 종류의 형 변환을 다룰 수 있습니다. -======= -As we can see from the code, `user` becomes a self-descriptive string or a money amount, depending on the conversion. The single method `user[Symbol.toPrimitive]` handles all conversion cases. ->>>>>>> upstream/master ## toString과 valueOf -<<<<<<< HEAD `toString`과 `valueOf`는 심볼이 생기기 이전부터 존재해 왔던 '평범한' 메서드입니다. 이 메서드를 이용하면 '구식'이긴 하지만 형 변환을 직접 구현할 수 있습니다. 객체에 `Symbol.toPrimitive`가 없으면 자바스크립트는 아래 규칙에 따라 `toString`이나 `valueOf`를 호출합니다. @@ -194,16 +139,6 @@ As we can see from the code, `user` becomes a self-descriptive string or a money - 그 외: `valueOf -> toString` 순 이 메서드들은 반드시 원시값을 반환해야합니다. `toString`이나 `valueOf`가 객체를 반환하면 그 결과는 무시됩니다. 마치 메서드가 처음부터 없었던 것처럼 되어버리죠. -======= -If there's no `Symbol.toPrimitive` then JavaScript tries to find methods `toString` and `valueOf`: - -- For the `"string"` hint: call `toString` method, and if it doesn't exist or if it returns an object instead of a primitive value, then call `valueOf` (so `toString` has the priority for string conversions). -- For other hints: call `valueOf`, and if it doesn't exist or if it returns an object instead of a primitive value, then call `toString` (so `valueOf` has the priority for maths). - -Methods `toString` and `valueOf` come from ancient times. They are not symbols (symbols did not exist that long ago), but rather "regular" string-named methods. They provide an alternative "old-style" way to implement the conversion. - -These methods must return a primitive value. If `toString` or `valueOf` returns an object, then it's ignored (same as if there were no method). ->>>>>>> upstream/master 일반 객체는 기본적으로 `toString`과 `valueOf`에 적용되는 다음 규칙을 따릅니다. @@ -221,15 +156,9 @@ alert(user.valueOf() === user); // true 이런 이유 때문에 `alert`에 객체를 넘기면 `[object Object]`가 출력되는 것입니다. -<<<<<<< HEAD 여기서 `valueOf`는 튜토리얼의 완성도를 높이고 헷갈리는 것을 줄여주려고 언급했습니다. 앞서 본 바와 같이 `valueOf`는 객체 자신을 반환하기 때문에 그 결과가 무시됩니다. 왜 그런거냐고 이유를 묻지는 말아주세요. 그냥 역사적인 이유때문입니다. 우리는 그냥 이 메서드가 존재하지 않는다고 생각하면 됩니다. 이제 직접 이 메서드들을 사용한 예시를 구현해봅시다. -======= -The default `valueOf` is mentioned here only for the sake of completeness, to avoid any confusion. As you can see, it returns the object itself, and so is ignored. Don't ask me why, that's for historical reasons. So we can assume it doesn't exist. - -Let's implement these methods to customize the conversion. ->>>>>>> upstream/master 아래 `user`는 `toString`과 `valueOf`를 조합해 만들었는데, `Symbol.toPrimitive`를 사용한 위쪽 예시와 동일하게 동작합니다. @@ -274,30 +203,19 @@ alert(user + 500); // toString -> John500 객체에 `Symbol.toPrimitive`와 `valueOf`가 없으면, `toString`이 모든 형 변환을 처리합니다. -<<<<<<< HEAD -## 반환 타입 -======= -### A conversion can return any primitive type ->>>>>>> upstream/master +### 변환은 어떤 원시형이든 반환할 수 있습니다 위에서 소개해드린 세 개의 메서드는 'hint'에 명시된 자료형으로의 형 변환을 보장해 주지 않습니다. -<<<<<<< HEAD `toString()`이 항상 문자열을 반환하리라는 보장이 없고, `Symbol.toPrimitive`의 hint가 `"number"`일 때 항상 숫자형 자료가 반환되리라는 보장이 없습니다. -======= -There is no control whether `toString` returns exactly a string, or whether `Symbol.toPrimitive` method returns a number for the hint `"number"`. ->>>>>>> upstream/master 확신할 수 있는 단 한 가지는 객체가 아닌 원시값을 반환해 준다는 것뿐입니다. ```smart header="과거의 잔재" `toString`이나 `valueOf`가 객체를 반환해도 에러가 발생하지 않습니다. 다만 이때는 반환 값이 무시되고, 메서드 자체가 존재하지 않았던 것처럼 동작합니다. 이렇게 동작하는 이유는 과거 자바스크립트엔 '에러'라는 개념이 잘 정립되어있지 않았기 때문입니다. -<<<<<<< HEAD 반면에 `Symbol.toPrimitive`는 *무조건* 원시자료를 반환해야 합니다. 그렇지 않으면 에러가 발생합니다. -======= In contrast, `Symbol.toPrimitive` is stricter, it *must* return a primitive, otherwise there will be an error. ->>>>>>> upstream/master ``` ## 추가 형 변환 @@ -308,15 +226,11 @@ In contrast, `Symbol.toPrimitive` is stricter, it *must* return a primitive, oth 1. 객체는 원시형으로 변화됩니다. 변환 규칙은 위에서 설명했습니다. 2. 변환 후 원시값이 원하는 형이 아닌 경우엔 또다시 형 변환이 일어납니다. -<<<<<<< HEAD -예시: -======= -If we pass an object as an argument, then there are two stages of calculations: -1. The object is converted to a primitive (using the rules described above). -2. If necessary for further calculations, the resulting primitive is also converted. +객체를 인수로 전달하면, 연산은 다음 두 단계를 거쳐 진행됩니다. +1. 객체는 (앞서 설명한 규칙에 따라) 원시값으로 변환됩니다. +2. 추가 연산에 필요하다면, 결과로 나온 원시값이 한 번 더 변환됩니다. -For instance: ->>>>>>> upstream/master +예시: ```js run let obj = { @@ -341,36 +255,22 @@ let obj = { } }; -<<<<<<< HEAD alert(obj + 2); // 22("2" + 2), 문자열이 반환되기 때문에 문자열끼리의 병합이 일어났습니다. -======= -alert(obj + 2); // "22" ("2" + 2), conversion to primitive returned a string => concatenation ->>>>>>> upstream/master ``` ## 요약 원시값을 기대하는 내장 함수나 연산자를 사용할 때 객체-원시형으로의 형 변환이 자동으로 일어납니다. -<<<<<<< HEAD 객체-원시형으로의 형 변환은 hint를 기준으로 세 종류로 구분할 수 있습니다. - `"string"` (`alert` 같이 문자열을 필요로 하는 연산) - `"number"` (수학 연산) - `"default"` (드물게 발생함) 연산자별로 어떤 hint가 적용되는지는 명세서에서 찾아볼 수 있습니다. 연산자가 기대하는 피연산자를 '확신할 수 없을 때'에는 hint가 `"default"`가 됩니다. 이런 경우는 아주 드물게 발생합니다. 내장 객체는 대개 hint가 `"default"`일 때와 `"number"`일 때를 동일하게 처리합니다. 따라서 실무에선 hint가 `"default"`인 경우와 `"number"`인 경우를 합쳐서 처리하는 경우가 많습니다. -======= -There are 3 types (hints) of it: -- `"string"` (for `alert` and other operations that need a string) -- `"number"` (for maths) -- `"default"` (few operators, usually objects implement it the same way as `"number"`) - -The specification describes explicitly which operator uses which hint. ->>>>>>> upstream/master 객체-원시형 변환엔 다음 알고리즘이 적용됩니다. -<<<<<<< HEAD 1. 객체에 `obj[Symbol.toPrimitive](hint)`메서드가 있는지 찾고, 있다면 호출합니다. 2. 1에 해당하지 않고 hint가 `"string"`이라면, - `obj.toString()`이나 `obj.valueOf()`를 호출합니다. @@ -378,14 +278,3 @@ The specification describes explicitly which operator uses which hint. - `obj.valueOf()`나 `obj.toString()`을 호출합니다. `obj.toString()`만 사용해도 '모든 변환'을 다 다룰 수 있기 때문에, 실무에선 `obj.toString()`만 구현해도 충분한 경우가 많습니다. 반환 값도 '사람이 읽고 이해할 수 있는' 형식이기 때문에 실용성 측면에서 다른 메서드에 뒤처지지 않습니다. `obj.toString()`은 로깅이나 디버깅 목적으로도 자주 사용됩니다. -======= -1. Call `obj[Symbol.toPrimitive](hint)` if the method exists, -2. Otherwise if hint is `"string"` - - try calling `obj.toString()` or `obj.valueOf()`, whatever exists. -3. Otherwise if hint is `"number"` or `"default"` - - try calling `obj.valueOf()` or `obj.toString()`, whatever exists. - -All these methods must return a primitive to work (if defined). - -In practice, it's often enough to implement only `obj.toString()` as a "catch-all" method for string conversions that should return a "human-readable" representation of an object, for logging or debugging purposes. ->>>>>>> upstream/master From 6d2a5a0f693c5b6b939fd5f787c91b9feace1f2e Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sat, 16 May 2026 01:29:12 +0900 Subject: [PATCH 08/19] docs: translate primitives-methods article to Korean Co-authored-by: Cursor --- .../01-primitives-methods/article.md | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/1-js/05-data-types/01-primitives-methods/article.md b/1-js/05-data-types/01-primitives-methods/article.md index 887d574aeb..56df6e7b0b 100644 --- a/1-js/05-data-types/01-primitives-methods/article.md +++ b/1-js/05-data-types/01-primitives-methods/article.md @@ -39,13 +39,8 @@ john.sayHi(); // 친구야 반갑다! 자바스크립트 창안자(creator)는 다음과 같은 모순적인 상황을 해결해야만 했었습니다. -<<<<<<< HEAD - 문자열이나 숫자와 같은 원시값을 다루어야 하는 작업이 많은데, 메서드를 사용하면 작업을 수월하게 할 수 있을 것 같다는 생각이 듭니다. - 그런데 원시값은 가능한 한 빠르고 가벼워야 합니다. -======= -- There are many things one would want to do with a primitive, like a string or a number. It would be great to access them using methods. -- Primitives must be as fast and lightweight as possible. ->>>>>>> upstream/master 조금 어색해 보이지만, 자바스크립트 창안자는 아래와 같은 방법을 사용해 해결책을 모색하였습니다. @@ -53,11 +48,7 @@ john.sayHi(); // 친구야 반갑다! 2. 문자열, 숫자, 불린, 심볼의 메서드와 프로퍼티에 접근할 수 있도록 언어 차원에서 허용합니다. 3. 이를 가능하게 하기 위해, 원시값이 메서드나 프로퍼티에 접근하려 하면 추가 기능을 제공해주는 특수한 객체, "원시 래퍼 객체(object wrapper)"를 만들어 줍니다. 이 객체는 곧 삭제됩니다. -<<<<<<< HEAD -"래퍼 객체"는 원시 타입에 따라 종류가 다양합니다. 각 래퍼 객체는 원시 자료형의 이름을 그대로 차용해, `String`,`Number`,`Boolean`, `Symbol`라고 부릅니다. 래퍼 객체 마다 제공하는 메서드 역시 다릅니다. -======= -The "object wrappers" are different for each primitive type and are called: `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. Thus, they provide different sets of methods. ->>>>>>> upstream/master +"래퍼 객체"는 원시 타입에 따라 종류가 다양합니다. 각 래퍼 객체는 원시 자료형의 이름을 그대로 차용해, `String`,`Number`,`Boolean`, `Symbol`, `BigInt` 라고 부릅니다. 래퍼 객체 마다 제공하는 메서드 역시 다릅니다. 인수로 받은 문자열의 모든 글자를 대문자로 바꿔주는 메서드 [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase)를 예로 들어보겠습니다. @@ -113,16 +104,9 @@ if (zero) { // 변수 zero는 객체이므로, 조건문이 참이 됩니다. } ``` -<<<<<<< HEAD -그런데, `new`를 붙이지 않고 `String / Number / Boolean`을 사용하는 건 괜찮습니다. `new` 없이 사용하면 상식에 맞게 인수를 원하는 형의 원시값(문자열, 숫자, 불린 값)으로 바꿔줍니다. 아주 유용하죠. +그런데, `new`를 붙이지 않고 `String/Number/Boolean`을 사용하는 건 괜찮습니다. `new` 없이 사용하면 상식에 맞게 인수를 원하는 형의 원시값(문자열, 숫자, 불린 값)으로 바꿔줍니다. 아주 유용하죠. 예시: -======= -On the other hand, using the same functions `String/Number/Boolean` without `new` is totally fine and useful thing. They convert a value to the corresponding type: to a string, a number, or a boolean (primitive). - -For example, this is entirely valid: - ->>>>>>> upstream/master ```js let num = Number("123"); // 문자열을 숫자로 바꿔줌 ``` From bf560ed66120b2f19d786924d92cff92f36f5779 Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sat, 16 May 2026 01:29:20 +0900 Subject: [PATCH 09/19] docs: translate primitives-methods task (string-new-property) to Korean Co-authored-by: Cursor --- .../01-primitives-methods/1-string-new-property/task.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md b/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md index b7f0539c59..082913c118 100644 --- a/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md +++ b/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md @@ -15,8 +15,4 @@ str.test = 5; alert(str.test); ``` -<<<<<<< HEAD 아래 코드를 실행하면, 의도한 대로 문자열(str)에 프로퍼티(test)를 추가할 수 있을까요? 만약 가능하다면 얼럿 창엔 무엇이 출력될까요? -======= -What do you think, will it work? What will be shown? ->>>>>>> upstream/master From 1301a43c385baaa763943a2583da23afc77622ed Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sat, 16 May 2026 01:29:26 +0900 Subject: [PATCH 10/19] docs: translate number article to Korean Co-authored-by: Cursor --- 1-js/05-data-types/02-number/article.md | 228 ++++-------------------- 1 file changed, 39 insertions(+), 189 deletions(-) diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md index 9e76f45893..6a3d701974 100644 --- a/1-js/05-data-types/02-number/article.md +++ b/1-js/05-data-types/02-number/article.md @@ -2,15 +2,9 @@ 모던 자바스크립트는 숫자를 나타내는 두 가지 자료형을 지원합니다. -<<<<<<< HEAD 1. 일반적인 숫자는 '배정밀도 부동소수점 숫자(double precision floating point number)'로 알려진 64비트 형식의 [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision)에 저장됩니다. 튜토리얼 전체에서 이 형식을 사용하여 숫자를 표현할 예정입니다. 2. 임의의 길이를 가진 정수는 BigInt 숫자로 나타낼 수 있습니다. 일반적인 숫자는 253이상이거나 -253이하일 수 없다는 제약 때문에 BigInt라는 새로운 자료형이 만들어졌습니다. BigInt는 아주 특별한 경우에만 사용되므로, 별도의 챕터 에서 자세한 내용을 다루겠습니다. -======= -1. Regular numbers in JavaScript are stored in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754), also known as "double precision floating point numbers". These are numbers that we're using most of the time, and we'll talk about them in this chapter. - -2. BigInt numbers represent integers of arbitrary length. They are sometimes needed because a regular integer number can't safely exceed (253-1) or be less than -(253-1), as we mentioned earlier in the chapter . As bigints are used in a few special areas, we devote them to a special chapter . ->>>>>>> upstream/master 자, 그럼 일반적인 숫자에 대해서 자세히 알아봅시다. @@ -22,28 +16,22 @@ let billion = 1000000000; ``` -<<<<<<< HEAD -그런데 이렇게 0을 많이 사용해 숫자를 표현하다 보면 잘못 입력하기 쉽기 때문에, 실제로는 이런 방법을 잘 사용하지 않습니다. 0을 많이 입력하는 게 귀찮기도 하지요. 그래서 대개는 10억(`billion`)을 나타낼 땐 `'1bn'`을 사용하고, 73억을 나타낼 땐 `'7.3bn'`을 사용합니다. 큰 숫자를 나타낼 땐 이런 방법이 주로 사용되죠. - -자바스크립트에서도 숫자 옆에 `'e'`를 붙이고 0의 개수를 그 옆에 붙여주면 숫자를 줄일 수 있습니다. -======= -We also can use underscore `_` as the separator: +숫자를 입력할 때 밑줄 _을 구분자로 사용할 수도 있습니다. ```js let billion = 1_000_000_000; -``` +```` + +여기서 밑줄 `_`은 코드를 더 읽기 쉽게 만들어주는 "[문법적 설탕(syntactic sugar)](https://en.wikipedia.org/wiki/Syntactic_sugar)" 역할을 합니다. 자바스크립트 엔진은 숫자 사이의 `_`를 단순히 무시하므로, 위에서 작성한 10억과 완전히 동일한 숫자가 됩니다. -Here the underscore `_` plays the role of the "[syntactic sugar](https://en.wikipedia.org/wiki/Syntactic_sugar)", it makes the number more readable. The JavaScript engine simply ignores `_` between digits, so it's exactly the same one billion as above. +하지만 실제로는 이렇게 `0`을 길게 나열하는 것을 피하려고 합니다. `0`을 많이 입력하는 게 귀찮기도 하니까요. 그래서 대개는 10억(billion)을 나타낼 땐 `"1bn"`을, 73억을 나타낼 땐 `"7.3bn"`을 사용하곤 합니다. 큰 숫자를 나타낼 땐 이런 방법이 주로 사용되죠. -In real life though, we try to avoid writing long sequences of zeroes. We're too lazy for that. We'll try to write something like `"1bn"` for a billion or `"7.3bn"` for 7 billion 300 million. The same is true for most large numbers. +자바스크립트에서도 숫자 옆에 `"e"`를 붙이고 `0`의 개수를 지정해 주면 숫자를 줄여서 표현할 수 있습니다. -In JavaScript, we can shorten a number by appending the letter `"e"` to it and specifying the zeroes count: ->>>>>>> upstream/master ```js run let billion = 1e9; // 10억, 1과 9개의 0 -<<<<<<< HEAD alert( 7.3e9 ); // 73억 (7,300,000,000) ``` @@ -55,25 +43,11 @@ alert( 7.3e9 ); // 73억 (7,300,000,000) ``` 이제 아주 작은 숫자인 1마이크로초(백만 분의 1초)를 표현해보겠습니다. -======= -alert( 7.3e9 ); // 7.3 billions (same as 7300000000 or 7_300_000_000) -``` - -In other words, `e` multiplies the number by `1` with the given zeroes count. - -```js -1e3 === 1 * 1000; // e3 means *1000 -1.23e6 === 1.23 * 1000000; // e6 means *1000000 -``` - -Now let's write something very small. Say, 1 microsecond (one-millionth of a second): ->>>>>>> upstream/master ```js let mсs = 0.000001; ``` -<<<<<<< HEAD 작은 숫자를 표현할 때도 큰 숫자를 표현할 때처럼 `'e'`를 사용할 수 있습니다. 0을 명시적으로 쓰고 싶지 않다면 다음과 같이 숫자를 표현할 수 있죠. ```js @@ -81,35 +55,18 @@ let ms = 1e-6; // 1에서 왼쪽으로 6번 소수점 이동 ``` `0.000001`에서 0의 개수를 세면 6이므로 `0.000001`은 당연히 `1e-6`이 되죠. -======= -Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could write the same as: - -```js -let mcs = 1e-6; // five zeroes to the left from 1 -``` - -If we count the zeroes in `0.000001`, there are 6 of them. So naturally it's `1e-6`. ->>>>>>> upstream/master 이렇게 `'e'` 우측에 음수가 있으면, 이 음수의 절댓값 만큼 10을 거듭제곱한 수로 나누는 것을 의미합니다. ```js -<<<<<<< HEAD // 10을 세 번 거듭제곱한 수로 나눔 1e-3 === 1 / 1000 // 0.001 // 10을 여섯 번 거듭제곱한 수로 나눔 1.23e-6 === 1.23 / 1000000 // 0.00000123 -======= -// -3 divides by 1 with 3 zeroes -1e-3 === 1 / 1000; // 0.001 -// -6 divides by 1 with 6 zeroes -1.23e-6 === 1.23 / 1000000; // 0.00000123 - -// an example with a bigger number -1234e-2 === 1234 / 100; // 12.34, decimal point moves 2 times ->>>>>>> upstream/master +// 조금 더 큰 숫자를 사용한 예시 +1234e-2 === 1234 / 100; // 12.34, 소수점이 두 칸 이동함 ``` ### 16진수, 2진수, 8진수 @@ -147,23 +104,13 @@ alert( num.toString(16) ); // ff alert( num.toString(2) ); // 11111111 ``` -<<<<<<< HEAD `base`는 `2`에서 `36`까지 쓸 수 있는데, 기본값은 `10`입니다. -======= -The `base` can vary from `2` to `36`. By default, it's `10`. ->>>>>>> upstream/master `base`별 유스 케이스는 다음과 같습니다. -<<<<<<< HEAD -- **base=16** -- 16진수 색, 문자 인코딩 등을 표현할 때 사용합니다. 숫자는 `0`부터 `9`, 10 이상의 수는 `A`부터 `F`를 사용하여 나타냅니다. -- **base=2** -- 비트 연산 디버깅에 주로 쓰입니다. 숫자는 `0` 또는 `1`이 될 수 있습니다. -- **base=36** -- 사용할 수 있는 `base` 중 최댓값으로, `0..9`와 `A..Z`를 사용해 숫자를 표현합니다. 알파벳 전체가 숫자를 나타내는 데 사용되죠. `36` 베이스는 url을 줄이는 것과 같이 숫자로 된 긴 식별자를 짧게 줄일 때 유용합니다. 예시를 살펴봅시다. -======= - **base=16** is used for hex colors, character encodings etc, digits can be `0..9` or `A..F`. - **base=2** is mostly for debugging bitwise operations, digits can be `0` or `1`. - **base=36** is the maximum, digits can be `0..9` or `A..Z`. The whole Latin alphabet is used to represent a number. A funny, but useful case for `36` is when we need to turn a long numeric identifier into something shorter, for example, to make a short url. Can simply represent it in the numeral system with base `36`: ->>>>>>> upstream/master ```js run alert( 123456..toString(36) ); // 2n9c @@ -172,16 +119,9 @@ The `base` can vary from `2` to `36`. By default, it's `10`. ```warn header="점 두 개와 메서드 호출" `123456..toString(36)`에 있는 점 두 개는 오타가 아닙니다. 위 예시처럼 숫자를 대상으로 메서드 `toString`을 직접 호출하고 싶다면 숫자 다음에 점 두 개 `..`를 붙여야 합니다. -<<<<<<< HEAD `123456.toString(36)`처럼 점을 한 개만 사용하면, 첫 번째 점 이후는 소수부로 인식되어 에러가 발생할 수 있습니다. 점을 하나 더 추가하면 자바스크립트는 소수부가 없다고 판단하고 함수를 호출합니다. `(123456).toString(36)`도 가능합니다. -======= -If we placed a single dot: `123456.toString(36)`, then there would be an error, because JavaScript syntax implies the decimal part after the first dot. And if we place one more dot, then JavaScript knows that the decimal part is empty and now uses the method. - -Also could write `(123456).toString(36)`. - ->>>>>>> upstream/master ``` ## 어림수 구하기 @@ -197,11 +137,7 @@ Also could write `(123456).toString(36)`. : 소수점 첫째 자리에서 올림. `3.1`은 `4`, `-1.1`은 `-1`이 됩니다. `Math.round` -<<<<<<< HEAD -: 소수점 첫째 자리에서 반올림. `3.1`은 `3`, `3.6`은 `4`, `-1.1`은 `-1`이 됩니다. -======= -: Rounds to the nearest integer: `3.1` becomes `3`, `3.6` becomes `4`. In the middle cases `3.5` rounds up to `4`, and `-3.5` rounds up to `-3`. ->>>>>>> upstream/master +: 가장 가까운 정수로 반올림합니다. `3.1`은 `3`, `3.6`은 `4`가 됩니다. 중간값의 경우 `3.5`는 `4`로 올림 되고, `-3.5`는 `-3`으로 올림 됩니다. `Math.trunc` (Internet Explorer에서는 지원하지 않음) : 소수부를 무시. `3.1`은 `3`이 되고 `-1.1`은 `-1`이 됩니다. @@ -226,11 +162,7 @@ Also could write `(123456).toString(36)`. 1. 곱하기와 나누기 -<<<<<<< HEAD 소수점 두 번째 자리 숫자까지만 남기고 싶은 경우, 숫자에 `100` 또는 `100`보다 큰 `10`의 거듭제곱 수를 곱한 후, 원하는 어림수 내장 함수를 호출하고 처음 곱한 수를 다시 나누면 됩니다. -======= - For example, to round the number to the 2nd digit after the decimal, we can multiply the number by `100`, call the rounding function and then divide it back. ->>>>>>> upstream/master ```js run let num = 1.23456; @@ -251,34 +183,20 @@ Also could write `(123456).toString(36)`. alert( num.toFixed(1) ); // "12.4" ``` -<<<<<<< HEAD `toFixed`를 사용할 때 주의할 점은 이 메서드의 반환 값이 문자열이라는 것입니다. 소수부의 길이가 인수보다 작으면 끝에 0이 추가됩니다. -======= - Please note that the result of `toFixed` is a string. If the decimal part is shorter than required, zeroes are appended to the end: ->>>>>>> upstream/master ```js run let num = 12.34; alert( num.toFixed(5) ); // "12.34000", 소수부의 길이를 5로 만들기 위해 0이 추가되었습니다. ``` -<<<<<<< HEAD 참고로, `+num.toFixed(5)`처럼 단항 덧셈 연산자를 앞에 붙이거나 `Number()`를 호출하면 문자형의 숫자를 숫자형으로 변환할 수 있습니다. -======= - We can convert it to a number using the unary plus or a `Number()` call, e.g. write `+num.toFixed(5)`. ->>>>>>> upstream/master ## 부정확한 계산 -<<<<<<< HEAD 숫자는 내부적으로 64비트 형식 [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision)으로 표현되기 때문에 숫자를 저장하려면 정확히 64비트가 필요합니다. 64비트 중 52비트는 숫자를 저장하는 데 사용되고, 11비트는 소수점 위치를(정수는 0), 1비트는 부호를 저장하는 데 사용됩니다. -그런데 숫자가 너무 커지면 64비트 공간이 넘쳐서 Infinity로 처리됩니다. -======= -Internally, a number is represented in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754), so there are exactly 64 bits to store a number: 52 of them are used to store the digits, 11 of them store the position of the decimal point, and 1 bit is for the sign. - -If a number is really huge, it may overflow the 64-bit storage and become a special numeric value `Infinity`: ->>>>>>> upstream/master +그런데 숫자가 너무 커지면 64비트 공간이 넘쳐서 `Infinity`로 처리됩니다. ```js run alert( 1e500 ); // Infinity @@ -286,11 +204,7 @@ alert( 1e500 ); // Infinity 원인을 이해하려면 집중이 필요하긴 하지만, 꽤 자주 발생하는 현상인 정밀도 손실(loss of precision)도 있습니다. -<<<<<<< HEAD -예시를 살펴봅시다. -======= -Consider this (falsy!) equality test: ->>>>>>> upstream/master +다음의 (falsy!) 동등 비교를 살펴봅시다. ```js run alert( 0.1 + 0.2 == 0.3 ); // *!*false*/!* @@ -304,27 +218,20 @@ alert( 0.1 + 0.2 == 0.3 ); // *!*false*/!* alert( 0.1 + 0.2 ); // 0.30000000000000004 ``` -<<<<<<< HEAD 부정확한 비교 연산이 만들어내는 결과는 여기서 그치지 않습니다. 인터넷 쇼핑몰 사이트를 운영하고 있다고 가정해 봅시다. 사용자가 `$0.10`와 `$0.20` 짜리 물품을 장바구니에 넣었다고 상상해 보죠. 주문 총액이 `$0.30000000000000004`인 것을 보고 놀라지 않을 사용자는 없을 겁니다. -======= -Ouch! Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into their cart. The order total will be `$0.30000000000000004`. That would surprise anyone. ->>>>>>> upstream/master 왜 이런 일이 발생하는 걸까요? 숫자는 0과 1로 이루어진 이진수로 변환되어 연속된 메모리 공간에 저장됩니다. 그런데 10진법을 사용하면 쉽게 표현할 수 있는 `0.1`, `0.2` 같은 분수는 이진법으로 표현하면 무한 소수가 됩니다. -<<<<<<< HEAD -`0.1`은 1을 10으로 나눈 수인 `1/10`입니다. 10진법을 사용하면 이러한 숫자를 쉽게 표현할 수 있죠. `1/10`과 `1/3`을 비교해봅시다. `1/3`은 무한 소수 `0.33333(3)`이 됩니다. -======= + ```js run alert(0.1.toString(2)); // 0.0001100110011001100110011001100110011001100110011001101 alert(0.2.toString(2)); // 0.001100110011001100110011001100110011001100110011001101 alert((0.1 + 0.2).toString(2)); // 0.0100110011001100110011001100110011001100110011001101 -``` +```` -What is `0.1`? It is one divided by ten `1/10`, one-tenth. In the decimal numeral system, such numbers are easily representable. Compare it to one-third: `1/3`. It becomes an endless fraction `0.33333(3)`. ->>>>>>> upstream/master +`0.1`은 1을 10으로 나눈 수인 `1/10`입니다. 10진법을 사용하면 이러한 숫자를 쉽게 표현할 수 있죠. `1/10`과 `1/3`을 비교해봅시다. `1/3`은 무한 소수 `0.33333(3)`이 됩니다. 이렇게 `10`의 거듭제곱으로 나눈 값은 10진법에서 잘 동작하지만 `3`으로 나누게 되면 10진법에서 제대로 동작하지 않습니다. 같은 이유로 2진법 체계에서 `2`의 거듭제곱으로 나눈 값은 잘 동작하지만 `1/10`같이 `2`의 거듭제곱이 아닌 값으로 나누게 되면 무한 소수가 되어버립니다. @@ -344,11 +251,7 @@ alert( 0.1.toFixed(20) ); // 0.10000000000000000555 ```smart header="자바스크립트뿐만이 아닙니다." 다른 언어에서도 같은 이슈가 있습니다. -<<<<<<< HEAD 자바스크립트와 동일한 숫자 형식을 사용하기 때문에 PHP, Java, C, Perl, Ruby에서도 똑같은 결과를 얻습니다. -======= -PHP, Java, C, Perl, and Ruby give exactly the same result, because they are based on the same numeric format. ->>>>>>> upstream/master ``` 문제를 해결하는 방법은 없을까요? 물론 있습니다. 가장 신뢰할만한 방법은 [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed)메서드를 사용해 어림수를 만드는 것입니다. @@ -372,11 +275,7 @@ alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3 alert( (0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001 ``` -<<<<<<< HEAD 이렇게 10의 거듭제곱을 곱하고 다시 동일한 숫자로 나누는 전략은 오류를 줄여주긴 하지만 완전히 없애지는 못합니다. -======= -So, the multiply/divide approach reduces the error, but doesn't remove it totally. ->>>>>>> upstream/master 구현을 하다 보면 무한 소수가 나오는 경우를 완전히 차단해야 하는 경우가 생기곤 합니다. 달러가 아닌 센트 단위로 물품 가격을 저장하는 쇼핑몰을 담당하고 있는데, 행사 때문에 가격을 30% 할인해야 하는 경우가 그렇죠. 무한소수를 방지하는 완벽한 방법은 사실 없습니다. 필요할 때마다 '꼬리'를 잘라 어림수를 만드는 방법뿐이죠. @@ -398,11 +297,7 @@ alert( 9999999999999999 ); // 10000000000000000이 출력됩니다. 자바스크립트에선 숫자의 부호가 단일 비트에 저장되는데 0을 포함한 모든 숫자에 부호를 설정할 수도, 설정하지 않을 수도 있기 때문입니다. -<<<<<<< HEAD -대부분의 연산은 `0`과 `-0`을 동일하게 취급하기 때문에 두 0의 차이는 두드러지지 않는 편입니다. -======= -In most cases, the distinction is unnoticeable, because operators are suited to treat them as the same. ->>>>>>> upstream/master +대부분의 경우, 연산자들이 이 둘을 동일하게 취급하도록 되어 있기 때문에 그 차이는 눈에 띄지 않는 편입니다. ``` ## isNaN과 isFinite @@ -422,11 +317,7 @@ In most cases, the distinction is unnoticeable, because operators are suited to alert( isNaN("str") ); // true ``` -<<<<<<< HEAD 그런데 굳이 이 함수가 필요할까요? "`=== NaN` 비교를 하면 되지 않을까?"라는 생각이 들 수 있습니다. 안타깝게도 대답은 '필요하다'입니다. `NaN`은 `NaN` 자기 자신을 포함하여 그 어떤 값과도 같지 않다는 점에서 독특합니다. -======= - But do we need this function? Can't we just use the comparison `=== NaN`? Unfortunately not. The value `NaN` is unique in that it does not equal anything, including itself: ->>>>>>> upstream/master ```js run alert( NaN === NaN ); // false @@ -450,61 +341,46 @@ let num = +prompt("숫자를 입력하세요.", ''); alert( isFinite(num) ); ``` -<<<<<<< HEAD 빈 문자열이나 공백만 있는 문자열은 `isFinite`를 포함한 모든 숫자 관련 내장 함수에서 `0`으로 취급된다는 점에 유의하시기 바랍니다. -```smart header="`Object.is`와 비교하기" - -[`Object.is`](mdn:js/Object/is)는 `===`처럼 값을 비교할 때 사용되는 특별한 내장 메서드인데, 아래와 같은 두 가지 에지 케이스에선 `===`보다 좀 더 신뢰할만한 결과를 보여줍니다. - -1. `NaN`을 대상으로 비교할 때: `Object.is(NaN, NaN) === true`임. -2. `0`과 `-0`이 다르게 취급되어야 할 때: `Object.is(0, -0) === false`임. 숫자를 나타내는 비트가 모두 0이더라도 부호를 나타내는 비트는 다르므로 `0`과 `-0`은 사실 다른 값이긴 합니다. -======= -Please note that an empty or a space-only string is treated as `0` in all numeric functions including `isFinite`. - -````smart header="`Number.isNaN` and `Number.isFinite`" -[Number.isNaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) and [Number.isFinite](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) methods are the more "strict" versions of `isNaN` and `isFinite` functions. They do not autoconvert their argument into a number, but check if it belongs to the `number` type instead. +````smart header="`Number.isNaN`과 `Number.isFinite`" +[Number.isNaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN)과 [Number.isFinite](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) 메서드는 `isNaN`과 `isFinite` 함수의 좀 더 "엄격한" 버전입니다. 이 메서드들은 인수를 숫자로 자동 변환하지 않고, 대신 인수가 `number` 자료형에 속하는지 먼저 확인합니다. -- `Number.isNaN(value)` returns `true` if the argument belongs to the `number` type and it is `NaN`. In any other case, it returns `false`. +- `Number.isNaN(value)`는 인수가 `number` 자료형이면서 값이 `NaN`일 때만 `true`를 반환합니다. 그 외의 모든 경우에는 `false`를 반환합니다. ```js run alert( Number.isNaN(NaN) ); // true alert( Number.isNaN("str" / 2) ); // true - // Note the difference: - alert( Number.isNaN("str") ); // false, because "str" belongs to the string type, not the number type - alert( isNaN("str") ); // true, because isNaN converts string "str" into a number and gets NaN as a result of this conversion + // 차이점에 유의하세요: + alert( Number.isNaN("str") ); // false, "str"은 숫자형이 아닌 문자열형이기 때문입니다. + alert( isNaN("str") ); // true, isNaN은 문자열 "str"을 숫자로 변환하고, 그 결과가 NaN이 되기 때문입니다. ``` -- `Number.isFinite(value)` returns `true` if the argument belongs to the `number` type and it is not `NaN/Infinity/-Infinity`. In any other case, it returns `false`. +- `Number.isFinite(value)`는 인수가 `number` 자료형이면서 `NaN/Infinity/-Infinity`가 아닐 때만 `true`를 반환합니다. 그 외의 모든 경우에는 `false`를 반환합니다. ```js run alert( Number.isFinite(123) ); // true alert( Number.isFinite(Infinity) ); // false alert( Number.isFinite(2 / 0) ); // false - // Note the difference: - alert( Number.isFinite("123") ); // false, because "123" belongs to the string type, not the number type - alert( isFinite("123") ); // true, because isFinite converts string "123" into a number 123 + // 차이점에 유의하세요: + alert( Number.isFinite("123") ); // false, "123"은 숫자형이 아닌 문자열형이기 때문입니다. + alert( isFinite("123") ); // true, isFinite는 문자열 "123"을 숫자 123으로 변환하기 때문입니다. ``` -In a way, `Number.isNaN` and `Number.isFinite` are simpler and more straightforward than `isNaN` and `isFinite` functions. In practice though, `isNaN` and `isFinite` are mostly used, as they're shorter to write. +어떤 면에서 `Number.isNaN`과 `Number.isFinite`는 `isNaN`과 `isFinite` 함수보다 더 단순하고 직관적입니다. 하지만 실무에서는 코드가 더 짧은 `isNaN`과 `isFinite`가 주로 사용됩니다. ```` -```smart header="Comparison with `Object.is`" -There is a special built-in method `Object.is` that compares values like `===`, but is more reliable for two edge cases: +```smart header="`Object.is`와 비교하기" +[`Object.is`](mdn:js/Object/is)는 `===`처럼 값을 비교할 때 사용되는 특별한 내장 메서드인데, 아래와 같은 두 가지 에지 케이스에선 `===`보다 좀 더 신뢰할만한 결과를 보여줍니다. -1. It works with `NaN`: `Object.is(NaN, NaN) === true`, that's a good thing. -2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, technically that's correct because internally the number has a sign bit that may be different even if all other bits are zeroes. ->>>>>>> upstream/master +1. `NaN`을 대상으로 비교할 때: `Object.is(NaN, NaN) === true`임. +2. `0`과 `-0`이 다르게 취급되어야 할 때: `Object.is(0, -0) === false`임. 숫자를 나타내는 비트가 모두 0이더라도 부호를 나타내는 비트는 다르므로 `0`과 `-0`은 사실 다른 값이긴 합니다. 이 두 에지 케이스를 제외하곤, `Object.is(a, b)`와 `a === b`의 결과는 같습니다. -<<<<<<< HEAD 이런 식의 비교는 자바스크립트 명세서에서 종종 찾아볼 수 있습니다. 내부 알고리즘에서 두 값을 비교해야 하는데, 비교 결과가 정확해야 하는 경우 `Object.is`를 사용하죠. `Object.is`에서 사용되는 비교방식은 명세서에서 [SameValue](https://tc39.github.io/ecma262/#sec-samevalue)라고 불립니다. -======= -We mention `Object.is` here, because it's often used in JavaScript specification. When an internal algorithm needs to compare two values for being exactly the same, it uses `Object.is` (internally called [SameValue](https://tc39.github.io/ecma262/#sec-samevalue)). ->>>>>>> upstream/master ``` @@ -518,11 +394,7 @@ alert( +"100px" ); // NaN 엄격한 규칙이 적용되지 않는 유일한 예외는 문자열의 처음 또는 끝에 공백이 있어서 공백을 무시할 때입니다. -<<<<<<< HEAD 그런데 실무에선 CSS 등에서 `'100px'`, `'12pt'`와 같이 숫자와 단위를 함께 쓰는 경우가 흔합니다. 대다수 국가에서 `'19€'`처럼 금액 뒤에 통화 기호를 붙여 표시하기도 하죠. 숫자만 추출하는 방법이 필요해 보이네요. -======= -But in real life, we often have values in units, like `"100px"` or `"12pt"` in CSS. Also in many countries, the currency symbol goes after the amount, so we have `"19€"` and would like to extract a numeric value out of that. ->>>>>>> upstream/master 내장 함수 `parseInt`와 `parseFloat`는 이런 경우를 위해 만들어졌습니다. @@ -560,11 +432,7 @@ alert( parseInt('2n9c', 36) ); // 123456 몇 가지 예시를 살펴봅시다. `Math.random()` -<<<<<<< HEAD : 0과 1 사이의 난수를 반환합니다(1은 제외). -======= -: Returns a random number from 0 to 1 (not including 1). ->>>>>>> upstream/master ```js run alert( Math.random() ); // 0.1234567894322 @@ -572,13 +440,8 @@ alert( parseInt('2n9c', 36) ); // 123456 alert( Math.random() ); // ... (무작위 수) ``` -<<<<<<< HEAD `Math.max(a, b, c...)` / `Math.min(a, b, c...)` : 인수 중 최대/최솟값을 반환합니다. -======= -`Math.max(a, b, c...)` and `Math.min(a, b, c...)` -: Returns the greatest and smallest from the arbitrary number of arguments. ->>>>>>> upstream/master ```js run alert( Math.max(3, 5, -10, 0, 1) ); // 5 @@ -586,21 +449,13 @@ alert( parseInt('2n9c', 36) ); // 123456 ``` `Math.pow(n, power)` -<<<<<<< HEAD : `n`을 power번 거듭제곱한 값을 반환합니다. -======= -: Returns `n` raised to the given power. ->>>>>>> upstream/master ```js run alert( Math.pow(2, 10) ); // 2의 10제곱 = 1024 ``` -<<<<<<< HEAD 이 외에도 삼각법을 포함한 다양한 함수와 상수가 `Math`에 있습니다. 자세한 내용은 [MDN 문서](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math)에서 읽어보시기 바랍니다. -======= -There are more functions and constants in `Math` object, including trigonometry, which you can find in the [docs for the Math object](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math). ->>>>>>> upstream/master ## 요약 @@ -615,18 +470,17 @@ There are more functions and constants in `Math` object, including trigonometry, - `parseInt(str, base)`를 사용하면 `str`을 `base`진수로 바꿔줍니다(단, `2 ≤ base ≤ 36`). - `num.toString(base)`는 숫자를 `base`진수로 바꾸고, 이를 문자열 형태로 반환합니다. -<<<<<<< HEAD -`12pt`나 `100px`과 같은 값을 숫자로 변환하는 것도 가능합니다. -======= -For regular number tests: +일반적인 숫자 검사의 경우: + +- `isNaN(value)`은 인수를 숫자로 변환한 다음 `NaN`인지 검사합니다. + +- `Number.isNaN(value)`은 인수가 숫자형인지 확인하고, 맞다면 `NaN`인지 검사합니다. -- `isNaN(value)` converts its argument to a number and then tests it for being `NaN` -- `Number.isNaN(value)` checks whether its argument belongs to the `number` type, and if so, tests it for being `NaN` -- `isFinite(value)` converts its argument to a number and then tests it for not being `NaN/Infinity/-Infinity` -- `Number.isFinite(value)` checks whether its argument belongs to the `number` type, and if so, tests it for not being `NaN/Infinity/-Infinity` +- `isFinite(value)`은 인수를 숫자로 변환한 다음 `NaN/Infinity/-Infinity`가 아닌지 검사합니다. -For converting values like `12pt` and `100px` to a number: ->>>>>>> upstream/master +- `Number.isFinite(value)`은 인수가 숫자형인지 확인하고, 맞다면 `NaN/Infinity/-Infinity`가 아닌지 검사합니다. + +`12pt`나 `100px`과 같은 값을 숫자로 변환하는 것도 가능합니다. - `parseInt/parseFloat`를 사용하면 문자열에서 숫자만 읽고, 읽은 숫자를 에러가 발생하기 전에 반환해주는 '약한' 형 변환을 사용할 수 있습니다. @@ -637,8 +491,4 @@ For converting values like `12pt` and `100px` to a number: 이 외에도 다양한 수학 함수가 있습니다. -<<<<<<< HEAD - 수학 연산이 필요할 때 [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) 객체를 찾아보세요. 작은 객체이지만 기본적인 연산은 대부분 다룰 수 있습니다. -======= -- See the [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) object when you need them. The library is very small but can cover basic needs. ->>>>>>> upstream/master From c8588291321d9daae56312d87820407a23e83ee6 Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sat, 16 May 2026 01:29:33 +0900 Subject: [PATCH 11/19] docs: translate number solution (why-rounded-down) to Korean Co-authored-by: Cursor --- 1-js/05-data-types/02-number/2-why-rounded-down/solution.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md index 73a98b976b..4473c71b9e 100644 --- a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md +++ b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md @@ -28,10 +28,6 @@ alert( (6.35 * 10).toFixed(20) ); // 63.50000000000000000000 ```js run -<<<<<<< HEAD alert( Math.round(6.35 * 10) / 10); // 6.35 -> 63.5 -> 64(반올림됨) -> 6.4 -======= -alert( Math.round(6.35 * 10) / 10 ); // 6.35 -> 63.5 -> 64(rounded) -> 6.4 ->>>>>>> upstream/master ``` From df5934f1017aa080e33b674819b3d78a9a377bbe Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sun, 17 May 2026 01:44:02 +0900 Subject: [PATCH 12/19] =?UTF-8?q?docs=20:=20=EC=8B=AC=EB=B3=BC=ED=98=95=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=EB=90=9C=20=EB=AC=B8=EC=9E=A5=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1-js/04-object-basics/08-symbol/article.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/1-js/04-object-basics/08-symbol/article.md b/1-js/04-object-basics/08-symbol/article.md index f9941efda1..3f53166c8a 100644 --- a/1-js/04-object-basics/08-symbol/article.md +++ b/1-js/04-object-basics/08-symbol/article.md @@ -3,8 +3,6 @@ 자바스크립트는 객체 프로퍼티 키로 오직 문자형과 심볼형만을 허용합니다. 숫자형, 불린형 모두 불가능하고 오직 문자형과 심볼형만 가능하죠. -지금까지는 프로퍼티 키가 문자형인 경우만 살펴보았습니다. 이번 챕터에선 프로퍼티 키로 심볼값을 사용해 보면서, 심볼형 키를 사용할 때의 이점에 대해 살펴보도록 하겠습니다. - - 문자형 또는 - 심볼형 From 641e16337410f2e0f73d5c493ebe55a0d1d8a60c Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sun, 17 May 2026 02:05:03 +0900 Subject: [PATCH 13/19] =?UTF-8?q?docs=20:=20user.adress=20=EB=B0=B1?= =?UTF-8?q?=ED=8B=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1-js/04-object-basics/07-optional-chaining/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/04-object-basics/07-optional-chaining/article.md b/1-js/04-object-basics/07-optional-chaining/article.md index e8d59f10ca..b71de2f4d1 100644 --- a/1-js/04-object-basics/07-optional-chaining/article.md +++ b/1-js/04-object-basics/07-optional-chaining/article.md @@ -40,7 +40,7 @@ let user = {}; alert(user.address ? user.address.street : undefined); ``` -에러 없이 잘 동작하네요. 하지만 코드가 꽤 볼품없습니다. 보시다시피 "user.address"가 코드에 두 번이나 등장합니다. +에러 없이 잘 동작하네요. 하지만 코드가 꽤 볼품없습니다. 보시다시피 `"user.address"`가 코드에 두 번이나 등장합니다. `document.querySelector`를 사용한 예시는 다음과 같은 모습일 것입니다. From e6d3b963b4ecee240bc286d022904ee142d7ec57 Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sun, 17 May 2026 02:06:02 +0900 Subject: [PATCH 14/19] =?UTF-8?q?docs=20:=20*=20->=20-=20=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1-js/04-object-basics/07-optional-chaining/article.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/04-object-basics/07-optional-chaining/article.md b/1-js/04-object-basics/07-optional-chaining/article.md index b71de2f4d1..8a7315a64c 100644 --- a/1-js/04-object-basics/07-optional-chaining/article.md +++ b/1-js/04-object-basics/07-optional-chaining/article.md @@ -88,9 +88,9 @@ alert( user && user.address && user.address.street ); // undefined, 에러가 즉, `value?.prop`은 다음과 같이 평가됩니다. -* `value`가 존재하면 `value.prop`처럼 동작합니다. +- `value`가 존재하면 `value.prop`처럼 동작합니다. -* 그렇지 않은 경우(`value`가 `undefined`나 `null`일 때)에는 `undefined`를 반환합니다. +- 그렇지 않은 경우(`value`가 `undefined`나 `null`일 때)에는 `undefined`를 반환합니다. 이제 `?.`을 사용해 `user.address.street`에 안전하게 접근해 봅시다. From 68192ef75bb2072de4e2a672317ff73a14076fff Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sun, 17 May 2026 14:52:38 +0900 Subject: [PATCH 15/19] =?UTF-8?q?docs=20:=20=EC=82=AD=EC=A0=9C=EB=90=9C=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1-js/04-object-basics/07-optional-chaining/article.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/1-js/04-object-basics/07-optional-chaining/article.md b/1-js/04-object-basics/07-optional-chaining/article.md index 8a7315a64c..19589a4960 100644 --- a/1-js/04-object-basics/07-optional-chaining/article.md +++ b/1-js/04-object-basics/07-optional-chaining/article.md @@ -127,6 +127,8 @@ alert( user?.address.street ); // undefined `user`가 `null`이나 `undefined`가 아니고 실제 값이 존재하는 경우엔 반드시 `user.address` 프로퍼티는 있어야 합니다. 그렇지 않으면 `user?.address.street`의 두 번째 점 연산자에서 에러가 발생합니다. +예를 들어, `user?.address.street.name`에서 `?.`은 `user`가 `null`이나 `undefined`가 되는 것을 안전하게 허용하지만(이 경우 `undefined`를 반환합니다), 이는 오직 `user`에만 적용됩니다. 그 이후에 이어지는 프로퍼티들은 일반적인 방식으로 접근됩니다. 만약 뒤이어 오는 프로퍼티들 중 일부도 선택적인(optional) 값으로 다루고 싶다면, `.`을 `?.`로 더 교체해야 합니다. + ```warn header="옵셔널 체이닝을 남용하지 마세요." `?.`는 존재하지 않아도 괜찮은 대상에만 사용해야 합니다. From 1d6e7c094cedab4133118f25d89f0cad7eed4139 Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sun, 17 May 2026 14:58:51 +0900 Subject: [PATCH 16/19] =?UTF-8?q?docs=20:=20=EC=A4=91=EB=B3=B5=20=EC=84=A4?= =?UTF-8?q?=EB=AA=85=20=EB=B6=80=EB=B6=84=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1-js/04-object-basics/09-object-toprimitive/article.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/1-js/04-object-basics/09-object-toprimitive/article.md b/1-js/04-object-basics/09-object-toprimitive/article.md index 49970a491a..cc38c235d4 100644 --- a/1-js/04-object-basics/09-object-toprimitive/article.md +++ b/1-js/04-object-basics/09-object-toprimitive/article.md @@ -3,8 +3,6 @@ `obj1 + obj2` 처럼 객체끼리 더하는 연산을 하거나, `obj1 - obj2` 처럼 객체끼리 빼는 연산을 하면 어떤 일이 일어날까요? `alert(obj)`로 객체를 출력할 때는 무슨 일이 발생할까요? -이 모든 경우에 자동 형 변환이 일어납니다. 객체는 원시값으로 변환되고, 그 후 의도한 연산이 수행됩니다. - Ruby나 C++ 같은 다른 프로그래밍 언어와 달리, 덧셈(이나 다른 연산)을 처리하기 위한 특별한 객체 메서드를 구현할 수 없죠. 객체에 이런 연산을 수행하면 객체는 원시값으로 자동 변환되고, 이후 이 원시값들을 대상으로 연산이 수행되어 최종적으로 원시값이 반환됩니다. From 0989689ebfe26460d312a74c8c3b80f1e60177f9 Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sun, 17 May 2026 17:58:36 +0900 Subject: [PATCH 17/19] =?UTF-8?q?docs=20:=20=EC=B6=94=EA=B0=80=20=EC=84=A4?= =?UTF-8?q?=EB=AA=85=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1-js/04-object-basics/04-object-methods/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md index fb41d92371..91a67b689c 100644 --- a/1-js/04-object-basics/04-object-methods/article.md +++ b/1-js/04-object-basics/04-object-methods/article.md @@ -90,7 +90,7 @@ user = { 위처럼 `function`을 생략해도 메서드를 정의할 수 있습니다. -일반적인 방법과 단축 구문을 사용한 방법이 완전히 동일하진 않습니다. 객체 상속과 관련된 미묘한 차이가 존재하는데 지금으로선 이 차이가 중요하지 않기 때문에 넘어가도록 하겠습니다. +일반적인 방법과 단축 구문을 사용한 방법이 완전히 동일하진 않습니다. 객체 상속과 관련된 미묘한 차이가 존재하는데 지금으로선 이 차이가 중요하지 않기 때문에 넘어가도록 하겠습니다. 대부분의 경우에는 더 짧은 단축 구문이 선호됩니다. ## 메서드와 this From 48d3760db1bfb4c0b6a94701a78832aa2011c816 Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sun, 17 May 2026 18:02:37 +0900 Subject: [PATCH 18/19] =?UTF-8?q?docs=20:=20=EC=97=90=EB=9F=AC=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=A7=88?= =?UTF-8?q?=EC=BB=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1-js/04-object-basics/04-object-methods/article.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md index 91a67b689c..5258716182 100644 --- a/1-js/04-object-basics/04-object-methods/article.md +++ b/1-js/04-object-basics/04-object-methods/article.md @@ -159,8 +159,9 @@ let user = { let admin = user; user = null; // user를 null로 덮어씁니다. - -admin.sayHi(); // sayHi()가 엉뚱한 객체를 참고하면서 에러가 발생했습니다. +*!* +admin.sayHi(); // TypeError: Cannot read property 'name' of null +*/!* ``` `alert` 함수가 `user.name` 대신 `this.name`을 인수로 받았다면 에러가 발생하지 않았을 겁니다. From 90df2b8792427b198cc5531ba5aa84057f2ff540 Mon Sep 17 00:00:00 2001 From: zerohyun00 Date: Sun, 17 May 2026 18:06:54 +0900 Subject: [PATCH 19/19] =?UTF-8?q?docs=20:=20--=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9E=90=EC=97=B0=EC=8A=A4=EB=9F=BD=EA=B2=8C=20?= =?UTF-8?q?=EB=B2=88=EC=97=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../06-constructor-new/2-calculator-constructor/task.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md index 0529b5f49a..2b536d1ced 100644 --- a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md +++ b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md @@ -6,9 +6,9 @@ importance: 5 아래와 같은 세 개의 메서드를 가진 생성자 함수, `Calculator`를 만들어보세요. -- `read()` -- `prompt` 함수를 이용해 사용자로부터 값 두 개를 받고, 이를 객체 프로퍼티에 저장합니다. -- `sum()` -- 프로퍼티에 저장된 값 두 개를 더한 후 반환합니다. -- `mul()` -- 프로퍼티에 저장된 값 두 개를 곱한 후 반환합니다. +- `read()` 사용자로부터 값 두 개를 받고, 이를 객체 프로퍼티에 저장합니다. +- `sum()` 프로퍼티에 저장된 값 두 개를 더한 후 반환합니다. +- `mul()` 프로퍼티에 저장된 값 두 개를 곱한 후 반환합니다. 예시: