SyntaxError: missing name after . operator - JavaScript

SyntaxError: missing name after . operator
==========================================

메시지
---
```

    SyntaxError: missing name after . operator
```

에러 타입
-----

`SyntaxError`무엇이 잘 못 되었을까?
-------------

점 연산자 (`.`)는 프로퍼티 접근을 위해 사용합니다. 접근해야 하는 프로퍼티 명은 제대로 명시 해야 합니다. 연산 프로퍼티에 접근하려면, 점 연산자를 사용하지 않고 대괄호를 사용하는 것으로 프로퍼티 접근 방식을 바꿔야 합니다. 이런 방식들이 표현식의 계산을 수행시켜줄 것입니다. 아마 당신은 연결을 하려고 했을 것입니다. 이 경우에는 더하기 연산자(`+`)가 필요합니다. 아래의 예제를 봐주세요.

예제
--

### 프로퍼티 접근

JavaScript 프로퍼티 접근자는 점(.) 또는 대괄호(`[]`) 중 하나만 사용한다. 대괄호는 연산 프로퍼티에 접근을 허용합니다.

```js
var obj = { foo: { bar: "baz", bar2: "baz2" } };
var i = 2;

obj.[foo].[bar]
// SyntaxError: missing name after . operator

obj.foo."bar"+i;
// SyntaxError: missing name after . operator
```

이 코드를 고치려면, 오브젝트에 이런 식으로 접근해야 합니다.:

```js
obj.foo.bar; // "baz"
// 또는 대신에
obj["foo"]["bar"]; // "baz"

// 연산 프로퍼티는 대괄호가 필요합니다.
obj.foo["bar" + i]; // "baz2"
```

### 프로퍼티 접근 vs. 연결

다른 프로그램 언어를 사용하다 왔다면 ( PHP 같은), 점 연산자(`.`)와 연결 연산자(`+`)를 혼동해서 쓰기가 더 쉬울 것입니다.

```js
console.log("Hello" . "world");

// SyntaxError: missing name after . operator
```

대신에 결합을 위해서는 더하기 표식을 사용해야 합니다.:

```js
console.log("Hello" + "World");
```

참조
--

* Property accessors


SyntaxError: Unexpected token - JavaScript

SyntaxError: Unexpected token
=============================

메시지
---
```

    SyntaxError: expected expression, got "x"
    SyntaxError: expected property name, got "x"
    SyntaxError: expected target, got "x"
    SyntaxError: expected rest argument name, got "x"
    SyntaxError: expected closing parenthesis, got "x"
    SyntaxError: expected '=>' after argument list, got "x"
```

에러 타입
-----

`SyntaxError`무엇이 잘못되었나요?
-----------

특정 언어 구조를 예상했지만 무언가 다른 것이 있었습니다. 아마도, 간단한 오타일 것입니다.

예제
--

### 예상하지 못한 표현식

예를 들어, 함수를 호출할 때, 인수에서 마지막 부분에 콤마는 허용되지 않습니다. JavaScript는 계속해서 다른 인자가 있을 것이라고 기대하기 때문입니다.

```js
Math.max(2, 42,);
// SyntaxError: expected expression, got ')'
```

콤마를 생략하거나 다른 인수를 추가해 수정할 수 있습니다.

```js
Math.max(2, 42);
Math.max(2, 42, 13 + 37);
```

참조
--

* `Math.max()`


ReferenceError: can't access lexical declaration`X' before initialization - JavaScript

ReferenceError: can't access lexical declaration`X' before initialization
=========================================================================

Message
-------
```

  ReferenceError: can't access lexical declaration `X' before initialization (Firefox)
  ReferenceError: 'x' is not defined (Chrome)
```

Error type
----------

`ReferenceError`무엇이 잘못 되었을까요?
-------------

변수가 초기화 되기 전에 엑세스가 되어버립니다. 이 문제는 let 또는 const 선언이 정의 되기 전에 엑세스되는 모든 block 문에서 발생합니다.

Examples
--------

### 잘못된 경우

이 경우에 변수 "foo"는 `let` 을 사용하여 block 문에서 다시 선언됩니다.

```js
function test() {
  let foo = 33;
  if (true) {
    let foo = foo + 55;
    // ReferenceError: can't access lexical
    // declaration `foo' before initialization
  }
}
test();
```

### 올바른 경우

if 문에서 "foo"를 변경하려면 재 선언을 발생시키는 `let` 을 제거해야합니다.

```js
function test() {
  let foo = 33;
  if (true) {
    foo = foo + 55;
  }
}
test();
```

그밖에 볼 것
-------

* Temporal Dead Zone and errors with let


SyntaxError: missing ) after argument list - JavaScript

SyntaxError: missing ) after argument list
==========================================

Message
-------
```

    SyntaxError: missing ) after argument list
```

Error type
----------

`SyntaxError`.

What went wrong?
----------------

function을 호출하는 방식에 에러가 있는 것입니다. 맞춤법, 연산자 누락 또는 이스케이프 처리를 하지 않는 문자열과 같은 것으로 발생될 수 있습니다.

Examples
--------

문자열을 합치는 "+" 연산자가 없기 때문에, Javascript는 `log` function에 대한 인수를 `"PI: "`로 인식을 합니다. 이 경우, 닫침 괄호가 누락된 것으로 인식을 합니다.

```js
console.log('PI: ' Math.PI);
// SyntaxError: missing ) after argument list
```

You can correct the `log` call by adding the "`+`" operator:

```js
console.log("PI: " + Math.PI);
// "PI: 3.141592653589793"
```

See also
--------

* Functions


SyntaxError: illegal character - JavaScript

SyntaxError: illegal character
==============================

메세지
---
```

  SyntaxError: Invalid character (Edge)
  SyntaxError: illegal character (Firefox)
  SyntaxError: Invalid or unexpected token (Chrome)
```

에러 타입
-----

`SyntaxError`무엇이 잘못되었을까?
-----------

코드에 해당 구문에 맞지 않거나 예기치 않은 토큰이 있습니다. 마이너스 기호(`-`)와 대시(`–`) 또는 따옴표(`"`)와 비표준 따옴표(`“`) 등이 잘못 사용된 경우에 대해 문법 체크를 해주는 편집기를 사용하여 코드를 주의 깊게 확인해야 합니다.

예제
--

### 잘못 사용된 문자

일부 문자들은 비슷하게 보이지만 파서가 코드 해석을 실패하게 만듭니다. 유명한 예로 따옴표, 마이너스 또는 세미콜론(greek questionmark (U+37e)과 동일하게 보입니다)이 있습니다.

```js
“This looks like a string”;  // SyntaxError: illegal character
                             // 비슷해 보이지만 “와 ”는 "이 아닙니다

42 – 13;                     // SyntaxError: illegal character
                             // 비슷해 보이지만 –은 -이 아닙니다

var foo = 'bar';             // SyntaxError: illegal character
                             // 비슷해 보이지만 <37e>은 ;이 아닙니다
```

아래 예제는 정상적으로 동작합니다:

```js
"This is actually a string";
42 - 13;
var foo = "bar";
```

일부 편집기와 IDE는 문제가 있는 부분을 알려주거나 적어도 강조 표시를 해주지만 전부는 아닙니다. 이런 에러가 발생했을 때 무엇이 문제인지 찾을 수 없는 경우, 문제가 있는 줄을 지우고 다시 작성하는 것 가장 좋습니다.

### 문자 빠트리기

앞이나 뒤에 오는 문자를 잊어버리기 쉽습니다.

```js
var colors = ['#000', #333', '#666'];
// SyntaxError: illegal character
```

`'#333'`에 빠진 작은따옴표를 추가합니다.

```js
var colors = ["#000", "#333", "#666"];
```

### 숨겨진 문자

다른 곳에서 코드를 복사하여 붙여넣은 경우 잘못된 문자가 포함돼 있을 수 있습니다. 주의하세요!

```js
var foo = 'bar';
// SyntaxError: illegal character
```

Vim과 같은 편집기에서 아래 코드를 체크하면 폭 없는 공백(zero-width space (ZWSP) (U+200B)) 문자가 있는 것을 확인할 수 있습니다.

```js
var foo = 'bar';<200b>
```

같이 보기
-----

* 문법 (en-US)


SyntaxError: applying the 'delete' operator to an unqualified name is deprecated - JavaScript

SyntaxError: applying the 'delete' operator to an unqualified name is deprecated
================================================================================

메세지
---
```

  SyntaxError: Calling delete on expression not allowed in strict mode (Edge)
  SyntaxError: applying the 'delete' operator to an unqualified name is deprecated (Firefox)
  SyntaxError: Delete of an unqualified identifier in strict mode. (Chrome)
```

에러 타입
-----

엄격(Strict) 모드에서의 `SyntaxError`

무엇이 잘못되었을까?
-----------

JavaScript에서 일반 변수는 `delete` (en-US) 연산자를 사용하여 삭제할 수 없습니다. 엄격 모드에서 변수를 삭제하는 접근은 허용되지 않으므로 에러가 발생합니다.

`delete` 연산자는 오직 객체의 속성만을 삭제할 수 있습니다. 객체 속성은 설정할 수 있는 경우 "수식"될 수 있습니다.

일반적인 생각과 다르게 `delete` 연산자는 메모리 해제와 직접적인 연관이 없습니다. 메모리 관리는 참조가 깨짐에 따라 간접적으로 수행됩니다. 자세한 내용은 메모리 관리 페이지와 `delete` (en-US) 연산자 페이지를 참조하십시오.

이 에러는 오직 엄격 모드 코드에서만 발생합니다. 엄격하지 않은 모드에서 해당 연산자는 단순히 `false` 를 반환합니다.

예제
--

JavaScript에서 일반 변수를 삭제하려고 하면 동작하지 않습니다. 그리고 엄격 모드에서는 에러가 발생합니다:

```js
"use strict";

var x;

// ...

delete x;

// SyntaxError: applying the 'delete' operator to an unqualified name
// is deprecated
```

변수의 내용을 비우려면 `null`을 설정하면 됩니다:

```js
"use strict";

var x;

// ...

x = null;

// x는 가비지 컬렉터에 의해 메모리에서 해제됩니다
```

같이 보기
-----

* `delete` (en-US)
* 메모리 관리
* TypeError: property "x" is non-configurable and can't be deleted (en-US)


SyntaxError: function statement requires a name - JavaScript

SyntaxError: function statement requires a name
===============================================

메세지
---
```

    Syntax Error: Expected identifier (Edge)
    SyntaxError: function statement requires a name [Firefox]
    SyntaxError: Unexpected token ( [Chrome]
```

에러 타입
-----

`SyntaxError`무엇이 잘못되었을까?
-----------

함수 구문(Function statement)은 이름이 필수입니다. 함수가 정의된 방법에 따라 함수의 이름을 짓거나 함수 표현식(Function expression) IIFE으로 작성하거나, 함수가 맥락에 맞게 제대로 작성되었는지 확인해야 합니다.

예제
--

### 구문 vs 표현식

함수 구문(또는 함수 선언)은 이름이 필요하므로 아래 예제는 동작하지 않습니다:

```js
function () {
  return 'Hello world';
}
// SyntaxError: function statement requires a name
```

대신 함수 표현식을 사용할 수 있습니다:

```js
var greet = function () {
  return "Hello world";
};
```

또는, 선언하자마자 바로 실행되는 IIFE (Immediately Invoked Function Expression)를 사용할 수 있습니다. 이 경우 몇 개의 괄호가 더 필요합니다:

```js
(function () {})();
```

### 레이블을 붙인 함수

만약 함수 레이블을 사용하는 경우 `function` 키워드 뒤에 함수 이름이 필요하므로 아래 예제는 동작하지 않습니다:

```js
function Greeter() {
  german: function () {
    return "Moin";
  }
}
// SyntaxError: function statement requires a name
```

아래 예제는 동작합니다:

```js
function Greeter() {
  german: function g() {
    return "Moin";
  }
}
```

### 객체 메소드

만약 객체 메소드를 만드는 경우 먼저 객체를 만들어야 합니다. 객체 메소드의 경우 아래 예제와 같이 `function` 키워드 뒤에 이름이 없어도 정상적으로 동작합니다.

```js
var greeter = {
  german: function () {
    return "Moin";
  },
};
```

### 콜백 구문

콜백을 사용하는 경우 구문을 확인해야 합니다. 괄호와 쉼표는 구문을 어렵게 만듭니다.

```js
promise.then(
  function() {
    console.log("success");
  });
  function() {
    console.log("error");
}
// SyntaxError: function statement requires a name
```

올바르게 변경하면:

```json
promise.then(
  function() {
    console.log("success");
  },
  function() {
    console.log("error");
  }
);
```

같이 보기
-----

* 함수
* 함수 구문
* 함수 표현식
* IIFE
* 레이블


SyntaxError: for-in loop head declarations may not have initializers - JavaScript

SyntaxError: for-in loop head declarations may not have initializers
====================================================================

메세지
---
```

    SyntaxError: for-in loop head declarations cannot have an initializer (Edge)
    SyntaxError: for-in loop head declarations may not have initializers (Firefox)
    SyntaxError: for-in loop variable declaration may not have an initializer. (Chrome)
```

에러 타입
-----

엄격(Strict) 모드에서의 `SyntaxError`.

무엇이 잘못되었을까?
-----------

for...in 반복문의 선언부에 초기화 구문이 포함되어 있습니다. 즉, |`for (var i = 0 in obj)`| 구문을 통해 변수가 정의되고 값이 할당된 것을 말합니다. 비엄격 모드(non-strict) 모드에서는 이 초기화 구문이 무시되어 `|for (var i in obj)|` 처럼 동작합니다. 하지만 엄격 모드에서는 `SyntaxError` 가 발생합니다.

예제
--

이 예제는 `SyntaxError`를 발생시킵니다.

```js
"use strict";

var obj = {a: 1, b: 2, c: 3 };

for (var i = 0 in obj) {
  console.log(obj[i]);
}

// SyntaxError: for-in loop head declarations may not have initializers
```

### 올바른 for-in 반복문

for-in 반복문의 선언부에서 초기화 구문(`i = 0`)을 삭제합니다.

```js
"use strict";

var obj = { a: 1, b: 2, c: 3 };

for (var i in obj) {
  console.log(obj[i]);
}
```

### 배열 반복

for...in 반복문은 배열을 반복하는데에는 사용하지 않습니다. 배열(`Array`)을 반복하기 위해 `for-in` 반복문 대신에 `for` 반복문을 사용하려고 한 적이 있습니까? `for` 반복문은 선언부에서 초기화도 할 수 있습니다:

```js
var arr = ["a", "b", "c"];

for (var i = 2; i < arr.length; i++) {
  console.log(arr[i]);
}

// "c"
```

같이 보기
-----

* `for...in`
* `for...of` – 엄격 모드와 비엄격 모드에서 모두 초기화를 허용하지 않습니다.
* `for` – 배열 반복에 적합하고 초기화도 가능합니다.


TypeError: "x" is read-only - JavaScript

TypeError: "x" is read-only
===========================

메시지
---
```

    TypeError: "x" is read-only (Firefox)
    TypeError: 0 is read-only (Firefox)
    TypeError: Cannot assign to read only property 'x' of #<Object> (Chrome)
    TypeError: Cannot assign to read only property '0' of [object Array] (Chrome)
```

에러 유형
-----

`TypeError`무엇이 잘못 된 걸까?
------------

전역변수 또는 객체 프로퍼티가 읽기 전용으로 할당된 경우입니다.(엄밀히 따지자면 쓰기가 불가능한 데이터 속성입니다.)

이 에러는 엄격모드에서만 등장합니다. 엄격하지 않은 모드에서는 읽기전용 속성은 묵시적으로 무시됩니다.

예시
--

### 적절하지 않은 예

읽기 전용 속성은 아주 흔한 것은 아니지만, `Object.defineProperty()` 나 `Object.freeze()` 를 이용해 만들어 질 수 있습니다.

```js
"use strict";
var obj = Object.freeze({ name: "Elsa", score: 157 });
obj.score = 0; // TypeError

("use strict");
Object.defineProperty(this, "LUNG\_COUNT", { value: 2, writable: false });
LUNG\_COUNT = 3; // TypeError

("use strict");
var frozenArray = Object.freeze([0, 1, 2]);
frozenArray[0]++; // TypeError
```

자바 스크립트에는 몇 가지 읽기 전용 속성이 내장되어 있습니다. 아마도 수학적 상수를 재정의하려고 한 것 같습니다.

```js
"use strict";
Math.PI = 4; // TypeError
```

이렇게는 불가능합니다.

전역변수 `undefined` 또한 읽기전용으로, 사람들이 모두 좋아하지 않는 "undefined is not a function" 에러가 다음과 같은 경우 등장합니다:

```js
"use strict";
undefined = function () {}; // TypeError: "undefined" is read-only
```

### 적절한 예

```js
"use strict";
var obj = Object.freeze({ name: "Score", points: 157 });
obj = { name: obj.name, points: 0 }; // replacing it with a new object works

("use strict");
var LUNG\_COUNT = 2; // a `var` works, because it's not read-only
LUNG\_COUNT = 3; // ok (anatomically unlikely, though)
```

더보기
---

* `Object.defineProperty()`
* `Object.freeze()`
* "Which animals have three lungs?" on answers.com
* Klingons (another answer to that query)


ReferenceError: reference to undefined property "x" - JavaScript

ReferenceError: reference to undefined property "x"
===================================================

메시지
---
```

  ReferenceError: reference to undefined property "x" (Firefox)
```

에러 형식
-----

엄격 모드(strict mode)에서만 발생하는 `ReferenceError` 경고.

무엇이 잘못되었을까?
-----------

이 스크립트는 존재하지 않는 객체의 속성에 접근을 시도했습니다. 요소에 접근하는 방법에는 두 가지가 있습니다.; 더 자세히 알고 싶으시다면, 속성 접근자(property accessors) 참조 문서를 봐주세요.

정의되지 않은 속성 참조에 대한 에러는 엄격 모드 코드(strict mode code)에서만 발생합니다. 비-엄격모드의 코드에서는 존재하지 않는 속성에 대한 접근은 조용히 무시됩니다.

예
-

### 허용되지 않는 경우

이 경우에는, 속성 `bar` 는 정의되지 않은 속성으로, `ReferenceError` 가 발생합니다.

```js
"use strict";

var foo = {};
foo.bar; // ReferenceError: reference to undefined property "bar"
```

### 허용되는 경우

에러를 피하기 위해서는, 접근을 시도하기 앞서, 객체에 `bar` 에 대한 정의를 추가하거나 `bar` 속성의 존재 여부를 확인해야 합니다.; 아래와 같이 `Object.prototype.hasOwnProperty()` (en-US) method)를 사용하는 것이 하나의 방법이 될 수 있습니다.:

```js
"use strict";

var foo = {};

// bar 속성을 정의한다.

foo.bar = "moon";
console.log(foo.bar); // "moon"

// bar에 접근하기 전에 존재 하는지 확인한다.

if (foo.hasOwnProperty("bar") {
  console.log(foo.bar);
}
```

참조
--

* Strict mode


TypeError: "x" has no properties - JavaScript

TypeError: "x" has no properties
================================

`null` 과 `undefined` 라는 속성에 접근하려고 시도할때 "null(혹은 undefined)은 속성이 없습니다"라는 JavaScript 에러가 발생합니다.

메세지
---
```

TypeError: Cannot read properties of undefined (reading 'x') (V8-based)
TypeError: null has no properties (Firefox)
TypeError: undefined has no properties (Firefox)
TypeError: undefined is not an object (evaluating 'undefined.x') (Safari)
```

에러 타입
-----

`TypeError`.

무엇이 잘못되었을까?
-----------

`null` 과 `undefined` 에 접근 할 수 있는 속성이 없습니다.

예제
--

### null and undefined have no properties

```js
null.foo;
// TypeError: null has no properties

undefined.bar;
// TypeError: undefined has no properties
```

참조
--

* `null`
* `undefined`


SyntaxError: "0"-prefixed octal literals and octal escape seq. are deprecated - JavaScript

SyntaxError: "0"-prefixed octal literals and octal escape seq. are deprecated
=============================================================================

메시지
---
```

    SyntaxError: Octal numeric literals and escape characters not allowed in strict mode (Edge)
    SyntaxError:
    "0"-prefixed octal literals and octal escape sequences are deprecated;
    for octal literals use the "0o" prefix instead
```

에러 타입
-----

`SyntaxError` strict mode 내에서만.

무엇이 잘 못 되었을까?
-------------

8진 리터럴과 8진수 이스케이프 시퀀스는 더 이상 사용하지 않으며, 엄격 모드(strict mode) 내에서는 `SyntaxError` 에러를 던질 것입니다. ECMAScript 2015와 이 후의 버전의 표준화된 구문은 0을 맨 앞자리에 두고 그 뒤를 대문자 또는 소문자의 라틴 문자 "O" 를 사용하도록 합니다. (`0o` 또는 `0O)`

예제
--

### "0"이 접두인 8진 리터럴

```js
"use strict";

03;

// SyntaxError: "0"-prefixed octal literals and octal escape sequences
// are deprecated (0으로 시작하는 8진수와 8진 이스케이프 시퀀스는 더 이상 사용되지 않습니다. )
```

### 8진수 이스케이프 시퀀스

```js
"use strict";

"\251";

// SyntaxError: "0"-prefixed octal literals and octal escape sequences
// are deprecated (0으로 시작하는 8진수와 8진 이스케이프 시퀀스는 더 이상 사용되지 않습니다. )
```

### 유효한 8진 수들

0뒤에 "o" 또는 "O"를 사용합니다. :

```js
0o3;
```

8진수 이스케이프 시퀀스 대신 16진수 이스케이프 시퀀스를 사용할 수도 있습니다. :

```js
"\xA9";
```

See also
--------

* Lexical grammar (en-US)
* Warning: 08/09 is not a legal ECMA-262 octal constant (en-US)


ReferenceError: "x" is not defined - JavaScript

ReferenceError: "x" is not defined
==================================

메시지
---
```

    ReferenceError: "x" is not defined
```

에러 타입
-----

`ReferenceError`.

무엇이 잘못되었을까?
-----------

존재하지 않는 변수를 참조하는 곳이 있습니다. 이 변수는 선언되어야 합니다. 또는, 현재 스크립트나 scope 에서 사용이 가능하도록 해야합니다.

**참고:** 라이브러리(예를 들면 jQuery와 같은)의 로딩은, 반드시 코드에서 "$"와 같은 라이브러리 변수에 접근하기 이전에 수행되어야 합니다. 라이브러리를 로딩하는 `<script>` 태그가 그 변수를 사용하는 코드보다 앞에 위치하도록 하세요.

예
-

### 선언되지 않은 변수

```js
foo.substring(1); // ReferenceError: foo is not defined
```

"foo" 변수는 어디에도 선언되지 않았습니다. `String.prototype.substring()` 메소드가 작동하도록 하기 위해서는 문자열을 필요로 합니다.

```js
var foo = "bar";
foo.substring(1); // "ar"
```

### 잘못된 스코프

변수는 현재의 실행 흐름 내에서 이용 가능해야합니다. 함수 내부에 정의된 변수는 다른 외부의 함수에서는 접근할 수 없습니다. 그 때문에, 변수는 함수의 스코프 내부에서만 정의 됩니다.

```js
function numbers() {
  var num1 = 2,
    num2 = 3;
  return num1 + num2;
}

console.log(num1); // ReferenceError: num1 is not defined
```

그러나, 함수는 모든 변수와 정의된 스코프 안에 정의된 함수에 접근할 수 있습니다. 따라서, 전역으로 정의된 함수는 전역에 정의된 모든 변수에도 접근할 수 있습니다.

```js
var num1 = 2,
  num2 = 3;

function numbers() {
  return num1 + num2;
}

console.log(num1); // 2
```

참조
--

* Scope
* Declaring variables in the JavaScript Guide
* Function scope in the JavaScript Guide


RangeError: argument is not a valid code point - JavaScript

RangeError: argument is not a valid code point
==============================================

메시지
---
```

    RangeError: {0} is not a valid code point (Firefox)
    RangeError: Invalid code point {0} (Chrome)
```

에러 형식
-----

`RangeError`무엇이 잘못되었을까?
-----------

`String.fromCodePoint()` (en-US) 메소드는 유효한 코드 포인트(code point)만을 받아들입니다.

code point는 유니코드의 코드 스페이스 값으로, `0`부터 `0x10FFFF`까지의 정수 범위입니다.

`NaN`을 사용하는 값, 음수 (`-1`), 정수가 아닌 수(3.14), 또는 `0x10FFFF` (`1114111`) 보다 큰 값은 이 함수에 적용될 수 없습니다.

예
-

### 유효하지 않은 경우

```js
String.fromCodePoint("\_"); // RangeError
String.fromCodePoint(Infinity); // RangeError
String.fromCodePoint(-1); // RangeError
String.fromCodePoint(3.14); // RangeError
String.fromCodePoint(3e-2); // RangeError
String.fromCodePoint(NaN); // RangeError
```

### 유효한 경우

```js
String.fromCodePoint(42); // "\*"
String.fromCodePoint(65, 90); // "AZ"
String.fromCodePoint(0x404); // "\u0404"
String.fromCodePoint(0x2f804); // "\uD87E\uDC04"
String.fromCodePoint(194564); // "\uD87E\uDC04"
String.fromCodePoint(0x1d306, 0x61, 0x1d307); // "\uD834\uDF06a\uD834\uDF07"
```

참조
--

* `String.fromCodePoint()` (en-US)


TypeError: "x" is (not) "y" - JavaScript

TypeError: "x" is (not) "y"
===========================

Message
-------
```

    TypeError: "x" is (not) "y"

    Examples:
    TypeError: "x" is undefined
    TypeError: "x" is null
    TypeError: "undefined" is not an object
    TypeError: "x" is not an object or null
    TypeError: "x" is not a symbol
```

Error type
----------

`TypeError`.

What went wrong?
----------------

그것은 정확하지 않은 형태이다. 그것은 가끔`undefined` 나 `null` 값을 발생한다.

또한, `Object.create()` 또는 `Symbol.keyFor()`와 같은 메서드는 반드시 제공되어야하는 특별한 형태를 요구한다.

Examples
--------

### Invalid cases

```js
// undefined and null cases on which the substring method won't work
var foo = undefined;
foo.substring(1); // TypeError: foo is undefined

var foo = null;
foo.substring(1); // TypeError: foo is null

// Certain methods might require a specific type
var foo = {};
Symbol.keyFor(foo); // TypeError: foo is not a symbol

var foo = "bar";
Object.create(foo); // TypeError: "foo" is not an object or null
```

### Fixing the issue

undefined 나 null 값을 가진 null 포인터를 고치기 위해서 아래 예제와 같이 typeof 연산자를 사용할 수 있다.

```js
if (typeof foo !== "undefined") {
  // Now we know that foo is defined, we are good to go.
}
```

같이 보기
-----

* `undefined`
* `null`


SyntaxError: return not in function - JavaScript

SyntaxError: return not in function
===================================

 JavaScript 예외 "return (or yield) not in function"은
 `return`
 또는 `yield`
 이 function 외부에서 호출될 때 발생합니다.

메시지
---

```js
SyntaxError: 'return' statement outside of function (Edge)
  SyntaxError: return not in function (Firefox)
  SyntaxError: yield not in function (Firefox)
```

에러 타입
-----

`SyntaxError`.

무엇이 잘못된 걸까요?
------------

`return`
 또는 `yield`
 문장이 function 밖에서 호출되었기 때문입니다.
 혹시 어딘가에 중괄호를 빠트리신 건 아닌가요? `return`과 `yield`는 function 내에 있어야합니다.
 왜냐하면 이것들은 function의 실행 종료 (또는 일시정지 및 재개)를 의미하고 function 호출자에게 특정 값을 반환하기 위해 사용되기 때문입니다.

예제
--

### 중괄호 누락

```js
var cheer = function(score) {
  if (score === 147)
    return 'Maximum!';
  };
  if (score > 100) {
    return 'Century!';
  }
}

// SyntaxError: return not in function
```

처음 볼 때는 중괄호가 제대로 있는 것처럼 보인다, 하지만 이 코드 조각에는 if 문장 다음에 중괄호가 하나 빠져 있다. 다음처럼 고쳐야 한다:

```js
var cheer = function (score) {
  if (score === 147) {
    return "Maximum!";
  }
  if (score > 100) {
    return "Century!";
  }
};
```

같이 보기
-----

* `return`
* `yield`


RangeError: invalid date - JavaScript

RangeError: invalid date
========================

메시지
---
```

    RangeError: invalid date (Firefox)
    RangeError: invalid time value (Chrome)
    RangeError: Provided date is not in valid range (Chrome)
```

에러 종류
-----

`RangeError`무엇이 잘못 된 걸까?
------------

유효하지 않은 String이 `Date` 나 `Date.parse()`에 입력되었습니다.

예시
--

### 올바르지 않은 사용 예시

인식 할 수 없는 string이나 잘못된 요소 값을 포함하는 ISO 형식의 날짜 string은 일반적으로 `NaN`을 반환합니다. 그러나 구현 방식에 따라 ISO 형식 string을 따르지 않는 경우 `RangeError: invalid date`가 표시 될 수 있습니다. Firefox의 경우:

```js
new Date("foo-bar 2014");
new Date("2014-25-23").toISOString();
new Date("foo-bar 2014").toString();
```

그러나 이 경우, Firefox에서는 `NaN` 을 반환합니다:

```js
Date.parse("foo-bar 2014"); // NaN
```

더 자세한 사항은 `Date.parse()` 문서를 참고하세요.

### 올바른 사용 예시

```js
new Date("05 October 2011 14:48 UTC");
```

더 보기
----

* `Date`
* `Date.prototype.parse()`
* `Date.prototype.toISOString()`


TypeError: 'x' is not iterable - JavaScript

TypeError: 'x' is not iterable
==============================

메시지
---
```

    TypeError: 'x' is not iterable (Firefox, Chrome)
    TypeError: 'x' is not a function or its return value is not iterable (Chrome)
```

에러 타입
-----

`TypeError`무엇이 문제인가요?
----------

`Promise.all` 또는 `TypedArray.from` (en-US) 과 같은 함수의 아규먼트 또는 for…of 의 right hand-side 로 주어진 값이 iterable 객체가 아닙니다. iterable 은 `Array`, `String` 또는 `Map`, 생성자 결과, 또는 iterable protocol 구현 객체와 같은 내장 iterable 타입이 될 수 있습니다.

예제
--

### 모든 객체 프로퍼티 iterating

 JavaScript 에서 iterable protocol 을 구현하지 않은 `Object` 는 iterable 이 아닙니다.
 그러므로, 객체의 프로퍼티를 반복하기 위해 for…of 를 사용하면 안됩니다.

```js
var obj = { France: "Paris", England: "London" };
for (let p of obj) {
  // TypeError: obj is not iterable
  // …
}
```

객체의 모든 항목 또는 프로퍼티를 반복하려면 대신 `Object.keys` 또는 `Object.entries` 를 사용해야 합니다.

```js
var obj = { France: "Paris", England: "London" };
// 모든 프로퍼티 이름을 iterate:
for (let country of Object.keys(obj)) {
  var capital = obj[country];
  console.log(country, capital);
}

for (const [country, capital] of Object.entries(obj))
  console.log(country, capital);
```

이 유즈 케이스에 대한 다른 옵션은 `Map` 을 사용하는 것입니다.

```js
var map = new Map();
map.set("France", "Paris");
map.set("England", "London");
// 모든 프로퍼티 이름 iterate
for (let country of map.keys()) {
  let capital = map[country];
  console.log(country, capital);
}

for (let capital of map.values()) console.log(capital);

for (const [country, capital] of map.entries()) console.log(country, capital);
```

### Generator iterating

Generators 는 iterable 객체를 생성하기 위해 호출하는 함수입니다.

```js
function\* generate(a, b) {
  yield a;
  yield b;
}

for (let x of generate) // TypeError: generate is not iterable
  console.log(x);
```

generator 가 호출되지 않으면, generator 에 해당하는 `Function` 객체를 호출할수는 있지만 interable 하지는 않습니다. generator 호출은 generator 실행동안 yield 된 모든 값을 iterate 하는 iterable 객체를 생성합니다.

```js
function\* generate(a, b) {
  yield a;
  yield b;
}

for (let x of generate(1, 2)) console.log(x);
```

함께 보기
-----

* iterable protocol
* `Object.keys`
* `Object.entries`
* `Map`
* generators
* for…of


SyntaxError: JSON.parse: bad parsing - JavaScript

SyntaxError: JSON.parse: bad parsing
====================================

메시지
---
```

    SyntaxError: JSON.parse: unterminated string literal
    SyntaxError: JSON.parse: bad control character in string literal
    SyntaxError: JSON.parse: bad character in string literal
    SyntaxError: JSON.parse: bad Unicode escape
    SyntaxError: JSON.parse: bad escape character
    SyntaxError: JSON.parse: unterminated string
    SyntaxError: JSON.parse: no number after minus sign
    SyntaxError: JSON.parse: unexpected non-digit
    SyntaxError: JSON.parse: missing digits after decimal point
    SyntaxError: JSON.parse: unterminated fractional number
    SyntaxError: JSON.parse: missing digits after exponent indicator
    SyntaxError: JSON.parse: missing digits after exponent sign
    SyntaxError: JSON.parse: exponent part is missing a number
    SyntaxError: JSON.parse: unexpected end of data
    SyntaxError: JSON.parse: unexpected keyword
    SyntaxError: JSON.parse: unexpected character
    SyntaxError: JSON.parse: end of data while reading object contents
    SyntaxError: JSON.parse: expected property name or '}'
    SyntaxError: JSON.parse: end of data when ',' or ']' was expected
    SyntaxError: JSON.parse: expected ',' or ']' after array element
    SyntaxError: JSON.parse: end of data when property name was expected
    SyntaxError: JSON.parse: expected double-quoted property name
    SyntaxError: JSON.parse: end of data after property name when ':' was expected
    SyntaxError: JSON.parse: expected ':' after property name in object
    SyntaxError: JSON.parse: end of data after property value in object
    SyntaxError: JSON.parse: expected ',' or '}' after property value in object
    SyntaxError: JSON.parse: expected ',' or '}' after property-value pair in object literal
    SyntaxError: JSON.parse: property names must be double-quoted strings
    SyntaxError: JSON.parse: expected property name or '}'
    SyntaxError: JSON.parse: unexpected character
    SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data
```

에러 타입
-----

`SyntaxError`뭐가 잘못됬나요?
---------

`JSON.parse()` 는 문자열을 JSON으로 파싱한다. 이 문자열은 유효한 JSON 형태의 문자열이어야 하며, 유효하지 않을 경우 에러가 발생한다.

예제
--

### `JSON.parse()` 는 여분의 콤마를 허용하지 않는다

다음 두 줄은 SyntaxError를 발생시킨다:

```js
JSON.parse("[1, 2, 3, 4,]");
JSON.parse('{"foo": 1,}');
// SyntaxError JSON.parse: unexpected character
// at line 1 column 14 of the JSON data
```

끝에 오는 콤마를 제거하면 정확하게 JSON으로 파싱한다:

```js
JSON.parse("[1, 2, 3, 4]");
JSON.parse('{"foo": 1}');
```

### 프로퍼티 이름은 반드시 쌍따옴표로 표현해야 한다

'foo'처럼 프로퍼티를 작은 따옴표로 감싸서는 안된다.

```js
JSON.parse("{'foo': 1}");
// SyntaxError: JSON.parse: expected property name or '}'
// at line 1 column 2 of the JSON data
```

대신에 "foo" 처럼 써야 한다:

```js
JSON.parse('{"foo": 1}');
```

### 리딩 제로와 십진 소수점

01 처럼 리딩제로를 사용할 수 없고, 십진 소수점 뒤에는 최소한 하나의 숫자는 등장해야 한다.

```js
JSON.parse('{"foo": 01}');
// SyntaxError: JSON.parse: expected ',' or '}' after property value
// in object at line 1 column 2 of the JSON data

JSON.parse('{"foo": 1.}');
// SyntaxError: JSON.parse: unterminated fractional number
// at line 1 column 2 of the JSON data
```

대신에 리딩제로를 없애고 1 이라고 쓰고, 십진 소수점 뒤에는 반드시 하나 이상의 숫자를 적도록 한다:

```js
JSON.parse('{"foo": 1}');
JSON.parse('{"foo": 1.0}');
```

또다른 내용
------

* `JSON`
* `JSON.parse()`
* `JSON.stringify()`


SyntaxError: missing } after property list - JavaScript

SyntaxError: missing } after property list
==========================================

메시지
---
```

    SyntaxError: missing } after property list
```

에러 유형
-----

`SyntaxError`무엇이 잘못 된 걸까?
------------

객체를 초기화 하는 부분 어딘가에 구문에 실수가 있습니다. 실제로 빠진 중괄호 일 수도 있지만, 누락 된 쉼표 일 수도 있습니다. 또한 닫는 중괄호나 괄호가 올바른 순서인지 확인하세요. 코드를 들여쓰기하거나 서식을 지정하면 좀 더 보기 쉽습니다.

예시
--

### 쉼표를 까먹은 경우

종종 객체 초기화 과정에서 쉼표를 빠트리는 경우가 있습니다:

```js
var obj = {
  a: 1,
  b: { myProp: 2 }
  c: 3
};
```

올바른 예시는 다음과 같습니다:

```js
var obj = {
  a: 1,
  b: { myProp: 2 },
  c: 3,
};
```

더 보기
----

* Object initializer


RangeError: repeat count must be less than infinity - JavaScript

RangeError: repeat count must be less than infinity
===================================================

메시지
---
```

    RangeError: repeat count must be less than infinity and not overflow maximum string size (Firefox)
    (repeat count는 infinity보다 작아야하며, 최대 문자열 크기를 넘길 수 없습니다.)

    RangeError: Invalid count value (Chrome)
```

에러 형식
-----

`RangeError`무엇이 잘못되었을까?
-----------

`String.prototype.repeat()` 메소드가 사용되었습니다. 이 메소드는 문자열을 반복하는 수를 예측하는 카운트 파라메터를 가지고 있었습니다. 그리고 이 파라메터는 0보다 커야하며, 양의 `Infinity` 보다 작아야 했으며, 음수는 허용되지 않았습니다. 이 값의 허용 범위는 이렇게 표현될 수 있습니다. : [0, +∞).

결과인 문자열은 최대 문자열 크기보다 클 수 없지만, JavaScript 에서는 다를 수 있습니다. Firefox (SpiderMonkey) 에서의 최대 문자열 크기는 2^28 -1 (`0xFFFFFFF`)입니다.

예
-

### 허용되지 않는 경우

```js
"abc".repeat(Infinity); // RangeError
"a".repeat(2 \*\* 28); // RangeError
```

### 허용되는 경우

```js
"abc".repeat(0); // ''
"abc".repeat(1); // 'abc'
"abc".repeat(2); // 'abcabc'
"abc".repeat(3.5); // 'abcabcabc' (숫자는 정수로 변환될 것입니다.)
```

참조
--

* `String.prototype.repeat()`


RangeError: precision is out of range - JavaScript

RangeError: precision is out of range
=====================================

메시지
---
```

    RangeError: precision {0} out of range (Firefox)
    RangeError: toExponential() argument must be between 0 and 20 (Chrome)
    RangeError: toFixed() digits argument must be between 0 and 20 (Chrome)
    RangeError: toPrecision() argument must be between 1 and 21 (Chrome)
```

에러 형식
-----

`RangeError`무엇이 잘못되었을까?
-----------

아래의 메소드들 중 하나에서, 실행 인자(argument)가 정확도의 범위를 벗어났습니다. :

* `Number.prototype.toExponential()`
* `Number.prototype.toFixed()`
* `Number.prototype.toPrecision()`

이 메소드들에게 허용된 범위는 0부터 20 (또는 21)까지 입니다. 하지만, ECMAScript 스펙은 아래의 범위까지 확장하여 허용하고 있습니다.

| Method | Firefox (SpiderMonkey) | Chrome, Opera (V8) |
| --- | --- | --- |
| `Number.prototype.toExponential()` | 0 부터 100 | 0 부터 20 |
| `Number.prototype.toFixed()` | -20 부터 100 | 0 부터 20 |
| `Number.prototype.toPrecision()` | 1 부터 100 | 1 부터 21 |

예
-

### 유효하지 않은 경우

```js
(77.1234).toExponential(-1); // RangeError
(77.1234).toExponential(101); // RangeError

(2.34).toFixed(-100); // RangeError
(2.34).toFixed(1001); // RangeError

(1234.5).toPrecision(-1); // RangeError
(1234.5).toPrecision(101); // RangeError
```

### 유효한 경우

```js
(77.1234).toExponential(4); // 7.7123e+1
(77.1234).toExponential(2); // 7.71e+1

(2.34).toFixed(1); // 2.3
(2.35).toFixed(1); // 2.4 (note that it rounds up in this case)

(5.123456).toPrecision(5); // 5.1235
(5.123456).toPrecision(2); // 5.1
(5.123456).toPrecision(1); // 5
```

참조
--

* `Number.prototype.toExponential()`
* `Number.prototype.toFixed()`
* `Number.prototype.toPrecision()`


RangeError: radix must be an integer - JavaScript

RangeError: radix must be an integer
====================================

 JavaScript 예외 "radix must be an integer at least 2 and no greater than 36"는
 `Number.prototype.toString()` 또는 `BigInt.prototype.toString()` (en-US)
 메서드의 선택적 매개 변수가 지정된 경우 2에서 36 사이여야 합니다.

메시지
---

```js
  RangeError: invalid argument (Edge)
  RangeError: radix must be an integer at least 2 and no greater than 36 (Firefox)
  RangeError: toString() radix argument must be between 2 and 36 (Chrome)
```

에러 형식
-----

`RangeError`무엇이 잘못되었을까?
-----------

`Number.prototype.toString()` 또는
 `BigInt.prototype.toString()` (en-US)
 메서드는 선택적 파라미터인 `radix`(기수: 진수를 지정하는 값)와 함게 사용되어 왔습니다.
 이 파라미터는 반드시 수의 값을 나타내는 진법 2와 36 사이로 지정된 정수(숫자)여야 합니다.

 이 매개 변수의 값이 36으로 제한된 이유는 무엇일까요?
 10보다 큰 기수는 알파벳 문자를 숫자로 사용하기 때문입니다.
 따라서 기수는 36을 초과할 수 없습니다. 라틴 알파벳(영어와 다른 많은 언어에서 사용됨)은 26자뿐이기 때문입니다.

보통 아래의 `radix` 중 하나를 사용하게 될 것입니다.

* 2 for binary numbers (2진수),
* 8 for octal numbers (8진수),
* 10 for decimal numbers (10진수),
* 16 for hexadecimal numbers (16진수).
예제
--

### 허용되지 않는 경우

```js
(42).toString(0);
(42).toString(1);
(42).toString(37);
(42).toString(150);
//포맷팅하기 위해 string을 이런 식으로 사용할 수는 없습니다. :
(12071989).toString("MM-dd-yyyy");
```

### 허용된 경우

```js
(42).toString(2); // "101010" (2진수)
(13).toString(8); // "15" (8진수)
(0x42).toString(10); // "66" (10진수)
(100000).toString(16); // "186a0" (16진수)
```

또 다른 내용
-------

* `Number.prototype.toString()`
* `BigInt.prototype.toString()` (en-US)


InternalError: too much recursion - JavaScript

InternalError: too much recursion
=================================

메시지
---
```

    InternalError: too much recursion
```

에러 형식
-----

`InternalError`.

무엇이 잘못되었을까?
-----------

자신을 호출하는 함수를 재귀 함수라고 합니다. 어떤 면에서, 재귀는 반복과 유사합니다. 둘 다 같은 코드를 여러 번 실행하며, 조건(무한 반복 피하기, 더 정확히 여기서 말하는 무한 재귀)이 있습니다. 너무 많거나 무한 번의 재귀가 발생할 경우, JavaScript는 이 에러를 던질 것입니다.

예
-

이 재귀 함수는 exit 조건에 따라 10번을 실행합니다.

```js
function loop(x) {
  if (x >= 10) {
    // "x >= 10" is the exit condition
    return;
  }
  // do stuff
  loop(x + 1); // the recursive call
}
loop(0);
```

이 조건에 대하여 너무 높은 값을 설정 하면 작동하지 않게 됩니다.

```js
function loop(x) {
  if (x >= 1000000000000) return;
  // do stuff
  loop(x + 1);
}
loop(0);

// InternalError: too much recursion
```

참조
--

* Recursion
* Recursive functions


ReferenceError: assignment to undeclared variable "x" - JavaScript

ReferenceError: assignment to undeclared variable "x"
=====================================================

메시지
---
```

    ReferenceError: assignment to undeclared variable "x" (Firefox)
    ReferenceError: "x" is not defined (Chrome)
    ReferenceError: Variable undefined in strict mode (Edge)
```

에러 형식
-----

엄격 모드(strict mode)에서만 발생하는 `ReferenceError` 경고.

무엇이 잘못되었을까?
-----------

선언되지 않은 변수로 값은 할당되었습니다. `var` 키워드가 없이 할당이 된 것입니다. 선언된 변수와 선언되지 않은 변수 사이에는 차이가 있는데, 이는 예상치 못한 결과를 가져오며, 때문에 JavaScript 엄격모드에서는 에러를 발생시키고 있습니다.

선언된 변수와 선언되지 않은 변수에 대하여 기억해야 할 세 가지:

* 선언된 변수는 선언된 실행 맥락 내에서 요구됩니다. 선언되지 않은 변수는 항상 전역의 특성을 띱니다.
* 선언된 변수는 코드가 실행되기 전에 생성됩니다. 선언되지 않은 변수는 실행을 위해 할당이 일어날 때까지 존재하지 않습니다.
* 선언된 변수는 실행 맥락 내(함수나 전역적인)에서 변경 불가한 요소입니다. 선언되지 않은 변수는 변경이 가능합니다. (삭제 될 수도 있습니다.)

더 많은 설명과 예제를 필요로 한다면 이 `var` 참조문서 페이지를 보세요.

선언되지 않은 변수 할당에 대한 에러는 엄격 모드(strict mode code)에서만 발생합니다. 비-엄격 코드에서는 조용히 묵인됩니다.

예
-

### 허용되지 않는 경우

이런 경우에는, 변수 "bar"는 선언되지 않은 변수가 됩니다.

```js
function foo() {
  "use strict";
  bar = true;
}
foo(); // ReferenceError: assignment to undeclared variable bar
```

### 허용되는 경우

"bar" 를 선언된 변수로 만들기 위해서, `var` 키워드를 변수명 앞에 붙여줍니다.

```js
function foo() {
  "use strict";
  var bar = true;
}
foo();
```

참조
--

* Strict mode


SyntaxError: a declaration in the head of a for-of loop can't have an initializer - JavaScript

SyntaxError: a declaration in the head of a for-of loop can't have an initializer
=================================================================================

메세지
---
```

  SyntaxError: for-of loop head declarations cannot have an initializer (Edge)
  SyntaxError: a declaration in the head of a for-of loop can't have an initializer (Firefox)
  SyntaxError: for-of loop variable declaration may not have an initializer. (Chrome)
```

에러 타입
-----

`SyntaxError`무엇이 잘못되었을까?
-----------

for...of 반복문의 식이 초기화 구문을 포함한 것이 문제입니다. 즉, |`for (var i = 0 of iterable)`| 구문을 통해 변수가 정의되고 값이 할당된 것을 말합니다. 이 구문은 for-of 반복문에서 허용되지 않습니다. 이 경우 초기화를 할 수 있는 for 반복문이 필요합니다.

예제
--

### 잘못된 for-of 반복문

```js
let iterable = [10, 20, 30];

for (let value = 50 of iterable) {
  console.log(value);
}

// SyntaxError: a declaration in the head of a for-of loop can't
// have an initializer
```

### 올바른 `for-of` 반복문

for-of 반복문에서 초기화 구문(`value = 50`)을 삭제해야 합니다. 50을 더하고 싶다면 다음 예제와 같이 반복문 안에 추가할 수 있습니다.

```js
let iterable = [10, 20, 30];

for (let value of iterable) {
  value += 50;
  console.log(value);
}
// 60
// 70
// 80
```

같이 보기
-----

* `for...of`
* `for...in` – 엄격(Strict) 모드에서는 마찬가지로 초기화를 허용하지 않습니다. (SyntaxError: for-in loop head declarations may not have initializers)
* `for` – 초기화를 허용합니다.


SyntaxError: invalid regular expression flag "x" - JavaScript

SyntaxError: invalid regular expression flag "x"
================================================

메세지
---
```

  SyntaxError: Syntax error in regular expression (Edge)
  SyntaxError: invalid regular expression flag "x" (Firefox)
  SyntaxError: Invalid regular expression flags (Chrome)
```

에러 타입
-----

`SyntaxError`무엇이 잘못되었을까?
-----------

코드에 잘못된 정규 표현식 플래그가 있습니다. 슬래시로 묶인 패턴으로 구성되어 있는 정규 표현식 문자에서 플래그는 두 번째 플래그 뒤에 정의됩니다. 플래그는 또한 `RegExp` 객체의 생성자 함수에서도 정의될 수 있습니다(두 번째 매개변수). 정규 표현식 플래그는 따로 또는 순서에 상관 없이 같이 사용될 수 있지만 ECMAScript에는 오직 5개만 있습니다.

정규 표현식에 플래그를 포함시키려면 아래의 문법을 사용하세요:

```js
var re = /pattern/flags;
```

또는

```js
var re = new RegExp("pattern", "flags");
```

| 플래그 | 설명 |
| --- | --- |
| `g` | 전역 검색. |
| i | 대소문자 구별 없이 검색. |
| m | 여러 줄(Multi-line) 검색. |
| u | 유니코드; 패턴을 유니코드 코드 포인트의 나열로 취급. |
| y | 현재 위치에서 검색. ("sticky" 검색). `sticky` (en-US) 참조. |

예제
--

5개의 플래그만이 유효합니다.

```js
/foo/bar;

// SyntaxError: invalid regular expression flag "b"
```

정규 표현식을 만들려고 했나요? 두 개의 슬래시가 포함된 표현식은 정규 표현식 문자로 해석됩니다.

```js
let obj = {
  url: /docs/Web
};

// SyntaxError: invalid regular expression flag "W"
```

아니면 문자열로 만들려고 했나요? 작은 따옴표 또는 큰 따옴표를 추가하여 문자열을 만듭니다.

```js
let obj = {
  url: "/docs/Web",
};
```

### 유효한 정규 표현식 플래그

JavaScript에서 허용하는 5개의 유효한 정규 표현식 플래그를 위의 표에서 확인하세요.

```js
/foo/g;
/foo/gim;
/foo/uy;
```

같이 보기
-----

* 정규 표현식
* XRegEx flags – 새로운 4개의 플래그(`n`, `s`, `x`, `A`)를 제공하는 정규 표현식 라이브러리


RangeError: invalid array length - JavaScript

RangeError: invalid array length
================================

메세지
---
```

    RangeError: invalid array length (Firefox)
    RangeError: Invalid array length (Chrome)
    RangeError: Invalid array buffer length (Chrome)
```

에러 형식
-----

`RangeError`무엇이 잘못 된 것일까?
-------------

다음과 같은 원인 때문이다:

* 2^32와 같거나 이보다 긴, 혹은 음수의 길이를 가진 `Array`나 `ArrayBuffer`를 생성했기 때문에, 혹은
* `Array` 속성을 2^32와 같거나 이보다 긴 값으로 설정했기 때문이다.

`Array` 와 `ArrayBuffer` 의 길이에 제한을 둔 이유는, `Array` 나 `ArrayBuffer` 의 length 속성은 사인되지 않은(unsigned) 32 비트 정수로 반영되기 때문이다. 즉 `Array`나 `ArrayBuffer` 는 오직 0 ~`2^32-1` 사이의 값만을 저장할 수 있다.

Array의 length로 해석되는 첫번째 argument로서 문자열 표기를 통해 contructor를 사용하여 Array를 생성할 수 있다.

다른 방법으로는, length 속성을 설정하기 전에 length의 길이에 제한을 두거나, constructor의 aurgment로서 사용할 수 있다.

예제
--

### 잘못된 예제

```js
new Array(Math.pow(2, 40));
new Array(-1);
new ArrayBuffer(Math.pow(2, 32));
new ArrayBuffer(-1);

let a = [];
a.length = a.length - 1; // set -1 to the length property

let b = new Array(Math.pow(2, 32) - 1);
b.length = b.length + 1; // set 2^32 to the length property
```

### 올바른 예제

```js
[Math.pow(2, 40)]; // [ 1099511627776 ]
[-1]; // [ -1 ]
new ArrayBuffer(Math.pow(2, 32) - 1);
new ArrayBuffer(0);

let a = [];
a.length = Math.max(0, a.length - 1);

let b = new Array(Math.pow(2, 32) - 1);
b.length = Math.min(0xffffffff, b.length + 1);

// 0xffffffff is the hexadecimal notation for 2^32 - 1
// which can also be written as (-1 >>> 0)
```

참조
--

* `Array`
* `Array.length`
* `ArrayBuffer`


TypeError: More arguments needed - JavaScript

TypeError: More arguments needed
================================

메시지
---
```

    TypeError: argument is not an Object and is not null (Edge)
    TypeError: Object.create requires at least 1 argument, but only 0 were passed
    TypeError: Object.setPrototypeOf requires at least 2 arguments, but only 0 were passed
    TypeError: Object.defineProperties requires at least 1 argument, but only 0 were passed
```

에러 타입
-----

`TypeError`.

무엇이 잘 못 되었을까?
-------------

함수 호출 시 에러가 있습니다. 더 많은 인수가 주어져야 합니다.

예제
--

`Object.create()` 메서드는 적어도 1개의 인자가 필요하며, `Object.setPrototypeOf()` (en-US) 메서드는 적어도 2개의 인자가 필요합니다.:

```js
var obj = Object.create();
// TypeError: Object.create requires at least 1 argument, but only 0 were passed

var obj = Object.setPrototypeOf({});
// TypeError: Object.setPrototypeOf requires at least 2 arguments, but only 1 were passed
```

예를 들면, 이렇게 프로토 타입으로 `null`를 세팅해서 고칠 수 있습니다.:

```js
var obj = Object.create(null);

var obj = Object.setPrototypeOf({}, null);
```

참조
--

* Functions


SyntaxError: missing = in const declaration - JavaScript

SyntaxError: missing = in const declaration
===========================================

메시지
---
```

    SyntaxError: Const must be initalized (Edge)
    SyntaxError: missing = in const declaration (Firefox)
    SyntaxError: Missing initializer in const declaration (Chrome)
```

에러 유형
-----

`SyntaxError`무엇이 잘못되었나요?
-----------

상수는 일반적인 실행 중에 프로그램에 의해 변경될 수 없는 값입니다. 상수는 재할당되거나 재선언될 수 없습니다. JavaScript에서 상수는 `const` 키워드를 사용해 선언됩니다. 상수는 이니셜라이저가 필요합니다. 다시말해, 한 문장 안에 선언과 동시에 초기화가 이루어져야 합니다 (따라서 추후 수정 불가).

예제
--

### const 이니셜라이저가 빠진 경우

`var` 또는 `let`과 달리, `const` 선언에서는 반드시 값을 정의해야 합니다.

```js
const COLUMNS;
// SyntaxError: missing = in const declaration
```

### 에러 수정

해당 에러를 수정하기 위해서 여러가지 방법이 존재합니다. 문제 상황에서 상수를 사용해 무엇을 하려 했는지 확인해보세요.

#### 상수 값 추가

선언과 같은 문장에 상수 값을 정의합니다.

```js
const COLUMNS = 80;
```

#### `const`, `let`, `var`?

상수를 선언할 목적이 아니었다면 `const`를 사용하지 마세요. `let` 키워드를 이용한 블록범위 변수, 또는 `var` 키워드를 이용한 전역 변수를 사용할 수 있습니다. 두 가지 경우 모두 초기값을 요구하지 않습니다.

```js
let columns;
```

같이 보기
-----

* `const`
* `let`
* `var`


SyntaxError: missing ) after condition - JavaScript

SyntaxError: missing ) after condition
======================================

메시지
---
```

    SyntaxError: missing ) after condition
```

에러 유형
-----

`SyntaxError`무엇이 잘못 된 걸까?
------------

`if`조건문에 에러가 있습니다. 어떠한 프로그래밍 언어에서든 코드는 입력값에 따라 의사를 결정하고 행동을 수행해야합니다. 지정된 조건이 true이면 if 문이 명령문을 실행합니다. JavaScript에서는 이 조건이 `if`문 다음의 괄호에 있어야 합니다. 다음은 그 예시입니다.

```js
if (condition) {
  // do something if the condition is true
}
```

예시
--

실수가 있을 수 있으니, 모든 괄호를 주의깊게 확인하세요.

```js
if (3 > Math.PI {
  console.log("wait what?");
}

// SyntaxError: missing ) after condition
```

이 코드를 고치기 위해선, 조건문을 괄호로 닫아야 합니다.

```js
if (3 > Math.PI) {
  console.log("wait what?");
}
```

다른 프로그래밍 언어를 배운 경우, JavaScript에서는 다르게 쓰이거나, 쓰이지 않는 키워드를 사용하기 쉽습니다.

```js
if (done is true) {
 console.log("we are done!");
}

// SyntaxError: missing ) after condition
```

이 경우 올바른 비교연산자 (en-US)를 사용해야 합니다. 그 예시로:

```js
if (done === true) {
  console.log("we are done!");
}
```

더 보기
----

* `if...else`
* Comparison operators (en-US)
* Making decisions in your code — conditionals


Map - JavaScript

Map
===

**`Map`** 객체는 키-값 쌍과 키의 원래 삽입 순서를 기억합니다. 모든 값(객체 및
 원시 값 모두)은 키 또는 값으로 사용될 수 있습니다.

시도해보기
-----

설명
--

`Map` 객체는 키-값 쌍인 집합입니다. 한 `Map`에서의 키는 **오직 단 하나만 존재** 합니다. 이는 `Map` 집합의 유일성입니다.
 `Map` 객체는 키-값 쌍으로 반복됩니다. `for...of` 루프는
 각 반복에 대해 `[key, value]`로 이루어진 멤버가 2개인 배열을 반환합니다. 반복은 삽입한 순서대로 발생합니다. 즉,
 `set()` 메서드로 맵에 처음
 삽입한 각각의 키-값 쌍 순서와 대응됩니다. (`set()`이 호출되었을때 맵에서 해당 키가 없었을 경우입니다)

`Map`의 명세는 "평균적으로 집합 내 요소의 수에 따라 하위 선형인 접근 시간을 제공하는" 맵을 구현해야 한다고 기술되어 있습니다.
 따라서 복잡성이 O(N)보다 더 나은 경우 내부적으로 해시 테이블(O(1) 룩업), 검색 트리(O(log(N)) 룩업) 또는 기타 데이터
 구조로 표현될 수 있습니다.

### 키 동일성

 값 동일성은 `SameValueZero`을
 기반으로 합니다.(`0`과 `-0`을 다르게 취급하는 등가 같음을
 사용하였습니다. 브라우저 호환성을 확인해보세요). 즉, `NaN !== NaN`에도 불구하고
 `NaN`은 `NaN`과 동일하게 간주되며, 다른 모든 값은 `===` 연산자의 의미론에 따라 동일하게 간주됩니다.

### 객체 vs 맵

`Object`는 `Map`과 유사합니다. 둘 다 값을 가리키는 키를 설정하고, 해당 값을 받아오며, 키를 삭제하며,
 키에 무언가가 저장되었는지 여부를 알 수 있습니다. 이러한 이유로 (그리고 대안으로 사용할 수 있는 내장 객체가 없었기 때문에)
 `Object`는 역사적으로 `Map`으로 사용되어 왔습니다.

그러나 경우에 따라서는 아래와 같이 `Map`이 선호되는 중요한 차이점이 있습니다.

|  | Map | Object |
| --- | --- | --- |
| 우발적 키 | `Map`는 기본적으로 키를 포함하지 않습니다. 여기에는 명시적으로 입력된 내용만 포함됩니다. | `Object`는 프로토타입이 있으므로 주의하지 않으면 자신의 키와 충돌할 수 있는 기본 키가 포함되어 있습니다.

**참고:**
 이는 `Object.create(null)`를 사용하여 무시할 수 있지만 거의 수행되지 않습니다.

 |
| 보안 | `Map`은 사용자가 제공하는 키와 값에 대해서 안전하게 사용할 수 있습니다. | 사용자가 제공한 키-값 쌍을 `Object`에 설정하면 공격자가 객체의 프로토타입을 재정의하여 객체 주입 공격을 발생시킬 수 있습니다. 돌발적인 키 문제와 마찬가지로 `null` 프로토타입 객체를 사용하여 이 문제를 해결할 수도 있습니다. |
| 키 유형 | `Map`의 키는 모든 값(함수, 객체 또는 원시값 포함)이 될 수 있습니다. | `Object`의 키는 `String` 또는 `Symbol`이여야 합니다. |
| 키 순서 | `Map`에서 키는 단순하고 직관적인 방식으로 정렬됩니다. `Map` 객체는 항목을 삽입한 순서대로 항목, 키 및 값을 반복합니다. | 일반적인 `Object`의 키는 정렬되어 있지만 항상 그런것은 아니며 순서가 복잡합니다. 결과적으로 속성 순서에 의존하지 않는 것이 가장 좋습니다.

 순서는 ECMAScript 2015에서만 자체 속성에 대해 처음 정의되었습니다.
 ECMAScript 2020은 상속된 속성의 순서도 정의합니다.
 OrdinaryOwnPropertyKeys
 와
 EnumerateObjectProperties
 추상 명세작업을 참고하시기 바랍니다. 그러나 객체의 **모든** 속성을 반복하는 단일 메커니즘은 없습니다. 다양한 메커니즘에는 각각 다른 속성 하위 집합이 포함됩니다
 (`for-in`은 오직 열거 가능한 문자열 키 속성만 포함합니다.
 `Object.keys`은 열거 가능한 자체 문자열 키 속성만 포함합니다.
 `Object.getOwnPropertyNames`은 열거 불가능하더라도 자체 문자열 키 속성을 포함합니다.
 `Object.getOwnPropertySymbols`은 `Symbol`-키 속성에 대해 동일합니다.)
  |
| 크기 | `Map`의 아이템의 수는 `size` 속성에서 쉽게 가져올 수 있습니다. | `Object`의 아이템 수는 수동으로 결정해야 합니다. |
| 순회 | `Map`은 순회가능(iterable)하기 때문에 이므로 직접 반복할 수 있습니다. |
`Object`는 iteration protocol을 구현하지 않기 때문에
 로 개체는 for...of문을 사용하여 직접적으로 반복할 수 없습니다.

**참고:**
* 객체는 iteration protocol을 구현하거나
 `Object.keys` 혹은
 `Object.entries`
 를 사용하여 객체의 반복 가능 항목을 얻을 수 있습니다.
* for...in 문을 사용하면 객체의 열거 가능한 속성(enumerable)을 반복할 수 있습니다 .

 |
| 성능 | 키-값 쌍의 빈번한 추가 및 제거와 관련된 상황에서는 성능이 좀 더 좋습니다. | 키-값 쌍의 빈번한 추가 및 제거에 최적화되지 않았습니다. |
| Serialization and parsing | 직렬화 또는 구문 분석에 대한 기본 지원이 없습니다.

 (하지만 `JSON.stringify()`에 인자로 *replacer*를 사용한다면 `Map`에 대한 자신만의 직렬화 및 구문 분석을 지원하게 만들 수 있습니다.
 Stack Overflow 질문인
 How do you JSON.stringify an ES6 Map?)을 참고하세요.)
  | `JSON.stringify()`를 사용하여 `Object`을 JSON으로 직렬화를 기본 지원합니다.
`JSON.parse()`를 사용하여 JSON에서 `Object`으로의 구문 분석을 기본 지원합니다. |

### 객체 속성 설정하기

객체 속성 설정은 Map 객체에서도 작동하지만 상당한 혼란을 야기할 수 있습니다.

따라서 이는 다음과 같은 방식으로 동작하는 것처럼 보입니다.

```js
const wrongMap = new Map();
wrongMap["bla"] = "blaa";
wrongMap["bla2"] = "blaaa2";

console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }
```

그러나 속성을 설정하는 방법은 Map 데이터 구조와 상호 작용하지 않습니다. 속성 설정은 일반 객체의 기능을 사용합니다. 'bla' 값은 질의를 위한 Map에 저장되지 않습니다. 데이터에 대한 다른 작업도 아래와 같이 실패합니다.

```js
wrongMap.has("bla"); // false
wrongMap.delete("bla"); // false
console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }
```

맵에 데이터를 저장하는 올바른 방법은 `set(key, value)` 메서드를 사용하는 것입니다.

```js
const contacts = new Map();
contacts.set("Jessie", { phone: "213-555-1234", address: "123 N 1st Ave" });
contacts.has("Jessie"); // true
contacts.get("Hilary"); // undefined
contacts.set("Hilary", { phone: "617-555-4321", address: "321 S 2nd St" });
contacts.get("Jessie"); // {phone: "213-555-1234", address: "123 N 1st Ave"}
contacts.delete("Raymond"); // false
contacts.delete("Jessie"); // true
console.log(contacts.size); // 1
```

생성자
---

`Map()`

새로운 `Map` 객체를 생성합니다.

정적 속성
-----

`get Map[@@species]` (en-US)

파생 객체를 만드는 데 사용되는 생성자 함수입니다.

인스턴스 속성
-------

`Map.prototype[@@toStringTag]`

`@@toStringTag` (en-US)
 속성의 초기 값은 문자열 `"Map"`입니다. 이 속성은 `Object.prototype.toString()`에서
 사용합니다.

`Map.prototype.size`

`Map` 객체의 키/값 쌍의 숫자를 반환합니다.

인스턴스 메서드
--------

`Map.prototype.clear()`

`Map` 객체에서 모든 키-값 쌍을 제거합니다.

`Map.prototype.delete()`

`Map` 객체에 해당 요소가 존재하며 삭제되었을 경우 `true`를 반환하며 해당 요소가 존재하지 않는 경우 `false`를
 반환합니다. 이 이후에 `map.has(key)`를 실행하면 `false`를 반환할 것입니다.

`Map.prototype.get()`

주어진 키에 해당하는 값을 반환하거나 값이 없다면 `undefined`을 반환합니다.

`Map.prototype.has()`

주어진 키에 연관된 값이 `Map` 객체에 존재하는지 여부를 불리언 값으로 반환합니다.

`Map.prototype.set()`

`Map`객체에서 전달된 키의 값을 설정합니다. `Map`객체를 반환합니다.

`Map.prototype[@@iterator]()`

`Map` 객체에 삽입된 순서에 따라 `[key, value]` 두 개의 멤버 배열을 포함하는 새로운 반복자를 반환합니다.

`Map.prototype.keys()`

`Map` 객체에 삽입된 순서에 따라 각 요소의 키를 포함하는 새로운 반복자를 반환합니다.

`Map.prototype.values()`

`Map` 객체에 삽입된 순서에 따라 각 요소의 값을 포함하는 새로운 반복자를 반환합니다.

`Map.prototype.entries()`

`Map` 객체에 삽입된 순서에 따라 `[key, value]` 두 개의 멤버 배열을 포함하는 새로운 반복자를 반환합니다.

`Map.prototype.forEach()`

`Map`객체에 존재하는 각 키-값 쌍에 대해 삽입 순서대로 `callbackFn`을 한 번씩 호출 합니다. 만약
 `forEach`호출 시 `thisArg` 매개변수가 있다면 각 콜백의 `this` 값으로 사용됩니다.

예제
--

### Map 객체 사용하기

```js
const myMap = new Map();

const keyString = "a string";
const keyObj = {};
const keyFunc = function () {};

// 값 설정
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");

console.log(myMap.size); // 3

// 값 불러오기
console.log(myMap.get(keyString)); // "value associated with 'a string'"
console.log(myMap.get(keyObj)); // "value associated with keyObj"
console.log(myMap.get(keyFunc)); // "value associated with keyFunc"

console.log(myMap.get("a string")); // "value associated with 'a string'", 왜냐하면 keyString === 'a string'
console.log(myMap.get({})); // undefined, 왜냐하면 keyObj !== {}
console.log(myMap.get(function () {})); // undefined, 왜냐하면 keyFunc !== function () {}
```

### Map 키로 NaN 사용하기

`NaN`도 키로 사용할 수 있습니다. 모든 `NaN`이 자신과 같지는 않지만(`NaN !== NaN`은 참입니다), `NaN`은 서로 구별할 수 없기 때문에 다음과 같은 예시가 동작합니다.

```js
const myMap = new Map();
myMap.set(NaN, "not a number");

myMap.get(NaN);
// "not a number"

const otherNaN = Number("foo");
myMap.get(otherNaN);
// "not a number"
```

### for...of로 맵 순회하기

맵은 `for...of` 반복을 사용하여 순회할 수 있습니다.

```js
const myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");

for (const [key, value] of myMap) {
  console.log(`${key} = ${value}`);
}
// 0 = zero
// 1 = one

for (const key of myMap.keys()) {
  console.log(key);
}
// 0
// 1

for (const value of myMap.values()) {
  console.log(value);
}
// zero
// one

for (const [key, value] of myMap.entries()) {
  console.log(`${key} = ${value}`);
}
// 0 = zero
// 1 = one
```

### forEach()로 맵 순회하기

맵은 `forEach()` 메서드를 사용하여 순회할 수 있습니다.

```js
myMap.forEach((value, key) => {
  console.log(`${key} = ${value}`);
});
// 0 = zero
// 1 = one
```

### 배열 객체와의 관계

```js
const kvArray = [
  ["key1", "value1"],
  ["key2", "value2"],
];

// Use the regular Map constructor to transform a 2D key-value Array into a map
const myMap = new Map(kvArray);
console.log(myMap.get("key1")); // "value1"

// Use Array.from() to transform a map into a 2D key-value Array
console.log(Array.from(myMap)); // Will show you exactly the same Array as kvArray

// A succinct way to do the same, using the spread syntax
console.log([...myMap]);

// Or use the keys() or values() iterators, and convert them to an array
console.log(Array.from(myMap.keys())); // ["key1", "key2"]
```

### 맵 복제하기와 병합하기

`Array`와 같이 `Map`은 복제가 가능합니다.

```js
const original = new Map([[1, "one"]]);

const clone = new Map(original);

console.log(clone.get(1)); // one
console.log(original === clone); // false (useful for shallow comparison)
```

**참고:** 데이터 자체는 복제가 안된다는 사실을 명심하셔야 합니다.

맵은 키 유일성을 유지한채로 병합이 가능합니다.

```js
const first = new Map([
  [1, "one"],
  [2, "two"],
  [3, "three"],
]);

const second = new Map([
  [1, "uno"],
  [2, "dos"],
]);

// 두 맵을 병합합니다. 키 값이 중복될 경우 마지막 키의 값을 따릅니다.
// 전개 문법은 맵을 배열로 변환합니다.
const merged = new Map([...first, ...second]);

console.log(merged.get(1)); // uno
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three
```

맵은 배열과 병합될 수 있습니다.

```js
const first = new Map([
  [1, "one"],
  [2, "two"],
  [3, "three"],
]);

const second = new Map([
  [1, "uno"],
  [2, "dos"],
]);

// 맵을 배열로 병합하기. 중복된 키가 있다면 마지막에 병합된 맵의 키에 해당하는 값이 설정됩니다.
const merged = new Map([...first, ...second, [1, "eins"]]);

console.log(merged.get(1)); // eins
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-map-objects |

브라우저 호환성
--------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

같이 보기
-----

* `Map`의 폴리필은 `core-js`에서 확인할 수 있습니다
* `Set` (en-US)
* `WeakMap`
* `WeakSet`


Object - JavaScript

Object
======

**`Object`** 클래스는 JavaScript의 데이터 유형 중 하나를 나타냅니다. 다양한 키 모음 및 더 복잡한 엔티티들을 저장하는 데 사용됩니다. 객체는 `Object()` 생성자 또는 객체 초기자 / 리터럴 구문를 통해 생성할 수 있습니다.

설명
--

JavaScript의 거의 모든 객체는 `Object`의 인스턴스입니다. 일반적인 객체는 `Object.prototype`에서 속성(메서드 포함)을 상속하지만, 이러한 속성들은 가려질(재정의될) 수 있습니다. 그러나 `Object`는 의도적으로 가려지지 않게 생성되거나(예: `Object.create(null)`), 더이상 가려지지 않도록 변경될 수 있습니다(예: `Object.setPrototypeOf` (en-US)).

`Object` 프로토타입 객체에 대한 변경 사항은 해당 변경 사항의 대상이 되는 프로토타입 체인상의 속성 및 메서드가 추가로 재정의되지 않는 한 프로토타입 체인을 통해 **모든** 객체에서 볼 수 있습니다. 이것은 객체 동작을 재정의하거나 확장하는 매우 강력하지만 잠재적으로 위험한 메커니즘을 제공합니다.

`Object` 생성자는 주어진 값에 대한 객체 래퍼를 생성합니다.

* 값이 `null` 또는 `undefined`이면 빈 객체를 생성하여 반환합니다.
* 그렇지 않으면 주어진 값에 해당하는 타입의 객체를 반환합니다.
* 값이 이미 객체인 경우 그 값을 반환합니다.

생성자가 아닌 맥락에서 호출될 때 `Object`는 `new Object()`와 동일하게 작동합니다.

객체 초기자 / 리터럴 구문도 참조하세요.

### 객체의 속성 삭제하기

객체 자체에는 속성을 삭제하는 메서드가 없습니다(예: `Map.prototype.delete()`). 삭제하기 위해서는 delete 연산자 (en-US)를 사용해야 합니다.

생성자
---

`Object()`

새 `Object` 객체를 만듭니다. 이 때 생성된 객체는 주어진 값에 대한 래퍼입니다.

정적 메서드
------

`Object.assign()`

하나 이상의 원본 객체들로부터 모든 열거 가능한 속성들을 대상 객체로 복사합니다.

`Object.create()`

지정한 프로토타입(prototype)의 객체 및 속성을 갖고 있는 새 객체를 생성합니다.

`Object.defineProperty()`

지정한 서술자(descriptor)에서 서술한 속성을 객체에 추가합니다.

`Object.defineProperties()`

지정한 서술자들에서 서술한 속성들을 객체에 추가합니다.

`Object.entries()`

지정한 객체 **자신의** 모든 열거 가능한 문자열 속성들의 `[key, value]` 쌍으로 구성된 배열을 반환합니다.

`Object.freeze()`

객체를 고정(freeze)합니다. 다른 곳의 코드에서 해당 속성을 삭제하거나 변경할 수 없게 됩니다.

`Object.fromEntries()`

`[key, value]` 쌍의 iterable로부터 새 객체를 반환합니다. (`Object.entries`의 반대입니다.)

`Object.getOwnPropertyDescriptor()`

객체의 지정한 속성에 대한 속성 서술자를 반환합니다.

`Object.getOwnPropertyDescriptors()`

객체 자신의 모든 속성 서술자들로 구성된 객체를 반환합니다.

`Object.getOwnPropertyNames()`

지정한 객체 **자신의** 모든 열거 가능하거나 불가능한 속성들의 이름으로 구성된 배열을 반환합니다.

`Object.getOwnPropertySymbols()`

지정한 객체 자신의 모든 심볼 속성들로 구성된 배열을 반환합니다.

`Object.getPrototypeOf()`

지정한 객체의 프로토타입(내부 `[[Prototype]]` 속성)을 반환합니다.

`Object.is()`

두 값이 같은지를 비교합니다. 모든 `NaN` 값을 같다고 처리합니다. (추상 동등 비교 및 엄격한 동등 비교와 다른 점입니다.)

`Object.isExtensible()`

객체의 확장이 가능한지 여부를 확인합니다.

`Object.isFrozen()`

객체가 고정(freeze)되었는지 여부를 확인합니다.

`Object.isSealed()`

객체가 봉인(seal)되었는지 여부를 확인합니다.

`Object.keys()`

지정한 객체 **자신의** 모든 열거 가능한 문자열 속성들의 이름으로 구성된 배열을 반환합니다.

`Object.preventExtensions()`

객체가 확장되지 못하도록 합니다.

`Object.seal()`

다른 코드가 객체의 속성을 삭제하지 못하도록 합니다.

`Object.setPrototypeOf()` (en-US)

객체의 프로토타입(내부 `[[Prototype]]` 속성)을 설정합니다.

`Object.values()`

지정한 객체 **자신의** 모든 열거 가능한 문자열 속성에 해당하는 값들로 구성된 배열을 반환합니다.

인스턴스 속성
-------

`Object.prototype.constructor`

객체의 프로토타입을 생성하는 함수를 지정합니다.

`Object.prototype.__proto__`

객체가 인스턴스화될 때 프로토타입으로 사용된 객체를 가리킵니다.

인스턴스 메서드
--------

`Object.prototype.__defineGetter__()`

액세스(get)할 때 실행되어 값을 반환하는 함수와 지정한 속성을 연결합니다.

`Object.prototype.__defineSetter__()` (en-US)

설정(set)할 때 실행되어 해당 속성을 수정하는 함수와 지정한 속성을 연결합니다.

`Object.prototype.__lookupGetter__()` (en-US)

`Object.prototype.__defineGetter__()` 메서드에 의해 지정된 속성과 연결된 함수를 반환합니다.

`Object.prototype.__lookupSetter__()` (en-US)

`Object.prototype.__defineSetter__()` (en-US) 메서드에 의해 지정된 속성과 연결된 함수를 반환합니다.

`Object.prototype.hasOwnProperty()` (en-US)

객체에 지정한 속성이 해당 객체에 직접 포함되어 있고 프로토타입 체인을 통해 상속되지 않는지 여부를 나타내는 불리언 값을 반환합니다.

`Object.prototype.isPrototypeOf()`

이 메서드를 호출한 객체가 지정한 객체의 프로토타입 체인에 있는지 여부를 나타내는 불리언 값을 반환합니다.

`Object.prototype.propertyIsEnumerable()`

내부 ECMAScript [[Enumerable]] 속성이 설정되었는지 여부를 나타내는 불리언 값을 반환합니다.

`Object.prototype.toLocaleString()`

`toString()`를 호출합니다.

`Object.prototype.toString()`

객체의 문자열 표현을 반환합니다.

`Object.prototype.valueOf()`

지정한 객체의 원시 값을 반환합니다.

예제
--

### `undefined` 및 `null` 타입을 지정한 `Object` 사용

다음 예제는 변수 `o`에 빈 `Object` 객체를 저장합니다.

```js
let o = new Object();
```

```js
let o = new Object(undefined);
```

```js
let o = new Object(null);
```

### `Object`로 `Boolean` 객체 생성하기

다음 예제는 변수 `o`에 `Boolean` 객체를 저장합니다.

```js
// o = new Boolean(true) 와 같음
let o = new Object(true);
```

```js
// o = new Boolean(false) 와 같음
let o = new Object(Boolean());
```

### 객체 프로토타입

기존 `Object.prototype` 메서드의 동작을 변경하고자 할 때에는 기존 내용의 앞이나 뒤에 확장할 내용을 래핑하여 코드를 주입하는 것을 고려하세요. 예를 들어, 이 (테스트되지 않은) 코드는 기본 제공 코드 또는 다른 사람의 확장 실행되기 전에 사전 조건부로 사용자 정의 코드를 실행합니다.

함수가 호출되면 호출에 대한 매개변수가 유사배열 "변수" arguments 객체에 보관됩니다. 예를 들어, `myFn(a, b, c)`를 호출하면 `myFn` 본문 내의 arguments 객체에는 `(a, b, c)`에 해당하는 3개의 유사배열요소가 포함됩니다.

hook을 통해 프로토타입을 수정하고자 할 때엔 해당 함수에서 `apply()`를 호출하면서 `this`와 arguments 객체를 현재 동작에 전달합니다. 이 패턴은 `Node.prototype`, `Function.prototype` 등 모든 프로토타입에 적용할 수 있습니다.

```js
var current = Object.prototype.valueOf;

// 내가 지정한 속성 "-prop-value"은 범분야에 걸쳐 사용되고 있고
// 항상 동일한 프로토타입 체인에 있지 않기 때문에, Object.prototype을 수정하고 싶습니다.
Object.prototype.valueOf = function () {
  if (this.hasOwnProperty("-prop-value")) {
    return this["-prop-value"];
  } else {
    // 내가 만든 객체가 아닌 것 같으므로,
    // 가능한 최선을 다해 원래의 동작을 재현하여 기본 동작으로 돌아가겠습니다.
    // 'apply' 메서드는 다른 언어에서의 'super'처럼 작동합니다.
    // valueOf()가 arguments를 취하지 않더라도, 다른 hook이 있으리라 생각합니다.
    return current.apply(this, arguments);
  }
};
```

JavaScript에는 명확한 하위 클래스 객체가 없기 때문에, 프로토타입은 특정 기능의 "기본 클래스" 객체를 만드는 데 유용한 해결 방법입니다. 예를 들어:

```js
var Person = function (name) {
  this.name = name;
  this.canTalk = true;
};
Person.prototype.greet = function () {
  if (this.canTalk) {
    console.log("Hi, I am " + this.name);
  }
};

var Employee = function (name, title) {
  Person.call(this, name);
  this.title = title;
};

Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee; // Object.prototype.constructor를 Employee로 설정하지 않으면
// Person (parent)의 prototype.constructor를 사용합니다.
// 이를 피하기 위해 prototype.constructor를 Employee (child)로 설정합니다.
Employee.prototype.greet = function () {
  if (this.canTalk) {
    console.log("Hi, I am " + this.name + ", the " + this.title);
  }
};

var Customer = function (name) {
  Person.call(this, name);
};

Customer.prototype = Object.create(Person.prototype);
Customer.prototype.constructor = Customer; // Object.prototype.constructor를 Customer로 설정하지 않으면
// Person (parent)의 prototype.constructor를 사용합니다.
// 이를 피하기 위해 prototype.constructor를 Customer (child)로 설정합니다.

var Mime = function (name) {
  Person.call(this, name);
  this.canTalk = false;
};

Mime.prototype = Object.create(Person.prototype);
Mime.prototype.constructor = Mime; // Object.prototype.constructor를 Mime로 설정하지 않으면
// Person (parent)의 prototype.constructor를 사용합니다.
// 이를 피하기 위해 prototype.constructor를 Mime (child)로 설정합니다.

var bob = new Employee("Bob", "Builder");
var joe = new Customer("Joe");
var rg = new Employee("Red Green", "Handyman");
var mike = new Customer("Mike");
var mime = new Mime("Mime");

bob.greet();
// Hi, I am Bob, the Builder

joe.greet();
// Hi, I am Joe

rg.greet();
// Hi, I am Red Green, the Handyman

mike.greet();
// Hi, I am Mike

mime.greet();
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object-objects |

브라우저 호환성
--------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

같이 보기
-----

* 객체 초기자


Array - JavaScript

Array
=====

다른 프로그래밍 언어의 배열과 마찬가지로, **`Array`** 객체는 여러 항목의 컬렉션을 단일 변수 이름 아래 저장할 수 있고, 일반적인 배열 연산을 수행하기 위한 멤버가 있습니다.

설명
--

JavaScript에서 배열은 원시 값이 아니라 다음과 같은 핵심적인 특성을 가진 `Array` 객체입니다.

* **JavaScript 배열은 크기를 조정이 가능하고, 다양한 데이터 형식을 혼합하여 저장할 수 있습니다**. (이러한 특성이 바람직하지 않은 경우라면, 형식화 배열을 대신 사용하세요.)
* **JavaScript 배열은 연관 배열이 아니므로** 임의의 문자열을 인덱스로 사용하여 배열 요소에 접근할 수 없습니다. 하지만, 음수가 아닌 정수(또는 해당 수의 문자열 형식)를 인덱스로 사용하여 접근해야 합니다.
* **JavaScript 배열은 0 인덱스**입니다. 배열의 첫 번째 요소는 인덱스 `0`, 두 번째 요소는 인덱스 `1`, 마지막 요소는 배열의 `length` 속성 값에서 1을 뺀 값에 위치합니다.
* **JavaScript 배열 복사 연산은 얕은 복사본을 생성합니다**. (모든 JavaScript 객체의 모든 표준 내장 복사 연산은 깊은 복사본이 아닌 얕은 복사본을 생성합니다).
### 배열 인덱스

`Array` 객체는 (연관 배열에서처럼) 임의의 문자열을 요소 인덱스로 사용할 수 없으며 음수가 아닌 정수(또는 해당 수의 문자열 형식)를 사용해야 합니다. 정수가 아닌 것을 통해 배열의 요소를 설정하거나 접근하려고 하면, 배열 목록 자체에서 요소를 설정하거나 검색하는 것이 아니라 해당 배열의 객체 속성 컬렉션과 연결된 변수를 설정하거나 접근하게 됩니다. 배열의 객체 속성과 배열의 요소 목록은 별개이며, 배열의 순회 및 수정 연산은 이렇게 이름 붙여진 속성에 적용할 수 없습니다.

배열 요소는 `toString`이 속성인 것과 같은 방식으로 객체 속성입니다(하지만, 정확히 말하자면 `toString()`은 메서드입니다). 그럼에도 불구하고 다음과 같이 배열의 요소에 접근하려고 하면 속성 이름이 유효하지 않기 때문에 구문 오류가 발생합니다.

```js
arr.0; // 구문 오류
```

JavaScript 구문에서 숫자로 시작하는 속성은 점 표기법 대신 대괄호 표기법을 사용하여 접근해야 합니다. 배열 인덱스를 따옴표로 묶을 수도 있지만 (예: `years[2]` 대신 `years['2']`), 일반적으로는 필요하지 않습니다.

`years[2]`의 `2`는 JavaScript 엔진에 의해 암시적 `toString` 변환을 통해 문자열로 강제 변환됩니다. 결과적으로 `'2'`와 `'02'`는 `years` 객체에서 서로 다른 두 개의 슬롯을 참조하게 되며, 다음 예제는 `true` 일 수 있습니다.

```js
console.log(years["2"] !== years["02"]);
```

`years['2']`만이 실제 배열 인덱스입니다. `years['02']`는 배열 순회에서 방문되지 않는 임의의 문자열 속성입니다.

### length와 숫자 속성의 관계

JavaScript 배열의 `length` 속성과 숫자 속성은 연결되어 있습니다.

내장 배열 메서드 중 일부(예: `join()`, `slice()`, `indexOf()` 등)는 호출 시 배열의 `length` 속성 값을 고려합니다.

다른 메서드(예: `push()`, `splice()` 등)도 배열의 `length` 속성을 갱신합니다.

```js
const fruits = [];
fruits.push("banana", "apple", "peach");
console.log(fruits.length); // 3
```

속성이 유효한 배열 인덱스이고 해당 인덱스가 배열의 현재 범위를 벗어날 때 JavaScript 배열에 속성을 설정하면, 엔진은 배열의 `length` 속성을 적절히 갱신합니다.

```js
fruits[5] = "mango";
console.log(fruits[5]); // 'mango'
console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
console.log(fruits.length); // 6
```

`length`를 늘리면 새 요소를 만들지 않고 빈 슬롯을 추가하여 배열을 확장할 수 있습니다. `undefined`가 아닙니다.

```js
fruits.length = 10;
console.log(fruits); // ['banana', 'apple', 'peach', empty x 2, 'mango', empty x 4]
console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
console.log(fruits.length); // 10
console.log(fruits[8]); // undefined
```

그러나 `length` 속성을 줄이면 요소가 삭제됩니다.

```js
fruits.length = 2;
console.log(Object.keys(fruits)); // ['0', '1']
console.log(fruits.length); // 2
```

`length` 페이지에서 더 자세히 설명하겠습니다.

### 배열 메서드와 빈 슬롯

희소 배열의 빈 슬롯은 배열 메서드 간에 일관성 없이 동작합니다. 일반적으로 오래된 메서드는 빈 슬롯을 건너뛰는 반면, 최신 메서드는 빈 슬롯을 `undefined`로 처리합니다.

여러 요소를 순회하는 메서드 중, 다음은 인덱스에 접근하기 전에 `in` 확인을 수행하여 빈 슬롯을 `undefined`로 취급하지 않습니다.

* `concat()`
* `copyWithin()`
* `every()`
* `filter()`
* `flat()`
* `flatMap()`
* `forEach()`
* `indexOf()`
* `lastIndexOf()`
* `map()`
* `reduce()`
* `reduceRight()`
* `reverse()`
* `slice()`
* `some()`
* `sort()`
* `splice()`

빈 슬롯을 정확히 어떻게 처리하는지는 각 메서드의 페이지를 참조하세요.

아래 메서드는 빈 슬롯을 `undefined`로 취급합니다.

* `entries()`
* `fill()`
* `find()`
* `findIndex()`
* `findLast()`
* `findLastIndex()`
* `includes()`
* `join()`
* `keys()`
* `toLocaleString()`
* `values()`
### 복사 메서드와 변경 메서드(mutating method)

일부 메서드는 메서드가 호출된 기존 배열을 변경하지 않는 대신, 새 배열을 반환합니다. 이러한 메서드는 먼저 새 배열을 구성한 다음 요소를 채우는 방식으로 수행됩니다. 복사는 항상 얕게 이루어지며, 메서드는 처음에 생성된 배열 이외에는 아무것도 복사하지 않습니다. 원래 배열의 요소는 다음과 같이 새 배열에 복사됩니다

* 객체: 객체 참조가 새 배열로 복사됩니다. 원래 배열과 새 배열 모두 동일한 객체를 참조합니다. 즉, 참조된 객체가 수정되면 변경 사항이 새 배열과 원래 배열 모두에 표시됩니다.
* 문자열, 숫자, 불리언과 같은 원시 유형(`String`, `Number`, `Boolean` 객체 아님): 해당 값이 새 배열에 복사됩니다.

어떤 메서드는 메서드가 호출된 배열을 변경하며, 이 경우 반환값은 메서드에 따라 다릅니다. 때로는 같은 배열에 대한 참조를 반환하고, 때로는 새 배열의 길이를 반환합니다.

다음 메서드는 `this.constructor[Symbol.species]`에 접근하여 사용할 생성자를 결정하고 새 배열을 생성합니다.

* `concat()`
* `filter()`
* `flat()`
* `flatMap()`
* `map()`
* `slice()`
* `splice()` (반환되는 제거된 요소의 배열을 구성하기 위해)

다음 메서드는 항상 `Array` 기본 생성자를 사용하여 새 배열을 생성합니다.

* `toReversed()`
* `toSorted()`
* `toSpliced()`
* `with()`

아래 표에는 원래 배열을 변경하는 메서드와 그에 상응하는 무변경 대체 메서드가 나열되어 있습니다.

| 변경 메서드 | 무변경 메서드 |
| --- | --- |
| `copyWithin()` | 단일 메서드 대안 없음 |
| `fill()` | 단일 메서드 대안 없음 |
| `pop()` | `slice(0, -1)` |
| `push(v1, v2)` | `concat([v1, v2])` |
| `reverse()` | `toReversed()` |
| `shift()` | `slice(1)` |
| `sort()` | `toSorted()` |
| `splice()` | `toSpliced()` |
| `unshift(v1, v2)` | `toSpliced(0, 0, v1, v2)` |

변경 메서드를 무변경 대체 메서드로 변경하는 쉬운 방법은 전개 구문 또는 `slice()`를 사용하여 먼저 복사본을 만드는 것입니다.

```js
arr.copyWithin(0, 1, 2); // arr을 변경함
const arr2 = arr.slice().copyWithin(0, 1, 2); // arr을 변경하지 않음
const arr3 = [...arr].copyWithin(0, 1, 2); // arr을 변경하지 않음
```

### 순회 메서드

많은 배열 메서드는 콜백 함수를 인수로 받습니다. 콜백 함수는 배열의 각 요소에 대해 순차적으로 최대 한 번만 호출되며, 콜백 함수의 반환값은 메서드의 반환값을 결정하는 데 사용됩니다. 이들은 모두 같은 모습을 공유합니다.

```js
method(callbackFn, thisArg)
```

여기서 `callbackFn`은 세 개의 인수를 받습니다.

`element`

배열에서 현재 처리 중인 요소입니다.

`index`

배열에서 현재 처리 중인 요소의 인덱스입니다.

`array`

메서드가 호출된 배열입니다.

`callbackFn`이 반환할 것으로 예상되는 것은 호출된 배열 메서드에 따라 다릅니다.

`callbackFn`을 호출할 때 `thisArg` 인자(기본값은 `undefined`)는 `this` 값이 사용됩니다. `callbackFn`이 최종적으로 관찰할 수 있는 `this` 값은 일반적인 규칙에 따라 결정됩니다. `callbackFn`이 비엄격이라면, 원시 `this` 값은 객체로 래핑되고, `undefined`/`null`은 `globalThis`로 대체됩니다. 화살표 함수에는 자체 `this` 바인딩이 없으므로 `thisArg` 인자는 화살표 함수로 정의된 `callbackFn`과 관련이 없습니다.

모든 순회 메서드는 복사와 범용 메서드 이지만, 빈 슬롯에서는 다르게 동작합니다.

다음 메서드는 순회 메서드입니다.

* `every()`
* `filter()`
* `find()`
* `findIndex()`
* `findLast()`
* `findLastIndex()`
* `flatMap()`
* `forEach()`
* `map()`
* `some()`

특히, `every()`, `find()`, `findIndex()`, `findLast()`, `findLastIndex()`, `some()`는 모든 요소에 대해 항상 `callbackFn`을 호출하는 것이 아니라, 반환 값이 결정되는 즉시 순회를 중지합니다.

콜백 함수를 받아 배열의 각 요소에 대해 최대 한 번만 실행하는 다른 두 가지 메서드가 있지만, 일반적인 순회 메서드와는 약간 다른 모습을 가집니다(예: `thisArg`를 허용하지 않음).

* `reduce()`
* `reduceRight()`

`sort()` 메서드도 콜백 함수를 받지만, 순회 메서드는 아닙니다. 이 메서드는 배열을 제자리에서 변경하고, `thisArg`를 허용하지 않으며, 한 인덱스에서 콜백을 여러 번 호출할 수 있습니다.

### 범용 배열 메서드

배열 메서드는 항상 범용적이고, 이는 배열 객체의 내부 데이터에 접근하지 않습니다. `length` 속성과 인덱스된 요소를 통해서만 배열 요소에 접근합니다. 즉, 유사 배열 객체에서도 이 메서드를 호출할 수 있습니다.

```js
const arrayLike = {
  0: "a",
  1: "b",
  length: 2,
};
console.log(Array.prototype.join.call(arrayLike, "+")); // 'a+b'
```

#### length 속성 일반화

`length` 속성은 정수로 변환된 다음 0에서 253 - 1 사이의 범위로 고정됩니다. `NaN`은 `0`이 되므로, `length`가 없거나 `undefined`인 경우에도 `0` 값이 있는 것처럼 동작합니다.

이 언어는 `length`를 안전하지 않은 정수로 설정하지 못하도록 합니다. 모든 내장 메서드는 `length`가 253 - 1보다 큰 숫자로 설정될 때 `TypeError`를 발생시킵니다. 그러나 배열의 `length` 속성이 232 - 1보다 큰 값으로 설정되면 오류가 발생하기 때문에 배열이 아닌 객체에서 메서드를 호출하지 않는 한 일반적으로 안전한 정수 임곗값에 도달하지 못합니다.

```js
Array.prototype.flat.call({}); // []
```

일부 배열 메서드는 배열 객체의 `length` 속성을 설정합니다. 이러한 메서드는 항상 일반화한 후 값을 설정하므로 `length`는 항상 정수로 끝납니다.

```js
const a = { length: 0.7 };
Array.prototype.push.call(a);
console.log(a.length); // 0
```

#### 유사 배열 객체

유사 배열 객체라는 용어는 위에서 설명한 `length` 변환 프로세스 중에 오류가 발생하지 않는 모든 객체를 의미합니다. 실제로 이러한 객체는 정말 `length` 속성을 가지며, `0`에서 `length - 1` 범위의 인덱스 요소를 가질 것으로 예상됩니다. (모든 인덱스가 없는 경우, 기능적으로 희소 배열과 동일합니다.) 배열 메서드가 유사 배열 객체에서 작동할 때 `0`보다 작거나 `length - 1`보다 큰 정수의 인덱스는 무시됩니다.

많은 DOM 객체는 유사 배열입니다(예: `NodeList`와 `HTMLCollection`). `arguments` 객체도 유사 배열입니다. 유사 배열에 배열 메서드가 없더라도 배열 메서드를 호출할 수 있습니다.

```js
function f() {
  console.log(Array.prototype.join.call(arguments, "+"));
}

f("a", "b"); // 'a+b'
```

생성자
---

`Array()`

새 `Array` 객체를 생성합니다.

정적 속성
-----

`Array[@@species]`

`Array` 생성자를 반환합니다.

정적 메서드
------

`Array.from()`

순회 가능 또는 유사 배열 객체에서 새 `Array`인스턴스를 생성합니다.

`Array.fromAsync()`

비동기 순회 가능, 순회 가능, 또는 유사 배열 객체에서 새 `Array` 인스턴스를 생성합니다.

`Array.isArray()`

인자가 배열이면 `true`를 반환하고, 그렇지 않으면 `false`를 반환합니다.

`Array.of()`

인자의 개수나 유형에 관계없이 가변적인 수의 인자를 가진 새 `Array` 인스턴스를 생성합니다.

인스턴스 속성
-------

아래 속성은 `Array.prototype`에 정의되며 모든 `Array` 인스턴스에서 공유됩니다.

`Array.prototype.constructor`

인스턴스 객체를 생성한 생성자 함수입니다. `Array` 인스턴스의 경우, 초기 값은 `Array` 생성자입니다.

`Array.prototype[@@unscopables]`

ES2015 버전 이전의 ECMAScript 표준에 포함되지 않았으며 `with` (en-US) 문 바인딩 목적으로 무시되는 속성 이름을 포함합니다.

아래 속성은 각 `Array` 인스턴스의 고유 속성입니다.

`length`

배열 요소의 개수를 반영합니다.

인스턴스 메서드
--------

`Array.prototype.at()`

주어진 인덱스에 있는 배열의 항목을 반환합니다. 마지막 항목부터 셀 수 있는 음의 정수를 허용합니다.

`Array.prototype.concat()`

다른 배열 및/또는 값과 결합된 호출 배열인 새 배열을 반환합니다.

`Array.prototype.copyWithin()`

배열 내의 배열 요소 시퀀스를 복사합니다.

`Array.prototype.entries()`

배열의 각 인덱스에 대한 키/값 쌍을 포함하는 새 배열 반복자 객체를 반환합니다.

`Array.prototype.every()`

호출 배열의 모든 요소가 테스트 함수를 만족하면 `true`를 반환합니다.

`Array.prototype.fill()`

시작 인덱스부터 끝 인덱스까지 배열의 모든 요소를 고정된 값으로 채웁니다.

`Array.prototype.filter()`

제공된 필터링 함수가 `true`를 반환하는 호출 배열의 모든 요소를 포함하는 새 배열을 반환합니다.

`Array.prototype.find()`

제공된 테스트 함수를 만족하는 배열의 첫 번째 요소의 값을 반환하고, 적절한 요소를 찾을 수 없으면 `undefined`를 반환합니다.

`Array.prototype.findIndex()`

제공된 테스트 함수를 만족하는 배열의 첫 번째 요소의 인덱스를 반환하고, 적절한 요소를 찾을 수 없으면 `-1`을 반환합니다.

`Array.prototype.findLast()`

제공된 테스트 함수를 만족하는 배열의 마지막 요소의 값을 반환하고, 적절한 요소를 찾을 수 없으면 `undefined`를 반환합니다.

`Array.prototype.findLastIndex()`

제공된 테스트 함수를 만족하는 배열의 마지막 요소의 인덱스를 반환하고, 적절한 요소를 찾을 수 없는 경우 `-1`을 반환합니다.

`Array.prototype.flat()`

지정된 깊이까지 재귀적으로 연결된 모든 하위 배열 요소가 포함된 새 배열을 반환합니다.

`Array.prototype.flatMap()`

호출 배열의 각 요소에 지정된 콜백 함수를 적용한 다음 결과를 한 단계씩 평탄화하여 만들어진 새 배열을 반환합니다.

`Array.prototype.forEach()`

호출 배열의 각 요소로 함수를 호출합니다.

`Array.prototype.includes()`

호출하는 배열에 값이 포함되어 있는지 여부를 판단하여 적절하게 `true`나`false`를 반환합니다.

`Array.prototype.indexOf()`

호출 배열에서 지정된 요소를 찾을 수 있는 첫 번째(최소) 인덱스를 반환합니다.

`Array.prototype.join()`

배열의 모든 요소를 문자열로 결합합니다.

`Array.prototype.keys()`

호출 배열의 각 인덱스에 대한 키를 포함하는 새 배열 반복자를 반환합니다.

`Array.prototype.lastIndexOf()`

호출 배열에서 지정된 요소를 찾을 수 있는 마지막(가장 큰) 인덱스를 반환하고, 찾을 수 없는 경우 `-1`을 반환합니다.

`Array.prototype.map()`

호출 배열의 모든 요소에 함수를 호출한 결과를 포함하는 새 배열을 반환합니다.

`Array.prototype.pop()`

배열에서 마지막 요소를 제거하고 해당 요소를 반환합니다.

`Array.prototype.push()`

배열 끝에 하나 이상의 요소를 추가하고, 배열의 새 `length`를 반환합니다.

`Array.prototype.reduce()`

배열의 각 요소(왼쪽에서 오른쪽으로)에 대해 사용자가 제공한 "리듀서" 콜백 함수를 실행하여 하나의 값으로 줄입니다.

`Array.prototype.reduceRight()`

배열의 각 요소(오른쪽에서 왼쪽으로)에 대해 사용자가 제공한 "리듀서" 콜백 함수를 실행하여 하나의 값으로 줄입니다.

`Array.prototype.reverse()`

배열 요소의 순서를 반대로 바꿉니다. (첫 번째가 마지막이 되고, 마지막이 첫 번째가 됩니다.)

`Array.prototype.shift()`

배열에서 첫 번째 요소를 제거하고 해당 요소를 반환합니다.

`Array.prototype.slice()`

호출 배열의 구획을 추출하고 새 배열을 반환합니다.

`Array.prototype.some()`

호출 배열의 요소 중 하나 이상이 제공된 테스트 함수를 만족하면 `true`를 반환합니다.

`Array.prototype.sort()`

배열의 요소를 제자리 정렬하고 배열을 반환합니다.

`Array.prototype.splice()`

배열에서 요소를 추가 및/또는 제거합니다.

`Array.prototype.toLocaleString()`

호출 배열과 그 요소를 나타내는 지역화된 문자열을 반환합니다. `Object.prototype.toLocaleString()` 메서드를 재정의합니다.

`Array.prototype.toReversed()`

원래 배열을 수정하지 않고, 요소가 역순으로 배열된 새 배열을 반환합니다.

`Array.prototype.toSorted()`

원래 배열을 수정하지 않고, 오름차순으로 정렬된 요소가 있는 새 배열을 반환합니다.

`Array.prototype.toSpliced()`

원래 배열을 수정하지 않고, 지정된 인덱스에서 일부 요소를 제거 및/또는 교체한 새 배열을 반환합니다.

`Array.prototype.toString()`

호출 배열과 그 요소를 나타내는 문자열을 반환합니다. `Object.prototype.toString()` 메서드를 재정의합니다.

`Array.prototype.unshift()`

배열 앞쪽에 하나 이상의 요소를 추가하고, 배열의 새 `length`를 반환합니다.

`Array.prototype.values()`

배열의 각 인덱스의 값을 포함하는 새 배열 순회자 객체를 반환합니다.

`Array.prototype.with()`

원래 배열을 수정하지 않고, 지정된 인덱스의 요소를 지정된 값으로 바꾼 새 배열을 반환합니다.

`Array.prototype[@@iterator]()`

기본적으로 `values()` 메서드의 별칭입니다.

예제
--

이 구획은 JavaScript에서 흔히 사용되는 배열 연산에 대한 몇 가지 예제를 제공합니다.

**참고:** 배열의 기초가 아직 익숙하지 않다면, 먼저 JavaScript 첫걸음: 배열을 읽어보세요. 이곳은 배열이 무엇인지 설명하고 일반적인 배열 연산에 대한 다른 예제를 포함하고 있습니다.

### 배열 만들기

이 예제는 먼저 배열 리터럴 표기법을 사용하고, 다음은 `Array()` 생성자를 사용하고, 마지막으로 문자열에서 배열을 생성하는 `String.prototype.split()`을 사용하여 새 배열을 만드는 세 가지 방법을 보여 줍니다.

```js
// 배열 리터럴 표기법을 사용하여 'fruits' 배열을 만듭니다.
console.log(fruits.length);
// 2

// Array() 생성자를 사용하여 'fruits2' 배열을 만듭니다.
const fruits2 = new Array("Apple", "Banana");
console.log(fruits2.length);
// 2

// String.prototype.split()을 사용하여 'fruits3' 배열을 만듭니다.
const fruits3 = "Apple, Banana".split(", ");
console.log(fruits3.length);
// 2
```

### 배열에서 문자열 만들기

이 예제에서는 `join()` 메서드를 사용하여 `fruits` 배열로 문자열을 만듭니다.

```js
const fruits = ["Apple", "Banana"];
const fruitsString = fruits.join(", ");
console.log(fruitsString);
// "Apple, Banana"
```

### 배열 인덱스로 항목에 접근하기

이 예제는 배열에서 해당 위치의 인덱스 번호를 지정하여 `fruits` 배열 항목에 접근하는 방법을 보여 줍니다.

```js
const fruits = ["Apple", "Banana"];

// 배열의 첫 번째 요소의 인덱스는 항상 0입니다.
fruits[0]; // Apple

// 배열의 두 번째 요소의 인덱스는 항상 1입니다.
fruits[1]; // Banana

// 배열의 마지막 요소의 인덱스는 항상
// 배열의 길이보다 1 작습니다.
fruits[fruits.length - 1]; // Banana

// 배열의 길이볻 큰 인덱스를 사용하면
// undefined가 반환됩니다.
fruits[99]; // undefined
```

### 배열에서 항목의 인덱스 찾기

이 예제는 `indexOf()` 메서드를 사용하여 `fruits` 배열에서 문자열 `"Banana"`의 위치(인덱스)를 찾습니다.

```js
const fruits = ["Apple", "Banana"];
console.log(fruits.indexOf("Banana"));
// 1
```

### 배열에 특정 항목이 포함되어 있는지 확인

이 예제는 `fruits` 배열에 `"Banana"`와 `"Cherry"`가 포함되어 있는지 확인하는 두 가지 방법을 보여줍니다. 먼저 `includes()` 메서드를 사용한 다음, `indexOf()` 메서드를 사용하여 인덱스가 `-1`이 아닌지 테스트합니다.

```js
const fruits = ["Apple", "Banana"];

fruits.includes("Banana"); // true
fruits.includes("Cherry"); // false

// indexOf()가 -1을 반환하지 않으면 배열에 지정된 항목이 포함되어 있습니다.
fruits.indexOf("Banana") !== -1; // true
fruits.indexOf("Cherry") !== -1; // false
```

### 배열에 항목 추가하기

이 예제는 `push()` 메서드를 사용하여 `fruits` 배열에 새 문자열을 추가합니다.

```js
const fruits = ["Apple", "Banana"];
const newLength = fruits.push("Orange");
console.log(fruits);
// ["Apple", "Banana", "Orange"]
console.log(newLength);
// 3
```

### 배열에서 마지막 항목 제거하기

이 예제는 `pop()` 메서드를 사용하여 `fruits` 배열에서 마지막 항목을 제거합니다.

```js
const fruits = ["Apple", "Banana", "Orange"];
const removedItem = fruits.pop();
console.log(fruits);
// ["Apple", "Banana"]
console.log(removedItem);
// Orange
```

**참고:** `pop()`은 배열에서 마지막 항목을 제거하는 데에만 사용할 수 있습니다. 배열의 끝에서 여러 항목을 제거하려면 다음 예제를 참조하세요.

### 배열의 끝에서 여러 항목 제거하기

이 예제는 `splice()` 메서드를 사용하여 `fruits` 배열에서 마지막 3개 항목을 제거합니다.

```js
const fruits = ["Apple", "Banana", "Strawberry", "Mango", "Cherry"];
const start = -3;
const removedItems = fruits.splice(start);
console.log(fruits);
// ["Apple", "Banana"]
console.log(removedItems);
// ["Strawberry", "Mango", "Cherry"]
```

### 배열을 처음 N개의 항목으로만 잘라내기

이 예제는 `splice()` 메서드를 사용하여 `fruits` 배열을 처음 두 항목으로만 잘라냅니다.

```js
const fruits = ["Apple", "Banana", "Strawberry", "Mango", "Cherry"];
const start = 2;
const removedItems = fruits.splice(start);
console.log(fruits);
// ["Apple", "Banana"]
console.log(removedItems);
// ["Strawberry", "Mango", "Cherry"]
```

### 배열에서 첫 번째 항목 제거하기

이 예제는 `shift()` 메서드를 사용하여 `fruits` 배열에서 첫 번째 항목을 제거합니다.

```js
const fruits = ["Apple", "Banana"];
const removedItem = fruits.shift();
console.log(fruits);
// ["Banana"]
console.log(removedItem);
// Apple
```

**참고:** `shift()`는 배열에서 첫 번째 항목을 제거하는 데에만 사용할 수 있습니다. 배열의 시작 부분에서 여러 항목을 제거하려면 다음 예제를 참조하세요.

### 배열의 시작 부분에서 여러 항목 제거하기

이 예제는 `splice()` 메서드를 사용하여 `fruits` 배열에서 처음 3개의 항목을 제거합니다.

```js
const fruits = ["Apple", "Strawberry", "Cherry", "Banana", "Mango"];
const start = 0;
const deleteCount = 3;
const removedItems = fruits.splice(start, deleteCount);
console.log(fruits);
// ["Banana", "Mango"]
console.log(removedItems);
// ["Apple", "Strawberry", "Cherry"]
```

### 배열에 새로운 첫 번째 항목 추가하기

이 예제는 `unshift()` 메서드를 사용하여 `fruits`배열의 인덱스 `0`에 새 항목을 추가하고 배열의 새 첫 번째 항목으로 만듭니다.

```js
const fruits = ["Banana", "Mango"];
const newLength = fruits.unshift("Strawberry");
console.log(fruits);
// ["Strawberry", "Banana", "Mango"]
console.log(newLength);
// 3
```

### 인덱스로 단일 항목 제거하기

이 예제는 `splice()` 메서드를 사용하여 `"Banana"`의 인덱스 위치를 지정하여 `fruits` 배열에서 문자열 `"Banana"`를 제거합니다.

```js
const fruits = ["Strawberry", "Banana", "Mango"];
const start = fruits.indexOf("Banana");
const deleteCount = 1;
const removedItems = fruits.splice(start, deleteCount);
console.log(fruits);
// ["Strawberry", "Mango"]
console.log(removedItems);
// ["Banana"]
```

### 인덱스로 여러 항목 제거하기

이 예제는 `splice()` 메서드를 사용하여 `fruits` 배열에서 문자열 `"Banana"`와 `"Strawberry"`를 제거하는데, `"Banana"`의 인덱스 위치와 제거할 총 항목 수를 지정하여 제거합니다.

```js
const fruits = ["Apple", "Banana", "Strawberry", "Mango"];
const start = 1;
const deleteCount = 2;
const removedItems = fruits.splice(start, deleteCount);
console.log(fruits);
// ["Apple", "Mango"]
console.log(removedItems);
// ["Banana", "Strawberry"]
```

### 배열의 여러 항목 바꾸기

이 예제는 `splice()` 메서드를 사용하여 `fruits` 배열의 마지막 2개 항목을 새 항목으로 바꿉니다.

```js
const fruits = ["Apple", "Banana", "Strawberry"];
const start = -2;
const deleteCount = 2;
const removedItems = fruits.splice(start, deleteCount, "Mango", "Cherry");
console.log(fruits);
// ["Apple", "Mango", "Cherry"]
console.log(removedItems);
// ["Banana", "Strawberry"]
```

### 배열 순회하기

이 예제에서는 `for...of` 루프를 사용하여 `fruits` 배열을 순회하며 각 항목을 콘솔에 기록합니다.

```js
const fruits = ["Apple", "Mango", "Cherry"];
for (const fruit of fruits) {
  console.log(fruit);
}
// Apple
// Mango
// Cherry
```

그러나 `for...of`는 배열을 순회하는 여러 가지 방법 중 하나일 뿐입니다. 더 많은 방법은 루프와 순회와, `every()`, `filter()`, `flatMap()`, `map()`, `reduce()`, `reduceRight()` 메서드에 대한 문서, 그리고 `forEach()` 메서드를 사용하는 다음 예시를 참조하세요.

### 배열의 각 요소에 대해 함수 호출

이 예제는 `forEach()` 메서드를 사용하여 `fruits` 배열의 각 요소에 대해 함수를 호출합니다. 이 함수는 각 항목이 항목의 인덱스 번호를 함께 콘솔에 기록합니다.

```js
const fruits = ["Apple", "Mango", "Cherry"];
fruits.forEach((item, index, array) => {
  console.log(item, index);
});
// Apple 0
// Mango 1
// Cherry 2
```

### 여러 배열 병합하기

이 예제는 `concat()` 메서드를 사용하여 `fruits` 배열을 `moreFruits` 배열과 병합해 새로운 `combinedFruits` 배열을 생성합니다. `fruits`와 `moreFruits`는 변경되지 않습니다.

```js
const fruits = ["Apple", "Banana", "Strawberry"];
const moreFruits = ["Mango", "Cherry"];
const combinedFruits = fruits.concat(moreFruits);
console.log(combinedFruits);
// ["Apple", "Banana", "Strawberry", "Mango", "Cherry"]

// 'fruits' 배열은 변경되지 않습니다.
console.log(fruits);
// ["Apple", "Banana", "Strawberry"]

// 'moreFruits' 배열도 변경되지 않습니다.
console.log(moreFruits);
// ["Mango", "Cherry"]
```

### 배열 복사하기

이 예제는 기존 `fruits` 배열에서 새 배열을 만드는 세 가지 방법을 보여줍니다. 먼저 전개 구문을 사용하고, `from()` 메서드, 그리고 `slice()` 메서드를 사용합니다.

```js
const fruits = ["Strawberry", "Mango"];

// 전개 구문을 사용하여 복사본을 만듭니다.
const fruitsCopy = [...fruits];
// ["Strawberry", "Mango"]

// from() 메서드를 사용하여 복사본을 만듭니다.
const fruitsCopy2 = Array.from(fruits);
// ["Strawberry", "Mango"]

// slice() 메서드를 사용하여 복사본을 만듭니다.
const fruitsCopy3 = fruits.slice();
// ["Strawberry", "Mango"]
```

모든 내장 배열 복사 연산(전개 구문, `Array.from()`, `Array.prototype.slice()`, `Array.prototype.concat()`)은 얕은 복사본을 생성합니다. 대신 배열의 깊은 복사본을 원한다면 `JSON.stringify()`를 사용하여 배열을 JSON 문자열로 변환한 다음, `JSON.parse()`를 사용하여 문자열을 원래 배열과 완전히 독립된 새 배열로 다시 변환할 수 있습니다.

```js
const fruitsDeepCopy = JSON.parse(JSON.stringify(fruits));
```

`structuredClone()` 메서드를 사용하여 깊은 복사본을 만들 수도 있는데, 이 메서드는 소스의 전송 가능한 객체 (en-US)를 단순히 복제하는 것이 아니라 새 복사본으로 전송할 수 있다는 장점이 있습니다.

마지막으로, 기존 배열을 새 변수에 할당해도 배열이나 그 요소의 복사본이 생성되지 않는다는 점을 이해하는 것이 중요합니다. 대신 새 변수는 기존 배열에 대한 참조 또는 별칭일 뿐이며, 기존 배열의 이름과 새 변수 이름은 완전히 동일한 객체에 대한 두 개의 이름일 뿐입니다(따라서 항상 엄격하게 동일한 것으로 평가됩니다). 따라서 기존 배열의 값이나 새 변수의 값을 조금이라도 변경하면, 다른 변수도 변경됩니다.

```js
const fruits = ["Strawberry", "Mango"];
const fruitsAlias = fruits;
// 'fruits'와 'fruitsAlias'는 동일한 객체이며, 엄격하게 동일합니다.
fruits === fruitsAlias; // true
// 'fruits' 배열에 대한 모든 변경 사항은 'fruitsAlias'도 변경합니다.
fruits.unshift("Apple", "Banana");
console.log(fruits);
// ['Apple', 'Banana', 'Strawberry', 'Mango']
console.log(fruitsAlias);
// ['Apple', 'Banana', 'Strawberry', 'Mango']
```

### 2차원 배열 만들기

다음 예제는 2차원 문자열 배열로 체스 판을 만듭니다. 첫 번째 이동은 `'p'`가 `board[6][4]`에서 `board[4][4]`로 복사되어 이루어집니다. 이전 위치 `[6][4]`는 빈칸이 됩니다.

```js
const board = [
  ["R", "N", "B", "Q", "K", "B", "N", "R"],
  ["P", "P", "P", "P", "P", "P", "P", "P"],
  [" ", " ", " ", " ", " ", " ", " ", " "],
  [" ", " ", " ", " ", " ", " ", " ", " "],
  [" ", " ", " ", " ", " ", " ", " ", " "],
  [" ", " ", " ", " ", " ", " ", " ", " "],
  ["p", "p", "p", "p", "p", "p", "p", "p"],
  ["r", "n", "b", "q", "k", "b", "n", "r"],
];

console.log(`${board.join("\n")}\n\n`);

// 킹의 폰을 2칸 앞으로 이동
board[4][4] = board[6][4];
board[6][4] = " ";
console.log(board.join("\n"));
```

출력 결과입니다.
```

R,N,B,Q,K,B,N,R
P,P,P,P,P,P,P,P
 , , , , , , ,
 , , , , , , ,
 , , , , , , ,
 , , , , , , ,
p,p,p,p,p,p,p,p
r,n,b,q,k,b,n,r

R,N,B,Q,K,B,N,R
P,P,P,P,P,P,P,P
 , , , , , , ,
 , , , , , , ,
 , , , ,p, , ,
 , , , , , , ,
p,p,p,p, ,p,p,p
r,n,b,q,k,b,n,r
```

### 배열을 사용하여 값 집합을 표로 만들기

```js
const values = [];
for (let x = 0; x < 10; x++) {
  values.push([2 \*\* x, 2 \* x \*\* 2]);
}
console.table(values);
```

출력 결과입니다.
```

// 첫 번째 열은 인덱스입니다.
0  1    0
1  2    2
2  4    8
3  8    18
4  16   32
5  32   50
6  64   72
7  128  98
8  256  128
9  512  162
```

### 일치 결과를 사용하여 배열 만들기

`RegExp`와 문자열 간의 일치 결과는 일치에 대한 정보를 제공하는 속성과 요소를 포함하는 JavaScript 배열을 생성할 수 있습니다. 이러한 배열은 `RegExp.prototype.exec()` (en-US)와 `String.prototype.match()`에서 반환됩니다.

예를 들어 다음과 같습니다.

```js
// 하나의 d, 하나 이상의 b, 하나의 d를 일치시킵니다.
// 일치하는 b와 뒤따라오는 d를 기억합니다.
// 대소문자는 무시.

const myRe = /d(b+)(d)/i;
const execResult = myRe.exec("cdbBdbsbz");

console.log(execResult.input); // 'cdbBdbsbz'
console.log(execResult.index); // 1
console.log(execResult); // [ "dbBd", "bB", "d" ]
```

일치 결과에 대한 자세한 내용은 `RegExp.prototype.exec()` (en-US)와 `String.prototype.match()` 페이지를 참조하세요.

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-array-objects |

브라우저 호환성
--------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

같이 보기
-----

* 인덱스된 컬렉션
* `TypedArray`
* `ArrayBuffer`


globalThis - JavaScript

globalThis
==========

 전역 **`globalThis`** 속성에는 일반적으로 전역 객체와 유사한
 전역 `this` 값이 포함됩니다.

시도해보기
-----

값
-

전역 `this` 객체입니다.

| Property attributes of `globalThis` |
| --- |
| Writable | 가능 |
| Enumerable | 불가능 |
| Configurable | 가능 |

**참고:** `globalThis` 속성은 구성 및 쓰기가 가능하므로 코드 작성자가 신뢰할 수 없는 코드를 실행할 때 숨길 수 있고 전역 객체 노출을 방지할 수 있습니다.

설명
--

 역사적으로 전역 객체에 접근하려면 다른 JavaScript 환경에서 다른 구문이 필요했습니다. 웹에서는 `window` (en-US), `self`, `frames` (en-US)를 사용할 수 있지만, Web Workers에서는 `self`만 동작합니다. Node.js에서는 이 중 어느 것도 작동하지 않으며 대신 `global`을 사용해야 합니다.
 `this` 키워드는 비엄격 모드에서 실행되는 함수 내부에서 사용될 수 있지만, `this`는 엄격 모드에서 실행되는 모듈 및 내부 함수에서 `undefined`가 됩니다. `Function('return this')()`를 사용하는 방법도 존재하지만, 브라우저의 CSP와 같이 `eval()` (en-US)을 비활성화하는 환경에서는 이러한 방식으로 `Function`을 사용할 수 없습니다.

`globalThis` 속성은 환경에 무관하게 전역 `this` 값, 즉 전역 객체에 접근하는 표준 방법을 제공합니다. `window`, `self` 등 유사한 속성과는 다르게 window와 non-window 컨텍스트 모두에서의 동작을 보장합니다. 따라서 코드를 구동하는 환경을 모르더라도 전역 객체에 일관된 방식으로 접근할 수 있습니다. 이름을 기억하는 데 도움이 되도록 전역 범위에서 `this` 값은 `globalThis`라는 점만 기억하세요.

**참고:** 브라우저와 Node의 경우에서 `globalThis`는 일반적으로 전역 객체와 동일한 개념입니다(즉, `globalThis`에 속성을 추가하면 전역 변수가 됨). 그러나 호스트는 전역 객체와 관련이 없는 `globalThis`에 대해 다른 값을 제공할 수 있습니다.

### HTML과 WindowProxy

많은 엔진에서 `globalThis`는 실제 전역 객체를 대한 참조이지만 웹 브라우저는 `<iframe>` (en-US)과 교차 창 보안 문제로 인해 전역 객체를 감싼 `Proxy`를 대신 참조합니다(직접 액세스할 수 없음). 일반적인 사용에는 차이가 없다고 봐도 무방하지만, 알아두는 것이 중요합니다.

### 이름 지정

`self` 및 `global`과 같은 다른 유명한 이름 제안들은 기존 코드와의 호환성 문제를 우려해 고려 대상에서 제외되었습니다. 자세한 내용은 언어 제안서의 "NAMING" 문서를 참조하세요.

`globalThis`는 문자 그대로 전역 `this` 값입니다. 객체 없이 호출되는 비엄격 함수의 `this` 값과 같은 값입니다. 스크립트의 전역 범위에서 `this`의 값이기도 합니다.

예제
--

### 환경별 전역 접근

일반적으로 전역 객체는 명시적으로 지정할 필요가 없습니다. 해당 속성은 자동으로 전역 변수로 액세스할 수 있습니다.

```js
console.log(window.Math === Math); // true
```

그러나 전역 객체에 명시적으로 접근해야 하는 한 가지 경우는 일반적으로 폴리필을 위해 전역 개체에 **작성** 할 때입니다.

`globalThis` 이전에는 환경에 대한 전역 객체를 가져오는 방법 중 유일하게 믿을만한 교차 플랫폼 방법은 `Function('return this')()` 이었습니다. 그러나 이로 인해 일부 설정에서 CSP 위반이 발생하므로 작성자는 이와 같은 조각별 정의를 사용합니다(원래 core-js 소스).

```js
function check(it) {
  // Math는 모든 환경에서 전역으로 존재하는 것으로 알려져 있습니다.
  return it && it.Math === Math && it;
}

const globalObject =
  check(typeof window === "object" && window) ||
  check(typeof self === "object" && self) ||
  check(typeof global === "object" && global) ||
  // 엄격 모드에서 실행할 때 undefined를 반환합니다.
  (function () {
    return this;
  })() ||
  Function("return this")();
```

전역 객체를 얻은 후 새로운 전역을 정의할 수 있습니다. 예를 들어 `Intl` (en-US)에 대한 구현을 추가합니다.

```js
if (typeof globalObject.Intl === "undefined") {
  // No Intl in this environment; define our own on the global scope
  Object.defineProperty(globalObject, "Intl", {
    value: {
      // Our Intl implementation
    },
    enumerable: false,
    configurable: true,
    writable: true,
  });
}
```

`globalThis`를 사용할 수 있으므로 환경 전체에 대한 추가 검색이 더 이상 필요하지 않습니다.

```js
if (typeof globalThis.Intl === "undefined") {
  Object.defineProperty(globalThis, "Intl", {
    value: {
      // Our Intl implementation
    },
    enumerable: false,
    configurable: true,
    writable: true,
  });
}
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-globalthis |

브라우저 호환성
--------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

같이 보기
-----

* Polyfill of `globalThis` in `core-js`
* `this`


WeakMap - JavaScript

WeakMap
=======

**`WeakMap`** 은 키/값 쌍의 모음으로, 키는 반드시 객체 또는 등록되지 않은 심볼이며 값은 임의의 JavaScript 타입입니다. `WeakMap`은 키에 대한 강력한 참조를 생성하지 않으므로, 객체가 `WeakMap`의 키에 포함되더라도 가비지 컬렉션의 대상이 됩니다. 키 객체가 가비지 컬렉터에 의해 정리된 후에는, 다른 곳에 강력한 참조가 존재하지 않는 한, 키에 연결됐던 값 또한 가비지 컬렉션 대상이 됩니다. `WeakMap`의 키로 사용할 수 있는 유일한 원시 값은 심볼, 정확히는 등록되지 않은 심볼인데, 등록되지 않은 심볼은 고유함이 보장되며 다시 생성할 수 없기 때문입니다.

`WeakMap`을 사용하면 값이 키를 참조하더라도 키 객체의 가비지 컬렉션을 방지하지 않는 방식으로 데이터를 객체에 연결할 수 있습니다. 그러나 `WeakMap`은 키의 활성 상태를 관찰하는 것을 허용하지 않으며, 이는 `WeakMap`의 키를 열거할 수 없는 이유입니다. 만약 `WeakMap`이 키 목록을 얻을 수 있는 어떤 메서드를 제공했다면, 그 목록은 가비지 컬렉션 상태에 따라 달라질 것이므로 비결정성이 발생합니다. 키 목록이 필요하면 `WeakMap` 대신 `Map`을 사용해야 합니다.

키 기반 컬렉션 안내서의 WeakMap 객체 구획에서 `WeakMap`에 대해 자세히 알아볼 수 있습니다.

설명
--

`WeakMap`의 키는 반드시 가비지 컬렉션 가능해야 합니다. 대부분의 원시 값은 임의로 생성될 수 있고 생명 주기가 따로 없으므로 키로 사용할 수 없습니다. 객체와 등록되지 않은 심볼은 가비지 컬렉션 대상이므로 키로 사용할 수 있습니다.

### 왜 WeakMap인가?

JavaScript의 맵 API는 4개의 API 메서드와 이들이 공유하는 두 개의 배열(키용 하나, 값용 하나)으로도 구현하려면 구현할 수 있습니다. 이 맵에 요소를 추가하면 키와 값을 동시에 각 배열의 끝으로 넣는 작업을 수행할 것입니다. 결과적으로, 키와 값이 두 배열 각각에서 같은 인덱스에 위치하게 됩니다. 맵에서 값을 가져오려면 키 배열을 순회하면서 일치하는 항목을 찾고, 이 항목의 인덱스로 값 배열에서 값을 가져올 것입니다.

이 구현에는 두 가지 큰 불편함이 있습니다.

1. 값의 설정과 검색이 `O(n)`(*n*은 맵 키의 수)입니다. 두 작업 모두 일치하는 값을 찾기 위해 키 목록을 순회해야 하기 때문입니다.
2. 메모리 누수입니다. 배열은 각 키와 각 값에 대한 참조가 무기한 유지되도록 보장하기 때문인데, 이 때문에 다른 곳에서 객체를 참조하지 않더라도 키가 가비지 컬렉션 대상이 되지 못합니다. 값도 마찬가지입니다.

반면, `WeakMap`에서 키 객체는 가비지 컬렉션 되지 않는 한 자신의 값을 강력하게 참조하고, 그 후에는 약하게 참조합니다. 따라서 `WeakMap`은 다음과 같습니다.

* 가비지 컬렉션을 방지하지 않으므로 키 객체에 대한 참조가 결국 사라집니다.
* 키 객체가 `WeakMap` 밖의 다른 곳에서 참조되지 않으면 그 값의 가비지 컬렉션도 허용합니다.

`WeakMap`은 가비지 컬렉션 되지 않아야만 유용한 키에 정보를 매핑할 때 특히 유용한 구조입니다.

그러나 `WeakMap`은 키의 활성 상태를 관찰하는 것을 허용하지 않으므로 키를 열거할 수 없습니다. 키 목록을 얻을 수 있는 방법은 존재하지 않습니다. 그런 방법이 존재했다면, 키 목록은 가비지 컬렉션 상태에 따라 달라질 것이므로 비결정성이 발생합니다. 키 목록이 필요하면 `Map`을 사용해야 합니다.

생성자
---

`WeakMap()` (en-US)

새로운 `WeakMap` 객체를 생성합니다.

인스턴스 속성
-------

이 속성들은 `WeakMap.prototype`에 정의되며 모든 `WeakMap` 인스턴스가 공유합니다.

`WeakMap.prototype.constructor`

인스턴스 객체를 생성했던 생성자 함수입니다. `WeakMap` 인스턴스에서의 초기 값은 `WeakMap` (en-US) 생성자입니다.

`WeakMap.prototype[@@toStringTag]`

`@@toStringTag` (en-US) 속성의 초기 값은 문자열 `"WeakMap"`입니다. 이 속성은 `Object.prototype.toString()`에서 사용합니다.

인스턴스 메서드
--------

`WeakMap.prototype.delete()`

`key`에 연결된 값을 제거합니다. 이후 `WeakMap.prototype.has(key)`는 `false`를 반환할 것입니다.

`WeakMap.prototype.get()`

`key`에 연결된 값을 반환합니다. 값이 없으면 `undefined`를 반환합니다.

`WeakMap.prototype.has()`

`key`에 연결된 값이 `WeakMap` 객체에 존재하는지 나타내는 불리언 값을 반환합니다.

`WeakMap.prototype.set()`

`WeakMap` 객체의 `key`에 `value`를 연결합니다. `WeakMap` 객체를 반환합니다.

예제
--

### WeakMap 사용하기

```js
const wm1 = new WeakMap();
const wm2 = new WeakMap();
const wm3 = new WeakMap();
const o1 = {};
const o2 = function () {};
const o3 = window;

wm1.set(o1, 37);
wm1.set(o2, "azerty");
wm2.set(o1, o2); // 값은 함수와 객체를 포함해 아무거나 가능
wm2.set(o3, undefined);
wm2.set(wm1, wm2); // 키는 아무 객체나 가능. 다른 WeakMap도 가능합니다!

wm1.get(o2); // "azerty"
wm2.get(o2); // undefined, wm2에는 o2에 연결된 값이 없음
wm2.get(o3); // undefined, o3에 undefined를 연결함

wm1.has(o2); // true
wm2.has(o2); // false
wm2.has(o3); // true (값이 undefined지만)

wm3.set(o1, 37);
wm3.get(o1); // 37

wm1.has(o1); // true
wm1.delete(o1);
wm1.has(o1); // false
```

### WeakMap과 유사하지만 .clear() 메서드를 가진 클래스 구현

```js
class ClearableWeakMap {
  #wm;
  constructor(init) {
    this.#wm = new WeakMap(init);
  }
  clear() {
    this.#wm = new WeakMap();
  }
  delete(k) {
    return this.#wm.delete(k);
  }
  get(k) {
    return this.#wm.get(k);
  }
  has(k) {
    return this.#wm.has(k);
  }
  set(k, v) {
    this.#wm.set(k, v);
    return this;
  }
}
```

### 비공개 멤버 흉내내기

`WeakMap`을 사용하면 비공개 데이터를 객체에 연결할 수 있고, 다음과 같은 이점을 누릴 수 있습니다.

* `Map`과 비교했을 때, `WeakMap`은 키로 사용되는 객체에 대한 강력한 참조를 보유하지 않으므로 객체와 그 메타데이터가 동일한 수명을 공유하고, 따라서 메모리 누수를 방지할 수 있습니다.
* 열거할 수 없는 속성이나 `Symbol` 속성을 사용하는 것과 비교했을 때, `WeakMap`은 객체 외부에 존재하므로 `Object.getOwnPropertySymbols` 등 리플렉션 메서드를 사용하더라도 사용자 코드에서는 메타데이터를 가져올 수 없습니다.
* 클로저와 비교했을 때, 하나의 `WeakMap`을 생성자에서 생성한 모든 인스턴스에 재사용할 수 있으므로 메모리 효율성이 더 높고, 같은 클래스의 다른 인스턴스가 서로의 비공개 멤버를 읽을 수 있습니다.

```js
let Thing;

{
  const privateScope = new WeakMap();
  let counter = 0;

  Thing = function () {
    this.someProperty = "foo";

    privateScope.set(this, {
      hidden: ++counter,
    });
  };

  Thing.prototype.showPublic = function () {
    return this.someProperty;
  };

  Thing.prototype.showPrivate = function () {
    return privateScope.get(this).hidden;
  };
}

console.log(typeof privateScope);
// "undefined"

const thing = new Thing();

console.log(thing);
// Thing {someProperty: "foo"}

thing.showPublic();
// "foo"

thing.showPrivate();
// 1
```

위 코드는 비공개 필드를 사용하는 아래 예제와 동일하다고 볼 수 있습니다.

```js
class Thing {
  static #counter = 0;
  #hidden;
  constructor() {
    this.someProperty = "foo";
    this.#hidden = ++Thing.#counter;
  }
  showPublic() {
    return this.someProperty;
  }
  showPrivate() {
    return this.#hidden;
  }
}

console.log(thing);
// Thing {someProperty: "foo"}

thing.showPublic();
// "foo"

thing.showPrivate();
// 1
```

### 메타데이터 연결하기

`WeakMap`을 사용하면 객체의 생명 주기에 영향을 주지 않고도 메타데이터를 연결할 수 있습니다. 비공개 멤버 예제하고도 굉장히 비슷한데, 비공개 멤버 또한 프로토타입 상속에 참여하지 않는 외부 메타데이터로 설계됐기 때문입니다.

하지만 이 방법은 이미 생성된 객체들을 대상으로도 확장할 수 있습니다. 예를 들어 웹에서는, DOM 요소에 추가 데이터를 연결했다가 나중에 접근하고 싶은 경우가 생길 수 있습니다. 흔히 쓰이는 방법은 데이터를 요소의 속성으로 붙이는 것입니다.

```js
const buttons = document.querySelectorAll(".button");
buttons.forEach((button) => {
  button.clicked = false;
  button.addEventListener("click", () => {
    button.clicked = true;
    const currentButtons = [...document.querySelectorAll(".button")];
    if (currentButtons.every((button) => button.clicked)) {
      console.log("모든 버튼을 클릭했습니다!");
    }
  });
});
```

위 방법도 동작하지만, 몇 가지 문제가 있습니다.

* `clicked` 속성이 열거 가능하므로 `Object.keys(button)`, `for...in` 반복문 등에 노출됩니다. `Object.defineProperty()`를 사용하면 대응할 수 있지만, 대신 코드가 더 시끄러워집니다.
* `clicked` 속성은 일반 문자열 속성이므로 다른 코드에서 접근하거나 덮어쓸 수 있습니다. `Symbol` 키를 사용해 대응할 수 있지만, 그래도 `Object.getOwnPropertySymbols()`로 접근할 수 있습니다.

`WeakMap`을 사용하면 모두 고칠 수 있습니다.

```js
const buttons = document.querySelectorAll(".button");
const clicked = new WeakMap();
buttons.forEach((button) => {
  clicked.set(button, false);
  button.addEventListener("click", () => {
    clicked.set(button, true);
    const currentButtons = [...document.querySelectorAll(".button")];
    if (currentButtons.every((button) => clicked.get(button))) {
      console.log("모든 버튼을 클릭했습니다!");
    }
  });
});
```

여기서는 `clicked`에 접근할 수 있는 코드만 각 버튼의 클릭 상태를 알 수 있으므로 외부 코드는 이 상태를 바꿀 수 없습니다. 또한 버튼이 DOM에서 제거되면 연관됐던 메타데이터도 가비지 컬렉터가 자동으로 정리합니다.

### 캐싱

함수에 전달했던 매개변수와 그 함수의 결과를 연관지으면, 같은 매개변수를 다시 받았을 때 함수를 다시 실행하지 않고 캐시된 결과를 반환할 수 있습니다. 이 방법은 함수가 순수(외부 객체를 조작하거나, 기타 관측 가능한 부작용을 유발하지 않음)할 때 유용합니다.

```js
const cache = new WeakMap();
function handleObjectValues(obj) {
  if (cache.has(obj)) {
    return cache.get(obj);
  }
  const result = Object.values(obj).map(heavyComputation);
  cache.set(obj, result);
  return result;
}
```

하지만 함수가 한 객체를 받을 때만 사용할 수 있다는 점을 주의해야 합니다. 또한 입력했던 객체를 함수에 다시 전달할 일이 영원히 없다고 해도, 결과는 캐시에 계속 남아있게 됩니다. 더 효율적인 방법은 `Map`과 `WeakRef` (en-US) 객체를 사용해서, 임의 타입의 입력 값을 그에 대응하는 (아마도 매우 큰) 계산 결과와 연관짓는 것입니다. 자세한 내용은 WeakRef와 FinalizationRegistry 예제를 참고하세요.

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-weakmap-objects |

브라우저 호환성
--------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

같이 보기
-----

* `core-js`의 `WeakMap` 폴리필
* 키 기반 컬렉션 안내서의 WeakMap 객체
* Hiding Implementation Details with ECMAScript 6 WeakMaps
* `Map`
* `Set` (en-US)
* `WeakSet`


Int8Array - JavaScript

Int8Array
=========

**`Int8Array`** 타입 배열은 2의 보수 8비트 부호있는 정수의 배열을 나타냅니다. 배열의 내용은 `0`으로 초기화됩니다.
 배열이 생성되면 객체의 메서드를 사용하거나 표준 배열 인덱스 구문(즉, 대괄호 표기법 사용)을 사용하여 배열의 요소를 참조할 수 있습니다.

생성자
---

`Int8Array()`

새로운 `Int8Array` 객체를 생성합니다.

정적 속성
-----

부모 `TypedArray`에서 정적 속성을 상속합니다.

`Int8Array.BYTES_PER_ELEMENT`

요소 크기를 숫자로 반환합니다. `Int8Array`의 경우 `1`입니다..

`Int8Array.name`

생성자 이름을 문자열로 반환합니다. `Int8Array`의 경우 `"Int8Array"` 입니다..

정적 메서드
------

부모 `TypedArray`에서 정적 메서드를 상속합니다.

인스턴스 속성
-------

부모 `TypedArray`에서 인스턴스 속성을 상속합니다.

`Int8Array.prototype.BYTES_PER_ELEMENT`

요소 크기를 숫자로 반환합니다. `Int8Array`의 경우 `1` 입니다.

인스턴스 메서드
--------

부모 `TypedArray`에서 인스턴스 메서드를 상속합니다.

예제
--

### Int8Array를 생성하기 위한 각기 다른 여러 방법

```js
// 길이로부터 생성
const int8 = new Int8Array(2);
int8[0] = 42;
console.log(int8[0]); // 42
console.log(int8.length); // 2
console.log(int8.BYTES\_PER\_ELEMENT); // 1

// 배열로부터 생성
const x = new Int8Array([21, 31]);
console.log(x[1]); // 31

// 다른 TypedArray로부터 생성
const y = new Int8Array(x);
console.log(y[0]); // 21

// ArrayBuffer로부터 생성
const buffer = new ArrayBuffer(8);
const z = new Int8Array(buffer, 1, 4);
console.log(z.byteOffset); // 1

// 순회로부터 생성
const iterable = (function\* () {
  yield\* [1, 2, 3];
})();
const int8FromIterable = new Int8Array(iterable);
console.log(int8FromIterable);
// Int8Array [1, 2, 3]
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # table-49 |

브라우저 호환성
--------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

같이 보기
-----

* `core-js`에서 `Int8Array` 폴리필
* JavaScript 형식화 배열
* `ArrayBuffer`
* `DataView`


Float32Array - JavaScript

Float32Array
============

**`Float32Array`** 형식화 배열(TypedArray)은 플랫폼의 바이트 순서를 따르는 32비트 부동 소수점(C의 `float`
 데이터 타입에 대응) 배열입니다. 바이트 순서를 제어해야 하는 경우 대신 `DataView`를 사용합니다. 배열의
 내용은 0으로 초기화됩니다. 배열이 생성되면 객체의 메서드를 사용하거나 표준 배열 인덱스 구문(즉, 대괄호 표기법 사용)을
 사용하여 배열의 요소를 참조할 수 있습니다.

생성자
---

`Float32Array()`

새로운 `Float32Array` 객체를 생성합니다.

정적 속성
-----

부모 `TypedArray`에서 정적 속성을 상속합니다.

`Float32Array.BYTES_PER_ELEMENT`

요소 크기를 숫자 값으로 반환합니다. `Float32Array`의 경우 `4`입니다.

`Float32Array.name`

생성자 이름을 문자열로 반환합니다. `Float32Array` 타입의 경우 `"Float32Array"`입니다.

정적 메서드
------

부모 `TypedArray`에서 정적 메서드를 상속합니다.

인스턴스 속성
-------

부모 `TypedArray`에서 인스턴스 속성을 상속합니다.

`Float32Array.prototype.BYTES_PER_ELEMENT`

요소 크기를 숫자 값으로 반환합니다. `Float32Array`의 경우 `4`입니다.

인스턴스 메서드
--------

부모 `TypedArray`에서 인스턴스 메서드를 상속합니다.

예제
--

### `Float32Array`를 생성하기 위한 각기 다른 여러 방법

```js
// 길이로부터 생성
const float32 = new Float32Array(2);
float32[0] = 42;
console.log(float32[0]); // 42
console.log(float32.length); // 2
console.log(float32.BYTES\_PER\_ELEMENT); // 4

// 배열로부터 생성
const x = new Float32Array([21, 31]);
console.log(x[1]); // 31

// 다른 TypedArray로부터 생성
const y = new Float32Array(x);
console.log(y[0]); // 21

// ArrayBuffer로부터 생성
const buffer = new ArrayBuffer(32);
const z = new Float32Array(buffer, 4, 4);
console.log(z.byteOffset); // 4

// 순회로부터 생성
const iterable = (function\* () {
  yield\* [1, 2, 3];
})();
const float32FromIterable = new Float32Array(iterable);
console.log(float32FromIterable);
// Float32Array [1, 2, 3]
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # table-49 |

브라우저 호환성
--------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

같이 보기
-----

* `core-js`에서 `Float32Array`의 폴리필
* JavaScript 형식화 배열
* `ArrayBuffer`
* `DataView`