URIError() constructor - JavaScript

URIError() constructor
======================

**`URIError()`** 생성자는 전역 URI 핸들링 함수가 잘못 사용될 때 오류를 생성합니다.

구문
--

```js
new URIError();
new URIError(message);
new URIError(message, fileName);
new URIError(message, fileName, lineNumber);
```

### 매개변수

`message` Optional

사람이 읽을 수 있는 에러에 대한 설명.

`fileName` Optional

예외를 일으킨 코드가 들어있는 파일 이름.

`lineNumber` Optional

예외를 일으킨 코드의 줄 수.

예제
--

### URIError 잡기

```js
try {
  decodeURIComponent("%");
} catch (e) {
  console.log(e instanceof URIError); // true
  console.log(e.message); // "malformed URI sequence"
  console.log(e.name); // "URIError"
  console.log(e.fileName); // "Scratchpad/1"
  console.log(e.lineNumber); // 2
  console.log(e.columnNumber); // 2
  console.log(e.stack); // "@Scratchpad/2:2:3\n"
}
```

### URIError 생성하기

```js
try {
  throw new URIError("Hello", "someFile.js", 10);
} catch (e) {
  console.log(e instanceof URIError); // true
  console.log(e.message); // "Hello"
  console.log(e.name); // "URIError"
  console.log(e.fileName); // "someFile.js"
  console.log(e.lineNumber); // 10
  console.log(e.columnNumber); // 0
  console.log(e.stack); // "@Scratchpad/2:2:9\n"
}
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-nativeerror-constructors |

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

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

같이 보기
-----

* `Error`
* `decodeURI()`
* `decodeURIComponent()`
* `encodeURI()`
* `encodeURIComponent()`


RegExp.prototype.global - JavaScript

RegExp.prototype.global
=======================

**`global`** 접근자 속성은 `g` 플래그가 정규표현식에 사용되었는지 여부를 나타냅니다.

시도해보기
-----

설명
--

`g` 플래그가 사용된 경우 `RegExp.prototype.global`의 값은 `true`이고, 그렇지 않으면 `false`입니다.
 `g` 플래그는 정규식이 문자열에서 가능한 모든 일치 항목에 대해 테스트되어야 함을 나타냅니다.
 `exec()` (en-US)를 호출할 때마다
 `lastIndex` (en-US) 속성이
 업데이트되므로 다음 `exec()` 호출은 다음 문자에서 시작됩니다.

`String.prototype.matchAll()` (en-US) 및 `String.prototype.replaceAll()`과 같은 일부 메서드는 매개변수가 정규식인 경우 전역(global)인지 여부를 확인합니다.
 정규식의 `@@match` (en-US) 및 `@@replace` (en-US) 메서드(`String.prototype.match()` 및 `String.prototype.replace()` (en-US)에 의해 호출됨)도 정규식이 전역일 때 다른 동작을 갖습니다.

`global`의 set 접근자는 `undefined`, 즉 정의되지 않았습니다. 이 속성은 직접 변경할 수 없습니다.

예제
--

### global 사용하기

```js
const regex = /foo/g;
console.log(regex.global); // true

const str = "fooexamplefoo";
const str1 = str.replace(regex, "");
console.log(str1); // example

const regex1 = /foo/;
const str2 = str.replace(regex1, "");
console.log(str2); // examplefoo
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-regexp.prototype.global |

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

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

같이 보기
-----

* `RegExp.prototype.lastIndex` (en-US)
* `RegExp.prototype.dotAll`
* `RegExp.prototype.hasIndices` (en-US)
* `RegExp.prototype.ignoreCase`
* `RegExp.prototype.multiline`
* `RegExp.prototype.source` (en-US)
* `RegExp.prototype.sticky` (en-US)
* `RegExp.prototype.unicode` (en-US)


RegExp.prototype.dotAll - JavaScript

RegExp.prototype.dotAll
=======================

**`dotAll`** 속성은 `s` 플래그가 정규식과 함께 사용되는지 여부를 나타냅니다. `dotAll`은 개별 정규식 인스턴스의 읽기 전용 속성입니다.

시도해보기
-----

설명
--

`dotAll`의 값은 `Boolean`으로 `s` 플래그가 사용된 경우 `true`, 그렇지 않으면 `false`입니다.
 `s` 플래그는 점 특수 문자(`.`)가 문자열의 다음 줄 종결자("newline") 문자와 추가로 일치해야 함을 나타냅니다.
 그렇지 않으면 일치하지 않습니다.

* U+000A LINE FEED (LF) (`\n`)
* U+000D CARRIAGE RETURN (CR) (`\r`)
* U+2028 LINE SEPARATOR
* U+2029 PARAGRAPH SEPARATOR

이것은 사실상 점이 유니코드 BMP(Basic Multilingual Plane)의 모든 문자와 일치한다는 것을 의미합니다. 별 기호와 일치하도록 하려면 `u`(유니코드) 플래그를 사용해야 합니다. 두 플래그를 함께 사용하면 예외 없이 점이 모든 유니코드 문자와 일치하도록 만들 수 있습니다.

`dotAll`의 set 접근자는 `undefined`, 즉 정의되지 않았습니다. 이 속성은 직접 변경할 수 없습니다.

예제
--

### `dotAll` 사용하기

```js
const str1 = "bar\nexample foo example";

const regex1 = /bar.example/s;

console.log(regex1.dotAll); // true

console.log(str1.replace(regex1, "")); // foo example

const str2 = "bar\nexample foo example";

const regex2 = /bar.example/;

console.log(regex2.dotAll); // false

console.log(str2.replace(regex2, ""));
// bar
// example foo example
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-regexp.prototype.dotAll |

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

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

같이보기
----

* Polyfill of `dotAll` `RegExp` flag in `core-js`
* `RegExp.lastIndex` (en-US)
* `RegExp.prototype.global`
* `RegExp.prototype.hasIndices` (en-US)
* `RegExp.prototype.ignoreCase`
* `RegExp.prototype.multiline`
* `RegExp.prototype.source` (en-US)
* `RegExp.prototype.sticky` (en-US)
* `RegExp.prototype.unicode` (en-US)


RegExp() constructor - JavaScript

RegExp() constructor
====================

**`RegExp`** 생성자는 패턴을 사용해 텍스트를 판별할 때 사용하는 정규 표현식 객체를 생성합니다.

정규 표현식에 대한 소개는 JavaScript 안내서의 정규 표현식 장을 참고하세요.

시도해보기
-----

구문
--

리터럴, 생성자, 팩토리 표기법이 가능합니다.
```

/pattern/flags
new RegExp(pattern[, flags])
RegExp(pattern[, flags])
```

### 매개변수

`pattern`

 정규 표현식을 나타내는 텍스트.
 ES5부터는, 생성자 표기법에 한정하여 다른 `RegExp` 객체 혹은 리터럴을 사용할 수 있습니다. 패턴은 특수 문자를 포함할 수 있어서 일반적인 문자열 리터럴보다 더 넓은 범위의 값을 판별할 수 있습니다.

`flags`

 정규 표현식에 추가할 플래그.
 정규 표현식 객체를 패턴으로 제공한 경우 `flags` 문자열은 제공한 객체의 플래그를 모두 대체하며 `lastIndex`를 `0`으로 초기화합니다. (ES2015 이후)
 `flags`를 지정하지 않았으면서 정규 표현식 객체를 제공한 경우, 해당 객체의 플래그와 `lastIndex`를 복제합니다.
 `flags`는 다음 문자를 조합하여 지정할 수 있습니다.

`g` (global, 전역 판별)

처음 일치에서 중단하지 않고, 문자열 전체를 판별합니다.

`i` (ignore case, 대소문자 무시)

`u` 플래그까지 활성화된 경우, Unicode 대소문자 폴딩을 사용합니다.

`m` (multiline, 여러 줄)

시작과 끝 문자(`^`과 `$`)가 여러 줄에 걸쳐 동작합니다. 즉, 전체 입력 문자열의 맨 처음과 맨 끝 뿐만 아니라 (`\n`이나 `\r`로 구분되는) 각각의 줄의 처음과 끝도 일치합니다.

`s` ("dotAll")

`.`이 줄 바꿈에도 일치합니다.

`u` (unicode)

`pattern`을 Unicode 코드 포인트 시퀀스로 처리합니다. (이진 문자열 참고)

`y` (sticky, 접착)

이 정규 표현식의 `lastIndex` 속성에 명시된 인덱스에서만 판별하고, 이전/이후 인덱스에서 판별을 시도하지 않습니다.

예제
--

### 리터럴 표기법과 생성자

`RegExp` 객체는 리터럴 표기법과 생성자로써 생성할 수 있습니다.

* **리터럴 표기법**의 매개변수는 두 빗금으로 감싸야 하며 따옴표를 사용하지 않습니다.
* **생성자 함수**의 매개변수는 빗금으로 감싸지 않으나 따옴표를 사용합니다.

다음의 세 표현식은 모두 같은 정규 표현식을 생성합니다.

```js
/ab+c/i;
new RegExp(/ab+c/, "i"); // 리터럴
new RegExp("ab+c", "i"); // 생성자
```

리터럴 표기법은 표현식을 평가할 때 정규 표현식을 컴파일합니다. 정규 표현식이 변하지 않으면 리터럴 표기법을 사용하세요. 예를 들어, 반복문 안에서 사용할 정규 표현식을 리터럴 표기법으로 생성하면 정규 표현식을 매번 다시 컴파일하지 않습니다.

정규 표현식 객체의 생성자(`new RegExp('ab+c')`)를 사용하면 정규 표현식이 런타임에 컴파일됩니다. 패턴이 변할 가능성이 있거나, 사용자 입력과 같이 알 수 없는 외부 소스에서 가져오는 정규 표현식의 경우 생성자 함수를 사용하세요.

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-regexp-constructor |

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

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

같이 보기
-----

* JavaScript 안내서의 정규 표현식 장
* `String.prototype.match()`
* `String.prototype.replace()` (en-US)


RegExp.prototype.ignoreCase - JavaScript

RegExp.prototype.ignoreCase
===========================

**`ignoreCase`** 접근자 속성은 `i` 플래그가 정규 표현식에 사용되었는지 여부를 가리킵니다.

시도해보기
-----

설명
--

`RegExp.prototype.ignoreCase`는 `i` 플래그가 사용되었으먼 `true`값을 가집니다. 그렇지 않으면 `false` 값을 가집니다. `i` 플래그는 문자열 매칭에서 대소문자를 구분하지 않음을 가리킵니다.

정규식에 `unicode` (en-US) 플래그가 있는 경우 대/소문자 케이스 매핑은 `CaseFolding.txt`에 명시된 대로 수행됩니다. 그렇지 않으면 대/소문자 매핑은 Unicode Default Case Conversion을 사용합니다. 이 알고리즘은 `String.prototype.toUpperCase()` 및 `String.prototype.toLowerCase()`에서 사용되는 알고리즘과 동일합니다.

`ignoreCase`의 set 접근자는 `undefined`, 즉 정의되지 않았습니다. 이 속성을 직접 변경할 수 없습니다.

예제
--

### ignoreCase 사용하기

```js
const regex = /foo/i;

console.log(regex.ignoreCase); // true
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-regexp.prototype.ignorecase |

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

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

같이 보기
-----

* `RegExp.prototype.lastIndex` (en-US)
* `RegExp.prototype.dotAll`
* `RegExp.prototype.global`
* `RegExp.prototype.hasIndices` (en-US)
* `RegExp.prototype.multiline`
* `RegExp.prototype.source` (en-US)
* `RegExp.prototype.sticky` (en-US)
* `RegExp.prototype.unicode` (en-US)


RegExp.prototype.test() - JavaScript

RegExp.prototype.test()
=======================

**`test()`** 메서드는 주어진 문자열이 정규 표현식을 만족하는지 판별하고, 그 여부를 `true` 또는 `false`로 반환합니다.

시도해보기
-----

구문
--

```js
regexObj.test(str);
```

### 매개변수

`str`

정규 표현식 일치를 수행할 문자열.

### 반환 값

주어진 문자열 `str` 중 정규 표현식이 일치하는 부분이 있으면 `true`, 아니면, `false`.

설명
--

패턴이 문자열 내에 존재하는지에 대한 여부를 알아보고자 할 때 `test()`를 사용하세요. 일치의 위치 인덱스, 또는 일치하지 않으면 `-1`을 반환하는 `String.prototype.search()` (en-US)와 달리 `test()`는 불리언을 반환합니다.

더 느리지만 더 많은 정보가 필요하면 `exec()` (en-US) 메서드를 사용하세요. (`String.prototype.match()` 메서드와 비슷합니다.)

`exec()`처럼, `test()`도 전역 탐색 플래그를 제공한 정규 표현식에서 여러 번 호출하면 이전 일치 이후부터 탐색합니다. `exec()`와 `test()`를 혼용해 사용하는 경우에도 해당됩니다.

예제
--

### `test()` 사용하기

문자열의 맨 처음에 `"hello"`가 포함됐는지 알아보는 간단한 예제 코드입니다.

```js
const str = "hello world!";
const result = /^hello/.test(str);

console.log(result); // true
```

다음은 일치 여부에 따라 다른 메시지를 기록하는 예제입니다.

```js
function testInput(re, str) {
  let midstring;
  if (re.test(str)) {
    midstring = "contains";
  } else {
    midstring = "does not contain";
  }
  console.log(`${str} ${midstring} ${re.source}`);
}
```

### 전역 플래그와 `test()`

정규 표현식에 전역 플래그를 설정한 경우, `test()` 메서드는 정규 표현식의 `lastIndex` (en-US)를 업데이트합니다. (`RegExp.prototype.exec()` (en-US)도 `lastIndex` 속성을 업데이트합니다.)

`test(str)`을 또 호출하면 `str` 검색을 `lastIndex`부터 계속 진행합니다. `lastIndex` 속성은 매 번 `test()`가 `true`를 반환할 때마다 증가하게 됩니다.

**참고:** `test()`가 `true`를 반환하기만 하면 `lastIndex`는 초기화되지 않습니다. 심지어 이전과 다른 문자열을 매개변수로 제공해도 그렇습니다!

`test()`가 `false`를 반환할 땐 `lastIndex` 속성이 `0`으로 초기화됩니다.

이 행동에 대한 예제가 다음 코드입니다.

```js
const regex = /foo/g; // the "global" flag is set

// regex.lastIndex is at 0
regex.test("foo"); // true

// regex.lastIndex is now at 3
regex.test("foo"); // false

// regex.lastIndex is at 0
regex.test("barfoo"); // true

// regex.lastIndex is at 6
regex.test("foobar"); //false

// regex.lastIndex is at 0
// (...and so on)
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-regexp.prototype.test |

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

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

같이 보기
-----

* JavaScript 안내서의 정규 표현식 장
* `RegExp`
* `RegExp.prototype` (en-US)


RegExp.prototype.multiline - JavaScript

RegExp.prototype.multiline
==========================

**`multiline`** 접근자 속성은 `m` 플래그가 정규표현식에 사용되었는지 여부를 나타냅니다.

시도해보기
-----

설명
--

`m` 플래그가 사용된 경우 `RegExp.prototype.multiline`은 `true` 값을 가지며,
 그렇지 않으면 `false` 값을 갖습니다. `m` 플래그는 여러 줄 입력 문자열을 여러 줄로 처리해야 함을 나타냅니다.
 예를 들어, `m`이 사용되면 `^`와 `$`는 전체 문자열의 시작 또는 끝에서만 일치하는 것에서
 문자열 내의 모든 줄의 시작 또는 끝에서 일치하는 것으로 변경됩니다.

`multiline`의 set 접근자는 `undefined`, 즉 정의되지 않았습니다. 이 속성은 직접 변경할 수 없습니다.

예제
--

### multiline 사용하기

```js
const regex = /foo/m;

console.log(regex.multiline); // true
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-regexp.prototype.multiline |

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

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

같이 보기
-----

* `RegExp.prototype.lastIndex` (en-US)
* `RegExp.prototype.dotAll`
* `RegExp.prototype.global`
* `RegExp.prototype.hasIndices` (en-US)
* `RegExp.prototype.ignoreCase`
* `RegExp.prototype.source` (en-US)
* `RegExp.prototype.sticky` (en-US)
* `RegExp.prototype.unicode` (en-US)


RegExp.prototype.flags - JavaScript

RegExp.prototype.flags
======================

**`flags`** 접근자 속성은 현재 정규식 객체의 플래그를 나타냅니다.

시도해보기
-----

설명
--

`RegExp.prototype.flags`는 문자열입니다. `flags` 속성의 플래그는 왼쪽에서 오른쪽으로 알파벳 순으로 정렬됩니다(예를 들어 `"dgimsuy"`). 실제로 다른 플래그 접근자(`hasIndices` (en-US), `global`, 등등)를 하나씩 호출하고 결과를 연결합니다.

내장된 모든 함수는 개별 플래그 접근자를 읽는 대신 `flags` 속성을 읽습니다.

`flags`의 set 접근자는 정의되지 않았습니다. 이 속성을 직접 변경할 수 없습니다.

예제
--

### flags 사용하기

```js
/foo/ig.flags; // "gi"
/bar/myu.flags; // "muy"
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-regexp.prototype.flags |

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

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

같이 보기
-----

* Polyfill of `RegExp.prototype.flags` in `core-js`
* `RegExp.prototype.source` (en-US)


Object.values() - JavaScript

Object.values()
===============

**`Object.values()`** 메소드는 전달된 파라미터 객체가 가지는 (열거 가능한) 속성의 값들로 이루어진 배열을 리턴합니다. 이 배열은 `for...in` 구문과 동일한 순서를 가집니다. (for in 반복문은 프로토타입 체인 또한 열거한다는 점에서 차이가 있습니다.)

시도해보기
-----

Syntax
------

```js
Object.values(obj);
```

### Parameters

`obj`

배열로 변환할 열거 가능한 속성을 가지는 객체

### Return value

전달된 객체의 속성 값들을 포함하는 배열

Description
-----------

`Object.values()` 는 파라미터로 전달된 객체가 가지는 열거 가능한 속성의 값들로 구성된 배열을 반환합니다. 배열의 값들이 순서는 오브젝트의 속성을 for in 구문등으로 반복한 결과와 동일합니다. (참고로 for in 구문은 순서를 보장하지 않습니다)

Examples
--------

```js
var obj = { foo: "bar", baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

// 유사 배열 (숫자를 속성으로 사용하는 객체)
var obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.values(obj)); // ['a', 'b', 'c']

// 유사 배열의 경의 속성으로 사용한 숫자의 크기 순으로 정렬되어 반환됩니다.
var an_obj = { 100: "a", 2: "b", 7: "c" };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']

// getFoo는 열거 가능한 속성이 아니라서 배열에 포함되지 않습니다.
var my_obj = Object.create(
  {},
  {
    getFoo: {
      value: function () {
        return this.foo;
      },
    },
  },
);
my_obj.foo = "bar";
console.log(Object.values(my_obj)); // ['bar']

// 객체가 아닌 경우에는 객체로 강제로 변환되어 적용됩니다.
console.log(Object.values("foo")); // ['f', 'o', 'o']
```

Polyfill
--------

`Object.values` 메소드는 구형 브라우저에서 지원하지 않습니다. 구형 브라우저와의 호환성을 고려하기 위해 폴리필을 찾아 볼 수 있습니다. tc39/proposal-object-values-entries 혹은 es-shims/Object.values 를 참조해보세요.

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.values |

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

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

See also
--------

* Enumerability and ownership of properties (en-US)
* `Object.keys()`
* `Object.entries()`
* `Object.prototype.propertyIsEnumerable()`
* `Object.create()`
* `Object.getOwnPropertyNames()`


Object.getOwnPropertySymbols() - JavaScript

Object.getOwnPropertySymbols()
==============================

**`Object.getOwnPropertySymbols()`** 메서드는 주어진 객체에서 직접 찾은 모든 심볼 속성들의 배열을 반환합니다.

시도해보기
-----

구문
--

```js
Object.getOwnPropertySymbols(obj);
```

### 매개변수

`obj`

반환받고자 하는 심볼 속성들이 있는 객체

### 반환 값

주어진 객체에서 직접 찾은 모든 심볼 속성들의 배열

설명
--

`Object.getOwnPropertyNames()`와 유사하게, 주어진 객체의 모든 심볼 속성을 배열로 가져올 수 있습니다. 참고로 `Object.getOwnPropertyNames()` 자체에는 객체의 심볼 속성이 포함되어 있지 않고 오직 문자열 속성만 포함되어 있습니다.

모든 객체에는 처음에는 고유한 심볼 속성이 없으므로, `Object.getOwnPropertySymbols()`는 객체에 심볼 속성을 설정하지 않는 한 빈 배열을 반환합니다.

예제
--

### getOwnPropertySymbols 사용하기

```js
var obj = {};
var a = Symbol("a");
var b = Symbol.for("b");

obj[a] = "localSymbol";
obj[b] = "globalSymbol";

var objectSymbols = Object.getOwnPropertySymbols(obj);

console.log(objectSymbols.length); // 2
console.log(objectSymbols); // [Symbol(a), Symbol(b)]
console.log(objectSymbols[0]); // Symbol(a)
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.getownpropertysymbols |

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

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

같이 보기
-----

* `Object.getOwnPropertySymbols`의 폴리필은 `core-js`에서 사용할 수 있습니다.
* `Object.getOwnPropertyNames()`
* `Symbol`


Object.defineProperty() - JavaScript

Object.defineProperty()
=======================

**`Object.defineProperty()`** 정적 메서드는 객체에 새로운 속성을 직접 정의하거나 이미 존재하는 속성을 수정한 후, 해당 객체를 반환합니다.

시도해보기
-----

구문
--

```js
Object.defineProperty(obj, prop, descriptor);
```

### 매개변수

`obj`

속성을 정의할 객체.

`prop`

새로 정의하거나 수정하려는 속성의 이름 또는 `Symbol`.

`descriptor`

새로 정의하거나 수정하려는 속성을 기술하는 객체.

### 반환 값

`obj` 객체.

설명
--

`defineProperty` 메서드를 사용하면 객체의 속성을 세밀하게 추가하거나 수정할 수 있습니다. 할당을 통해 속성을 추가하는 일반적인 방법으로 추가한 속성은 객체의 속성을 열거(`for...in` 반복문 또는 `Object.keys` 메서드)할 때 노출되며, 원하는대로 값을 변경하고 `delete` (en-US) 연산자로 삭제할 수도 있습니다. `defineProperty`를 사용하면 이런 기본 동작까지도 상세하게 조절할 수 있습니다. `Object.defineProperty()`로 추가한 속성은 기본적으로 불변하며 열거 불가능합니다.

속성 서술자(`descriptor`)는 데이터 서술자(data descriptors)와 접근자 서술자(accessor descriptors) 두 가지 형식을 취할 수 있습니다. **데이터 서술자**는 값을 가지는 속성을 기술할 때 사용합니다. **접근자 서술자**는 접근자(getter)-설정자(setter) 함수를 한 쌍으로 가지는 속성을 기술할 때 사용합니다. 서술자는 두 유형 중 하나여야 하며, 두 유형을 동시에 나타낼 수는 없습니다.

데이터 서술자와 접근자 서술자는 모두 객체로, 다음의 선택적 키를 서로 공유합니다.

**참고:** 아래에서 설명하는 **기본 값**은 `Object.defineProperty()`로 정의한 속성의 기본 동작을 의미합니다.

`configurable`

속성의 값을 변경할 수 있고, 객체에서 삭제할 수도 있으면 `true`입니다. **기본 값은 `false`입니다.**

`enumerable`

속성이 객체의 속성 열거 시 노출되면 `true`입니다. **기본 값은 `false`입니다.**

**데이터 서술자**는 다음의 키를 선택적으로 포함할 수 있습니다.

`value`

속성에 연관된 값입니다. 유효한 JavaScript 값(숫자, 객체, 함수 등)은 모두 사용할 수 있습니다. **기본 값은 `undefined`입니다.**

`writable`

할당 연산자 (en-US)로 속성의 값을 바꿀 수 있으면 `true`입니다. **기본 값은 `false`입니다.**

**접근자 서술자**는 다음 키를 선택사항으로 가집니다.

`get`

속성의 접근자로 사용할 함수입니다. 접근자가 없으면 `undefined`입니다. 이 속성에 접근하면, 접근할 때 사용한 객체(속성의 주인 객체와 다를 수 있음)를 이 함수의 `this`로 설정하고, 매개변수 없이 호출한 뒤 그 반환 값을 이 속성의 값으로 취급합니다. **기본 값은 `undefined`입니다.**

`set`

속성의 설정자로 사용할 함수입니다. 설정자가 없으면 `undefined`입니다. 이 속성에 값을 할당하면, 할당할 때 사용한 객체를 이 함수의 `this`로 설정하고, 한 개의 매개변수(할당 중인 값)로 호출합니다. **기본 값은 `undefined`입니다.**

`value`, `writable`, `get`, `set` 키를 모두 지니고 있지 않은 서술자는 데이터 서술자로 간주합니다. 반면 `value` 또는 `writable`을 `get` 또는 `set` 키와 함께 가지고 있으면 오류가 발생합니다.

위의 각 설정이 서술자의 자체 속성일 필요는 없으며, 서술자가 상속하는 속성도 고려합니다. 기본 값을 확실하게 보존하려면 `Object`를 먼저 동결하거나, 모든 설정을 직접 명시하거나, `Object.create(null)`을 사용해 서술자의 프로토타입이 `null`을 가리키도록 하세요.

```js
// \_\_proto\_\_ 사용
var obj = {};
var descriptor = Object.create(null); // 상속받은 속성 없음
descriptor.value = "static";

// 기본 값은 열거 불가, 설정 불가, 쓰기 불가
Object.defineProperty(obj, "key", descriptor);

// 기본 값 명시하기
Object.defineProperty(obj, "key", {
  enumerable: false,
  configurable: false,
  writable: false,
  value: "static",
});

// 같은 객체를 재활용하기
function withValue(value) {
  var d =
    withValue.d ||
    (withValue.d = {
      enumerable: false,
      writable: false,
      configurable: false,
      value: null,
    });

  // 중복 할당 방지
  if (d.value !== value) d.value = value;

  return d;
}

Object.defineProperty(obj, "key", withValue("static"));

// 객체 동결을 사용할 수 있다면 프로토타입의 변형을 방지하기
// (value, get, set, enumerable, writable, configurable)
(Object.freeze || Object)(Object.prototype);
```

예제
--

### 속성 생성하기

`Object.defineProperty()`는 가리킨 속성이 객체에 존재하지 않으면 서술자를 사용해 속성을 객체에 새로 생성합니다. 서술자의 일부 항목은 생략 가능하며, 생략한 항목에는 기본 값을 사용합니다.

```js
var o = {}; // 새로운 객체 생성

// 값 속성 서술자와 defineProperty로
// 새로운 속성을 추가하는 예시
Object.defineProperty(o, "a", {
  value: 37,
  writable: true,
  enumerable: true,
  configurable: true,
});
// 'a' 속성이 o 객체에 존재하고 값은 37

// 접근자 속성 기술자와 defineProperty로
// 새로운 속성을 추가하는 예시
var bValue = 38;
Object.defineProperty(o, "b", {
  // ES2015 단축 메서드명 사용
  // 아래 코드와 같음
  // get: function() { return bValue; }
  // set: function(newValue) { bValue = newValue; },
  get() {
    return bValue;
  },
  set(newValue) {
    bValue = newValue;
  },
  enumerable: true,
  configurable: true,
});
o.b; // 38
// 'b' 속성이 o 객체에 존재하고 값은 38
// o.b를 재정의하지 않는 이상
// o.b의 값은 항상 bValue와 동일함

// 두 가지를 혼용할 수는 없음
Object.defineProperty(o, "conflict", {
  value: 0x9f91102,
  get: function () {
    return 0xdeadbeef;
  },
});
// TypeError 발생
// value는 데이터 서술자에만,
// get은 접근자 서술자에만 나타날 수 있음
```

### 속성 수정하기

`ObjectdefineProperty()`는 가리킨 속성이 객체에 이미 존재하면, 주어진 서술자와 해당 속성의 기존 설정에 따라 속성의 수정을 시도합니다. 기존 속성의 `configurable` 특성이 `false`일 때, 해당 속성이 "설정 불가능"하다고 말합니다. 접근자 속성이 설정 불가능하면 속성의 모든 특성을 수정할 수 없습니다. 값 속성은 설정 불가능하더라도 `writable` 특성은 바꿀 수 있고, 쓰기 가능한 경우 `value`도 바꿀 수 있습니다. 설정 불가능한 속성의 유형을 변경(값 속성을 접근자 속성으로, 혹은 그 반대로)하는 것은 불가능합니다.

설정 불가능한 속성의 특성을 바꾸려고 시도하면 `TypeError`가 발생합니다. 단, 기존 값이 신규 값과 같거나, 값 속성의 `value`(쓰기 가능할 때)와 `writable`을 수정하는 경우에는 오류가 발생하지 않습니다.

#### `writable` 특성

`writable` 특성이 `false`인 속성은 "쓰기 불가능"하여 다시 할당할 수 없습니다.

```js
var o = {}; // 새로운 객체 생성

Object.defineProperty(o, "a", {
  value: 37,
  writable: false,
});

console.log(o.a); // 37 기록
o.a = 25; // 오류 발생하지 않음
// 단, 엄격 모드에서는 값이 같더라도 오류가 발생했을 것
console.log(o.a); // 37 기록, 25가 할당되지 않음

// 엄격 모드
(function () {
  "use strict";
  var o = {};
  Object.defineProperty(o, "b", {
    value: 2,
    writable: false,
  });
  o.b = 3; // TypeError: "b" is read-only
  return o.b; // 윗줄이 없다면 2 반환
})();
```

위의 예제에서 확인할 수 있듯, 엄격 모드가 아니라면 쓰기 불가능한 속성에 할당을 시도하면 값이 바뀌지도 않고, 오류가 발생하지도 않습니다.

#### `enumerable` 특성

`enumerable` 특성은 `Object.assign()`과 전개 연산자가 속성을 볼 수 있는지, 없는지를 결정합니다. 이에 더해, 비 `Symbol` 속성에 대해서는 `for...in` 반복문과 `Object.keys()`에서의 노출 여부도 추가로 결정합니다.

```js
var o = {};
Object.defineProperty(o, "a", {
  value: 1,
  enumerable: true,
});
Object.defineProperty(o, "b", {
  value: 2,
  enumerable: false,
});
Object.defineProperty(o, "c", {
  value: 3,
}); // enumerable의 기본 값은 false
o.d = 4; // 할당을 통한 생성 시에는
// enumerable의 기본 값이 true
Object.defineProperty(o, Symbol.for("e"), {
  value: 5,
  enumerable: true,
});
Object.defineProperty(o, Symbol.for("f"), {
  value: 6,
  enumerable: false,
});

for (var i in o) {
  console.log(i);
}
// 'a'와 'd' 기록

Object.keys(o); // ['a', 'd']

o.propertyIsEnumerable("a"); // true
o.propertyIsEnumerable("b"); // false
o.propertyIsEnumerable("c"); // false
o.propertyIsEnumerable("d"); // true
o.propertyIsEnumerable(Symbol.for("e")); // true
o.propertyIsEnumerable(Symbol.for("f")); // false

var p = { ...o };
p.a; // 1
p.b; // undefined
p.c; // undefined
p.d; // 4
p[Symbol.for("e")]; // 5
p[Symbol.for("f")]; // undefined
```

#### `configurable` 특성

`configurable` 특성은 객체에서 이 속성을 제거할 수 있는지, 그리고 속성의 (`value`와 `writable`을 제외한) 특성을 바꿀 수 있는지 결정합니다.

```js
var o = {};
Object.defineProperty(o, "a", {
  get() {
    return 1;
  },
  configurable: false,
});

Object.defineProperty(o, "a", {
  configurable: true,
}); // TypeError
Object.defineProperty(o, "a", {
  enumerable: true,
}); // TypeError
Object.defineProperty(o, "a", {
  set() {},
}); // TypeError (set이 undefined였음)
Object.defineProperty(o, "a", {
  get() {
    return 1;
  },
}); // TypeError
// (형태는 같지만 서로 다른 함수이므로)
Object.defineProperty(o, "a", {
  value: 12,
}); // TypeError
// (configurable이 false여도 value는 바꿀 수 있지만, 속성의 기존 get 접근자로 인해 변경 불가)

console.log(o.a); // 1 기록
delete o.a; // 아무 일도 없음
console.log(o.a); // 1 기록
```

`o.a`의 `configurable`이 `true`였다면 오류가 발생하지도 않고, 마지막에 객체에서 삭제도 가능했을 것입니다.

### 속성 추가와 특성 기본 값

속성 추가 시, 각 특성의 기본 값을 적용하는 방식을 중요하게 고려해야 합니다. 일반 속성 접근 구문(`o.a`)에 할당해 속성을 추가하는 것과, `Object.defineProperty()`를 사용해 추가하는 경우의 특성 기본 값은 아래 예제에서 보이듯 서로 다릅니다.

```js
var o = {};

o.a = 1;
// 위의 할당은 아래와 같음
Object.defineProperty(o, "a", {
  value: 1,
  writable: true,
  configurable: true,
  enumerable: true,
});

// 반면...
Object.defineProperty(o, "a", { value: 1 });
// 위 경우 아래와 같음
Object.defineProperty(o, "a", {
  value: 1,
  writable: false,
  configurable: false,
  enumerable: false,
});
```

### 사용자 정의 설정자와 접근자

아래 예제에서는 스스로 값의 변화를 기록하는 속성을 구현합니다. `temperature` 속성에 값을 할당할 때마다 `archive` 배열에 값이 추가됩니다.

```js
function Archiver() {
  var temperature = null;
  var archive = [];

  Object.defineProperty(this, "temperature", {
    get: function () {
      console.log("get!");
      return temperature;
    },
    set: function (value) {
      temperature = value;
      archive.push({ val: temperature });
    },
  });

  this.getArchive = function () {
    return archive;
  };
}

var arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]
```

다음 코드에서는, 접근자가 항상 같은 값을 반환합니다.

```js
var pattern = {
  get() {
    return "무엇을 할당해도 항상 같은 값을 반환합니다";
  },
  set() {
    this.myname = "내 이름";
  },
};

function TestDefineSetAndGet() {
  Object.defineProperty(this, "myproperty", pattern);
}

var instance = new TestDefineSetAndGet();
instance.myproperty = "test";
console.log(instance.myproperty);
// 무엇을 할당해도 항상 같은 값을 반환합니다

console.log(instance.myname); // 내 이름
```

### 속성의 상속

접근자 속성이 상속될 경우, 자식 객체의 속성에 접근하고 수정할 때 부모의 속성 `get`과 `set` 메서드를 호출합니다. 아래와 같이, 두 메서드가 바깥 변수에 값을 저장할 경우 모든 객체 인스턴스가 값을 공유하게 됩니다.

```js
function myclass() {}

var value;
Object.defineProperty(myclass.prototype, "x", {
  get() {
    return value;
  },
  set(x) {
    value = x;
  },
});

var a = new myclass();
var b = new myclass();
a.x = 1;
console.log(b.x); // 1
```

이 문제는 값을 다른 속성에 저장해서 수정할 수 있습니다. `get`과 `set` 메서드에서 `this`는 속성에 접근하거나 수정할 때 사용하는 객체를 가리킵니다.

```js
function myclass() {}

Object.defineProperty(myclass.prototype, "x", {
  get() {
    return this.stored_x;
  },
  set(x) {
    this.stored_x = x;
  },
});

var a = new myclass();
var b = new myclass();
a.x = 1;
console.log(b.x); // undefined
```

접근자 속성과 달리, 값 속성은 프로토타입이 아닌 객체 자체에 설정됩니다. 그러나 부모의 쓰기 불가능한 속성을 상속하는 경우 자식 객체에서도 값을 수정할 수 없습니다.

```js
function myclass() {}

myclass.prototype.x = 1;
Object.defineProperty(myclass.prototype, "y", {
  writable: false,
  value: 1,
});

var a = new myclass();
a.x = 2;
console.log(a.x); // 2
console.log(myclass.prototype.x); // 1
a.y = 2; // 무시, 엄격 모드에서는 오류
console.log(a.y); // 1
console.log(myclass.prototype.y); // 1
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.defineproperty |

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

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

같이 보기
-----

* 속성의 소유권과 열거 가능성 (en-US)
* `Object.defineProperties()`
* `Object.propertyIsEnumerable()`
* `Object.getOwnPropertyDescriptor()`
* `Object.prototype.watch()`
* `Object.prototype.unwatch()`
* `get` (en-US)
* `set` (en-US)
* `Object.create()`
* `Reflect.defineProperty()`


Object.preventExtensions() - JavaScript

Object.preventExtensions()
==========================

**`Object.preventExtensions()`** 메서드는 새로운 속성이 이제까지 객체에 추가되는 것을 방지합니다 (즉 객체의 장래 확장을 막습니다).

시도해보기
-----

구문
--

```js
Object.preventExtensions(obj);
```

### 매개변수

`obj`

확장 불가로 해야 할 객체.

설명
--

객체는 새로운 속성이 추가될 수 있는 경우 확장 가능입니다. `Object.preventExtensions()`는 객체를 이제 확장 불가로 표시하므로 표시된 그 시점에 있던 것 이외의 속성을 갖지 않습니다. 보통 확장 불가인 객체의 속성은 여전히 *삭제될* 수 있음을 주의하세요. 확장 불가인 객체에 새로운 속성을 추가하려는 시도는 실패합니다, 조용히든 `TypeError`가 발생해서든 (가장 흔하나 오로지 엄격 모드 (en-US)인 경우에서만은 아님).

`Object.preventExtensions()`는 자신의 속성 추가만을 방지합니다. 속성은 여전히 객체의 프로토타입에 추가될 수 있습니다. 그러나, 객체에 `Object.preventExtensions()`를 호출하면 그 `Object.prototype.__proto__`
지원이 중단되었습니다
 속성의 확장 또한 막습니다.

ECMAScript 5에서 확장 가능 객체를 확장 불가로 바꾸는 법이 있더라도, 반대로 하는 법은 없습니다.

예제
--

```js
// Object.preventExtensions는 확장 불가된 객체를 반환합니다.
var obj = {};
var obj2 = Object.preventExtensions(obj);
obj === obj2; // true

// 객체는 기본으로 확장 가능입니다.
var empty = {};
Object.isExtensible(empty); // === true

// ...하지만 바뀔 수 있습니다.
Object.preventExtensions(empty);
Object.isExtensible(empty); // === false

// Object.defineProperty는 확장 불가 객체에 새 속성을 추가할 때 오류가 발생합니다.
var nonExtensible = { removable: true };
Object.preventExtensions(nonExtensible);
Object.defineProperty(nonExtensible, "new", { value: 8675309 }); // TypeError 발생

// 엄격 모드에서, 확장 불가 객체에 새 속성을 추가하려는 시도는 TypeError가 발생합니다.
function fail() {
  "use strict";
  nonExtensible.newProperty = "FAIL"; // TypeError 발생
}
fail();

// 확장 (\_\_proto\_\_(는 사라집니다. 대신 Object.getPrototypeOf를 쓰세요)를
// 지원하는 엔진에서만 동작합니다):
// 확장 불가 객체의 프로토타입은 불변합니다.
var fixed = Object.preventExtensions({});
fixed.__proto__ = { oh: "hai" }; // TypeError 발생
```

참고
--

ES5에서, 이 메서드의 인수가 비객체(원시형)인 경우, 그러면 `TypeError`가 발생합니다. ES6에서, 비객체 인수는 마치 확장 불가인 보통 객체였던 것처럼 취급됩니다, 그저 자신을 반환하는.

```js
Object.preventExtensions(1);
// TypeError: 1은 객체가 아닙니다 (ES5 코드)

Object.preventExtensions(1);
// 1 (ES6 코드)
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.preventextensions |

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

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

같이 보기
-----

* `Object.isExtensible()`
* `Object.seal()`
* `Object.isSealed()`
* `Object.freeze()`
* `Object.isFrozen()`
* `Reflect.preventExtensions()`


Object.is() - JavaScript

Object.is()
===========

**`Object.is()`** 정적 메서드는 두 값이 같은 값인지 결정합니다.

시도해보기
-----

구문
--

```js
Object.is(value1, value2);
```

### 매개변수

`value1`

비교할 첫 번째 값.

`value2`

비교할 두 번째 값.

### 반환 값

두 인수가 같은 값인지 여부를 나타내는 불리언.

설명
--

`Object.is()`는 두 값이 같은 값인지 결정합니다. 다음 중 하나를 만족하면 두 값은 같습니다.

* 둘 다 `undefined`
* 둘 다 `null`
* 둘 다 `true` 또는 둘 다 `false`
* 둘 다 같은 순서로 같은 문자에 같은 길이인 문자열
* 둘 다 같은 객체 (두 값 모두 메모리에서 같은 객체를 참조하는 것을 의미)
* 둘 다 숫자이며
    + 둘 다 `+0`
    + 둘 다 `-0`
    + 둘 다 `NaN`
    + 둘 다 0이나 `NaN`이 아니고, 같은 값을 지님

`Object.is()`는 `==` 연산자와 같지 않습니다. `==` 연산자는 같음을 테스트하기 전에 양 쪽(이 같은 형이 아니라면)에 다양한 강제(coercion)를 적용하지만(`"" == false`가 `true`가 되는 것과 같은 행동을 초래), `Object.is`는 어느 값도 강제하지 않습니다.

`Object.is()`는 `===` (en-US) 연산자와도 같지 않습니다. `Object.is()`와 `===`의 유일한 차이는 부호 있는 0과 `NaN` 값들의 처리입니다. `===` 연산자(및 `==` 연산자)는 숫자값 `-0`과 `+0`을 같게 처리하지만, `NaN`은 서로 같지 않게 처리합니다.

예제
--

### Object.is() 사용

```js
// Case 1: 평가 결과는 ===을 사용한 것과 동일합니다
Object.is(25, 25); // true
Object.is("foo", "foo"); // true
Object.is("foo", "bar"); // false
Object.is(null, null); // true
Object.is(undefined, undefined); // true
Object.is(window, window); // true
Object.is([], []); // false
const foo = { a: 1 };
const bar = { a: 1 };
const sameFoo = foo;
Object.is(foo, foo); // true
Object.is(foo, bar); // false
Object.is(foo, sameFoo); // true

// Case 2: 부호 있는 0
Object.is(0, -0); // false
Object.is(+0, -0); // false
Object.is(-0, -0); // true

// Case 3: NaN
Object.is(NaN, 0 / 0); // true
Object.is(NaN, Number.NaN); // true
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.is |

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

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

같이 보기
-----

* `core-js`의 `Object.is` 폴리필
* 동치 비교 및 동일성 — 동일성 내장 기능 3가지 모두 비교


Object.getOwnPropertyDescriptors() - JavaScript

Object.getOwnPropertyDescriptors()
==================================

**`Object.getOwnPropertyDescriptors()`** 메서드는 주어진 객체의 모든 속성들의 설명자(descriptor)들을 반환합니다.

시도해보기
-----

구문
--

```js
Object.getOwnPropertyDescriptors(obj);
```

### 매개변수

`obj`

가지고 있는 모든 속성들의 설명자를 반환받고 싶은 객체

### 반환 값

객체의 모든 속성의 설명자를 가지는 객체를 반환합니다. 매개변수 객체에 속성이 없다면, 빈 객체가 반환됩니다.

설명
--

 이 메서드를 사용하면, 객체의 모든 속성들에 대한 설명자를 정확하게 확인할 수 있습니다.
 JavaScript의 *속성*은 문자열로된 이름 또는 심볼, 그리고 속성 설명자로 이루어져 있습니다.
 속성 설명자 종류와 특성에 대한 자세한 정보는 `Object.defineProperty()`에 있습니다..

*속성 설명자* 는 다음과 같은 특징들을 가진 레코드입니다.

`value`

속성과 관련된 값입니다. (데이터 설명자만 해당됨)

`writable`

`참(true)`인 경우, 속성과 관련된 값이 변경될 수 있는 상태입니다. (데이터 설명자만 해당됨)

`get`

 속성에 대한 getter 역할을 하는 함수거나, getter가 정의되지 않은 경우에는 `undefined` 입니다.
 (접근자 설명자만 해당됨)

`set`

 속성에 대한 setter 역할을 하는 함수거나, setter 정의되지 않은 경우에는 `undefined` 입니다.
 (접근자 설명자만 해당됨)

`configurable`

`참(true)`인 경우, 객체로 부터 속성 설명자가 변경 및 삭제될 수 있는 상태입니다.

`enumerable`

`true`인 경우, 열거 가능한 상태의 속성입니다.

예시
--

### 얕은 복사하기

`Object.assign()` 메서드는 원본 객체에서 목표 객체로 열거 가능한 속성과 객체의 속성들만 복사하는 반면,
 이 메서드와 `Object.create()` 를 사용하면 어느 두 객체를 얕은 복사에 사용할 수 있습니다.

```js
Object.create(
  Object.getPrototypeOf(obj),
  Object.getOwnPropertyDescriptors(obj),
);
```

### 서브클래스 만들기

 서브클래스를 만드는 일반적인 방법은 서브클래스를 정의하고, 프로토타입을 슈퍼 클래스의 인스턴스로 설정한 다음, 그 인스턴스에 속성을 정의하는 것입니다.
 이 방법은 게터와 세터의 경우 굉장히 불편합니다. 대신, 다음 코드를 사용하여 프로토타입을 설정할 수 있습니다.

```js
function superclass() {}
superclass.prototype = {
  // 여기에 슈퍼 클래스의 생성자, 매서드, 속성을 정의합니다.
};
function subclass() {}
subclass.prototype = Object.create(superclass.prototype, {
  // 여기에 서브클래스의 생성자, 매서드, 속성을 정의합니다.
});
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.getownpropertydescriptors |

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

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

같이 보기
-----

* `Object.getOwnPropertyDescriptors`의 폴리필은 다음에서 확인 할 수 있습니다. `core-js`
* `Object.getOwnPropertyDescriptor()`
* `Object.defineProperty()`
* Polyfill


Object.keys() - JavaScript

Object.keys()
=============

**`Object.keys()`** 메서드는 주어진 객체의 속성 이름들을 일반적인 반복문과
 동일한 순서로 순회되는 열거할 수 있는 배열로 반환합니다.

시도해보기
-----

구문
--

```js
Object.keys(obj)
```

### 매개변수

`obj`

객체

### 반환 값

주어진 객체 자체의 열거 가능한 문자열로된 속성 키를 나타내는 문자열 배열.

설명
--

`Object.keys()`는 `object` 에서 직접 찾은 열거 가능한 문자열 키 속성 이름에 해당하는 문자열을 요소로 하는
 배열을 반환합니다. 이는 `for...in` 루프가 프로토타입 체인의 속성도 열거한다는 점을 제외하면
 `for...in` 루프를 사용하여 반복하는 것과 동일합니다.
 `Object.keys()`가 반환하는 배열의 순서는 `for...in`
 루프에서 제공하는 것과 동일합니다.

 속성 값이 필요한 경우 `Object.values()`를 대신 사용하시기 바랍니다.
 속성 키와 값이 모두 필요한 경우 `Object.entries()`를 대신 사용하시기 바랍니다.

예제
--

### Object.keys() 사용하기

```js
// 단순 배열
const arr = ["a", "b", "c"];
console.log(Object.keys(arr)); // console: ['0', '1', '2']

// 배열형 객체
const obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.keys(obj)); // console: ['0', '1', '2']

// 키와 순서가 무작위인 유사 배열 객체
const anObj = { 100: "a", 2: "b", 7: "c" };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']

// getFoo 는 열거할 수 없는 속성입니다.
const myObj = Object.create(
  {},
  {
    getFoo: {
      value() {
        return this.foo;
      },
    },
  },
);
myObj.foo = 1;
console.log(Object.keys(myObj)); // ['foo']
```

 만약 열거할 수 없는 속성도 포함한 문자열이 키인 객체 자체 속성을 원한다면,
 `Object.getOwnPropertyNames()`을 참고하시기 바랍니다.

### 원시형애서 Object.keys() 사용하기

 객체가 아닌 인수는 강제로 객체로 변환됩니다.
 문자열만 자체 열거 가능한 속성을 가질 수 있으며, 다른 모든 원시형은 빈 배열을 반환합니다.

```js
// 문자열은 열거가능한 자체 속성처럼 인덱스를 가지고 있습니다.
console.log(Object.keys("foo")); // ['0', '1', '2']

// 다른 원시형은 자체 속성이 없숩니다.
console.log(Object.keys(100)); // []
```

**참고:** ES5에서는 비객체를 `Object.keys()`에 전달하면 `TypeError`가 발생합니다.

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.keys |

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

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

같이 보기
-----

* `Object.keys` 의 폴리필 코드는 아래에서 확인할 수 있습니다. `core-js`
* Enumerability and ownership of properties (en-US)
* `Object.entries()`
* `Object.values()`
* `Object.prototype.propertyIsEnumerable()`
* `Object.create()`
* `Object.getOwnPropertyNames()`
* `Map.prototype.keys()`


Object.prototype.propertyIsEnumerable() - JavaScript

Object.prototype.propertyIsEnumerable()
=======================================

**`propertyIsEnumerable()`** 메서드는 특정 속성이 열거가능한지 여부를 나타내는 불리언 값을 반환합니다.

시도해보기
-----

구문
--

```js
obj.propertyIsEnumerable(prop);
```

### 매개변수

`prop`

테스트 할 속성의 이름.

### 반환 값

특정 속성이 열거가능한지 여부를 나타내는 `Boolean`.

설명
--

모든 객체는 `propertyIsEnumerable` 메소드를 가지고 있습니다. 이 메소드는 프로토타입 체인을 통해 상속된 특성을 제외하고 개체에 지정된 속성을 `for...in` 루프로 열거할 수 있는지 여부를 확인할 수 있습니다. 개체에 지정된 속성이 없으면 이 메소드는 `false`를 반환합니다.

예제
--

### A basic use of `propertyIsEnumerable`

The following example shows the use of `propertyIsEnumerable` on objects and arrays:

```js
var o = {};
var a = [];
o.prop = "is enumerable";
a[0] = "is enumerable";

o.propertyIsEnumerable("prop"); // returns true
a.propertyIsEnumerable(0); // returns true
```

### User-defined versus built-in objects

The following example demonstrates the enumerability of user-defined versus built-in properties:

```js
var a = ["is enumerable"];

a.propertyIsEnumerable(0); // returns true
a.propertyIsEnumerable("length"); // returns false

Math.propertyIsEnumerable("random"); // returns false
this.propertyIsEnumerable("Math"); // returns false
```

### Direct versus inherited properties

```js
var a = [];
a.propertyIsEnumerable("constructor"); // returns false

function firstConstructor() {
  this.property = "is not enumerable";
}

firstConstructor.prototype.firstMethod = function () {};

function secondConstructor() {
  this.method = function method() {
    return "is enumerable";
  };
}

secondConstructor.prototype = new firstConstructor();
secondConstructor.prototype.constructor = secondConstructor;

var o = new secondConstructor();
o.arbitraryProperty = "is enumerable";

o.propertyIsEnumerable("arbitraryProperty"); // returns true
o.propertyIsEnumerable("method"); // returns true
o.propertyIsEnumerable("property"); // returns false

o.property = "is enumerable";

o.propertyIsEnumerable("property"); // returns true

// These return false as they are on the prototype which
// propertyIsEnumerable does not consider (even though the last two
// are iteratable with for-in)
o.propertyIsEnumerable("prototype"); // returns false (as of JS 1.8.1/FF3.6)
o.propertyIsEnumerable("constructor"); // returns false
o.propertyIsEnumerable("firstMethod"); // returns false
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.propertyisenumerable |

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

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

같이 보기
-----

* Enumerability and ownership of properties (en-US)
* `for...in`
* `Object.keys()`
* `Object.defineProperty()`


Object.getPrototypeOf() - JavaScript

Object.getPrototypeOf()
=======================

**`Object.getPrototypeOf()`** 메서드는 지정된 객체의 프로토타입(가령 내부 `[[Prototype]]` 속성값)을 반환합니다.

구문
--

```js
Object.getPrototypeOf(obj);
```

### 매개변수

`obj`

자신의 프로토타입이 반환되는 객체.

예
-

```js
var proto = {};
var obj = Object.create(proto);
Object.getPrototypeOf(obj) === proto; // true
```

주의
--

ES5에서, `obj` 매개변수가 객체가 아닌 경우 `TypeError` 예외가 발생합니다. ES6에서, 매개변수는 `Object`로 강제됩니다.

```js
Object.getPrototypeOf("foo");
// TypeError: "foo"는 객체가 아닙니다 (ES5 코드)
Object.getPrototypeOf("foo");
// String.prototype (ES6 코드)
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.getprototypeof |

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

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

Opera 전용 주의사항
-------------

이전 Opera 버전이 `Object.getPrototypeOf()`를 아직 지원하지 않지만, Opera는 Opera 10.50 이후로 비표준 `Object.prototype.__proto__` 속성을 지원합니다.

참조
--

* `Object.prototype.isPrototypeOf()`
* `Object.setPrototypeOf()` (en-US)
* `Object.prototype.__proto__`
* John Resig의 getPrototypeOf 포스트
* `Reflect.getPrototypeOf()`


Object.getOwnPropertyDescriptor() - JavaScript

Object.getOwnPropertyDescriptor()
=================================

**`Object.getOwnPropertyDescriptor()`** 메서드는 주어진 객체 *자신의 속성*(즉, 객체에 직접 제공하는 속성, 객체의 프로토타입 체인을 따라 존재하는 덕택에 제공하는 게 아닌)에 대한 속성 설명자(descriptor)를 반환합니다.

구문
--

```js
Object.getOwnPropertyDescriptor(obj, prop);
```

### 매개변수

`obj`

속성을 찾을 대상 객체.

`prop`

설명이 검색될 속성명.

### 반환값

객체에 존재하는 경우 주어진 속성의 속성 설명자, 없으면 `undefined`.

설명
--

이 메서드는 정확한 속성 설명의 검사를 허용합니다. JavaScript에서 *속성*은 문자열 값인 이름과 속성 설명자로 구성됩니다. 속성 설명자 유형과 attribute에 관한 자세한 정보는 `Object.defineProperty()`에서 찾을 수 있습니다.

*속성 설명자*는 다음 attribute 중 일부의 기록입니다:

`value`

속성과 관련된 값 (데이터 설명자만).

**`writable`**

속성과 관련된 값이 변경될 수 있는 경우에만 `true` (데이터 설명자만).

`get`

속성에 대해 getter로서 제공하는 함수 또는 getter가 없는 경우 `undefined` (접근자 설명자만).

`set`

속성에 대해 setter로서 제공하는 함수 또는 setter가 없는 경우 `undefined` (접근자 설명자만).

`configurable`

이 속성 설명자의 유형이 바뀔 수 있는 경우에만 그리고 속성이 해당 객체에서 삭제될 수 있는 경우 `true`.

`enumerable`

이 속성이 해당 객체의 속성 열거 중에 나타나는 경우에만 `true`.

예
-

```js
var o, d;

o = {
  get foo() {
    return 17;
  },
};
d = Object.getOwnPropertyDescriptor(o, "foo");
// d는 { configurable: true, enumerable: true, get: /\* getter 함수 \*/, set: undefined }

o = { bar: 42 };
d = Object.getOwnPropertyDescriptor(o, "bar");
// d는 { configurable: true, enumerable: true, value: 42, writable: true }

o = {};
Object.defineProperty(o, "baz", {
  value: 8675309,
  writable: false,
  enumerable: false,
});
d = Object.getOwnPropertyDescriptor(o, "baz");
// d는 { value: 8675309, writable: false, enumerable: false, configurable: false }
```

주의
--

ES5에서, 이 메서드의 첫 번째 인수가 비객체(원시형)인 경우, 그러면 `TypeError`가 발생합니다. ES6에서, 비객체 첫 번째 인수는 먼저 객체로 강제됩니다.

```js
Object.getOwnPropertyDescriptor("foo", 0);
// TypeError: "foo"는 객체가 아닙니다 // ES5 코드

Object.getOwnPropertyDescriptor("foo", 0);
// {configurable:false, enumerable:true, value:"f", writable:false} // ES6 코드
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.getownpropertydescriptor |

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

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

참조
--

* `Object.defineProperty()`
* `Reflect.getOwnPropertyDescriptor()`


Object.seal() - JavaScript

Object.seal()
=============

**`Object.seal()`** 메서드는 객체를 밀봉합니다. 객체를 밀봉하면 그 객체에는 새로운 속성을 추가할 수 없고, 현재 존재하는 모든 속성을 설정 불가능 상태로 만들어줍니다. 하지만 쓰기 가능한 속성의 값은 밀봉 후에도 변경할 수 있습니다(역자 주 : 바로 이 점이 `Object.freeze()`와의 차이라고 할 수 있습니다).

시도해보기
-----

구문
--

```js
Object.seal(obj);
```

### 매개변수

`obj`

봉인할 객체.

### 반환 값

봉인한 객체.

설명
--

객체는 기본적으로 확장이 가능(extensible)합니다. 즉, 새로운 속성을 추가할 수 있습니다. 하지만 객체를 밀봉하면 그 객체에 새로운 속성을 추가할 수 없게되고, 그 객체 내에 존재하는 모든 속성이 설정 불가능(non-configurable)해 집니다. 객체를 밀봉하면 객체의 속성을 고정된 불변의 상태로 만듭니다. 모든 속성을 설정 불가능한 상태로 만드는 것은 데이터 속성(data properties)을 접근자 속성(accessor properties)으로, 또는 접근자 속성을 데이터 속성으로 변경할 수 없게 만듭니다. 하지만 객체를 완전히 얼려서 데이터 속성의 값도 변경할 수 없게 만드는 `Object.freeze()`와 달리, `Object.seal()`은 객체를 밀봉한 후에도 그 객체의 데이터 속성의 값은 여전히 변경할 수 있게 해줍니다. 다만, 밀봉한 후에는 객체를 얼리는 것과 마찬가지로 속성의 추가/삭제나 데이터 속성과 접근자 속성 사이의 전환은 암묵적이든, 아니면 strict mode 에서와 같이 명시적으로 `TypeError` 예외를 발생시키든 모두 실패로 끝납니다.

프로토타입 체인은 밀봉 전이나 후나 달라지지 않습니다. 하지만 `Object.prototype.__proto__`
지원이 중단되었습니다
 속성은 함께 밀봉됩니다.

예제
--

```js
var obj = {
  prop: function () {},
  foo: "bar",
};

// 새 속성이 추가되고, 기존 속성은 변경되거나 제거될 수 있음
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;

var o = Object.seal(obj);

assert(o === obj);
assert(Object.isSealed(obj) === true);

// 밀봉한 객체의 속성값은 밀봉 전과 마찬가지로 변경할 수 있음
obj.foo = "quux";
obj.foo; // 'quux' 가 출력됨

// 데이터 속성과 접근자 속성 사이의 전환은 불가
Object.defineProperty(obj, "foo", {
  get: function () {
    return "g";
  },
}); // TypeError 발생

// 속성값의 변경을 제외한 어떤 변경도 적용되지 않음
obj.quaxxor = "the friendly duck"; // 에러가 나지는 않지만 속성은 추가되지 않음
delete obj.foo; // 에러가 나지는 않지만 속성이 삭제되지 않음

// strict mode 에서는 속성값의 변경을 제외한 모든 변경은 TypeError 발생
function fail() {
  "use strict";
  delete obj.foo; // TypeError 발생
  obj.sparky = "arf"; // TypeEror 발생
}
fail();

// Object.defineProperty() 메서드를 이용한 속성의 추가도 TypeError 발생
Object.defineProperty(obj, "ohai", { value: 17 }); // TypeErorr 발생
Object.defineProperty(obj, "foo", { value: "eit" }); // 속성값의 변경은 가능함
```

참고
--

ES5에서는 **`Object.seal()`** 메서드의 인자가 객체가 아닐 때(즉, 원시형일 때)는 `TypeError`가 발생합니다. ES6에서는 원시형 인자도 밀봉된 객체라고 취급해서 `TypeError`를 발생시키지 않고 원시형 인자를 그대로 반환합니다.

```js
> Object.seal(1)
TypeError: 1 is not an object // ES5 code

> Object.seal(1)
1                             // ES6 code
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.seal |

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

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

같이 보기
-----

* `Object.isSealed()`
* `Object.preventExtensions()`
* `Object.isExtensible()`
* `Object.freeze()`
* `Object.isFrozen()`


Object.isSealed() - JavaScript

Object.isSealed()
=================

**`Object.isSealed()`** 메서드는 객체가 봉인됐는지 판별합니다.

시도해보기
-----

구문
--

```js
Object.isSealed(obj);
```

### 매개변수

`obj`

판별할 객체.

### 반환 값

객체의 봉인 여부를 나타내는 `Boolean`.

설명
--

객체가 봉인된 경우 `true`를 반환하고, 그렇지 않으면 `false`. 객체는 확장 불가이고 모든 속성이 설정 불가이며 따라서 삭제할 수 없(지만 반드시 쓰기 불가일 필요는 없)는 경우 봉인됩니다.

예제
--

```js
// 객체는 기본으로 봉인되지 않습니다.
var empty = {};
Object.isSealed(empty); // === false

// 빈 객체를 확장 불가하게 한 경우, 빈 채로 봉인됩니다.
Object.preventExtensions(empty);
Object.isSealed(empty); // === true

// 비어 있지 않은 객체는 다릅니다, 그 속성이 모두 설정 불가가 아닌 한.
var hasProp = { fee: "fie foe fum" };
Object.preventExtensions(hasProp);
Object.isSealed(hasProp); // === false

// 그러나 모두 설정 불가하게 하면 객체는 봉인됩니다.
Object.defineProperty(hasProp, "fee", { configurable: false });
Object.isSealed(hasProp); // === true

// 객체를 봉인하는 가장 쉬운 방법은 물론 Object.seal 입니다.
var sealed = {};
Object.seal(sealed);
Object.isSealed(sealed); // === true

// 봉인된 객체는 정의에 의해 확장 불가입니다.
Object.isExtensible(sealed); // === false

// 봉인된 객체는 동결될 수 있지만 꼭 그럴 필요는 없습니다.
Object.isFrozen(sealed); // === true (모든 속성도 쓰기 불가)

var s2 = Object.seal({ p: 3 });
Object.isFrozen(s2); // === false ('p'는 여전히 쓰기 가능)

var s3 = Object.seal({
  get p() {
    return 0;
  },
});
Object.isFrozen(s3); // === true (설정 가능성만이 접근자 속성에게 중요함)
```

주의
--

ES5에서, 이 메서드의 인수가 비객체(원시형)인 경우, 그러면 `TypeError`가 발생합니다. ES6에서, 비객체 인수는 마치 봉인된 보통 객체였던 것처럼 취급됩니다, 그저 `true`를 반환하는.

```js
Object.isSealed(1);
// TypeError: 1은 객체가 아닙니다 (ES5 코드)

Object.isSealed(1);
// true (ES6 코드)
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.issealed |

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

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

같이 보기
-----

* `Object.seal()`
* `Object.preventExtensions()`
* `Object.isExtensible()`
* `Object.freeze()`
* `Object.isFrozen()`


Object.create() - JavaScript

Object.create()
===============

**`Object.create()`** 메서드는 지정된 프로토타입 객체 및 속성(property)을 갖는 새 객체를 만듭니다.

구문
--

```js
Object.create(proto[, propertiesObject])
```

### 매개변수

`proto`

새로 만든 객체의 프로토타입이어야 할 객체.

`propertiesObject`

선택사항. 지정되고 `undefined`가 아니면, 자신의 속성(즉, 자체에 정의되어 그 프로토타입 체인에서 열거가능하지 *않은* 속성)이 열거가능한 객체는 해당 속성명으로 새로 만든 객체에 추가될 속성 설명자(descriptor)를 지정합니다. 이러한 속성은 `Object.defineProperties()`의 두 번째 인수에 해당합니다.

### 반환값

지정된 프로토타입 개체와 속성을 갖는 새로운 개체.

### 예외

`proto` 매개변수가 `null` 또는 객체가 아닌 경우 `TypeError` 예외가 발생(throw).

예
-

### `Object.create()`를 사용한 고전적인 상속방법

아래는 고전적인 상속방법으로 사용된 `Object.create()` 사용 예입니다. 이는 단일 상속 용으로, JavaScript가 지원하는 전부입니다.

```js
// Shape - 상위클래스
function Shape() {
  this.x = 0;
  this.y = 0;
}

// 상위클래스 메서드
Shape.prototype.move = function (x, y) {
  this.x += x;
  this.y += y;
  console.info("Shape moved.");
};

// Rectangle - 하위클래스
function Rectangle() {
  Shape.call(this); // super 생성자 호출.
}

// 하위클래스는 상위클래스를 확장
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

console.log("Is rect an instance of Rectangle?", rect instanceof Rectangle); // true
console.log("Is rect an instance of Shape?", rect instanceof Shape); // true
rect.move(1, 1); // Outputs, 'Shape moved.'
```

여러 객체에서 상속하고 싶은 경우엔 mixin이 사용가능합니다.

```js
function MyClass() {
  SuperClass.call(this);
  OtherSuperClass.call(this);
}

MyClass.prototype = Object.create(SuperClass.prototype); // 상속
mixin(MyClass.prototype, OtherSuperClass.prototype); // mixin

MyClass.prototype.myMethod = function () {
  // 기능 수행
};
```

`mixin` 함수는 상위(super)클래스 프로토타입에서 하위(sub)클래스 프로토타입으로 함수를 복사하고, mixin 함수는 사용자에 의해 공급될 필요가 있습니다. mixin 같은 함수의 예는 jQuery.extend()입니다.

### `Object.create()`와 함께 `propertiesObject` 인수 사용하기

```js
var o;

// 프로토타입이 null인 객체 생성
o = Object.create(null);

o = {};
// 위는 아래와 같습니다:
o = Object.create(Object.prototype);

// 샘플 속성 두개를 갖는 객체를 만드는 예.
// (두 번째 매개변수는 키를 \*속성 설명자\*에 맵핑함을 주의하세요.)
o = Object.create(Object.prototype, {
  // foo는 정규 '값 속성'
  foo: { writable: true, configurable: true, value: "hello" },
  // bar는 접근자(accessor, getter-및-setter) 속성
  bar: {
    configurable: false,
    get: function () {
      return 10;
    },
    set: function (value) {
      console.log("Setting `o.bar` to", value);
    },
    /\* ES5 접근자로 코드는 이렇게 할 수 있습니다
 get function() { return 10; },
 set function(value) { console.log('setting `o.bar` to', value); } \*/
  },
});

function Constructor() {}
o = new Constructor();
// 위는 아래와 같습니다:
o = Object.create(Constructor.prototype);
// 물론, 생성자 함수에 실제 초기화 코드가 있다면
// Object.create()는 그것을 반영할 수 없습니다

// 빈 새 객체가 프로토타입인 새 객체를 만들고
// 값이 42인 단일 속성 'p' 추가.
o = Object.create({}, { p: { value: 42 } });

// 기본으로 writable, enumerable 또는 configurable 속성은 false:
o.p = 24;
o.p;
// 42

o.q = 12;
for (var prop in o) {
  console.log(prop);
}
// 'q'

delete o.p;
// false

// ES3 속성을 지정하기 위해
o2 = Object.create(
  {},
  {
    p: {
      value: 42,
      writable: true,
      enumerable: true,
      configurable: true,
    },
  },
);
```

폴리필
---

이 폴리필에서는 새 개체에 대한 프로토타입이 선택되었지만 두번째 인수가 없이 개체를 생성하는 사례를 보여줍니다.

`[[Prototype]]`에 `null` 을 설정하는 것이 실제 ES5 `Object.create`에서는 지원되지만, ECMAScript 5 보다 낮은 버전에서는 상속에 제한이 있기 때문에 이 폴리필에서는 지원할 수 없음에 주의하세요.

```js
if (typeof Object.create != "function") {
  Object.create = (function (undefined) {
    var Temp = function () {};
    return function (prototype, propertiesObject) {
      if (prototype !== Object(prototype) && prototype !== null) {
        throw TypeError("Argument must be an object, or null");
      }
      Temp.prototype = prototype || {};
      if (propertiesObject !== undefined) {
        Object.defineProperties(Temp.prototype, propertiesObject);
      }
      var result = new Temp();
      Temp.prototype = null;
      // Object.create(null)인 경우 모방
      if (prototype === null) {
        result.__proto__ = null;
      }
      return result;
    };
  })();
}
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.create |

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

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

참조
--

* `Object.defineProperty()`
* `Object.defineProperties()`
* `Object.prototype.isPrototypeOf()`
* John Resig의 getPrototypeOf() 포스트


Object.prototype.__proto__ - JavaScript

Object.prototype.\_\_proto\_\_
==============================

**지원이 중단되었습니다:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

>
> **주의:** 객체의 `[[Prototype]]`을 변경하는 것은 최신 JavaScript 엔진이 속성 접근을 최적화하는 방식의 특성상 **모든** 브라우저 및 JavaScript 엔진에서 매우 느린 작업입니다. 상속 구조를 변경하는 것이 성능에 미치는 영향은 미묘하고 광범위하며, `obj.__proto__ = ...` 문에 소요되는 시간 뿐만 아니라 `[[Prototype]]`이 변경된 객체에 접근할 수 있는 **모든** 코드들에 대해서도 영향을 줄 수 있습니다. 성능에 관심이 있다면 객체의 `[[Prototype]]` 설정을 피해야 합니다. 대신 `Object.create()`를 사용하여 원하는 `[[Prototype]]`으로 새 객체를 만드세요.
>
>
>

>
> **주의:** `Object.prototype.__proto__`는 오늘날 대부분의 브라우저에서 지원되지만, 그 존재와 정확한 동작은 오직 웹 브라우저와의 호환성을 보장하기 위한 레거시 기능으로서 ECMAScript 2015 사양에서 비로소 표준화되었습니다. 더 나은 지원을 위해 대신 `Object.getPrototypeOf()`를 사용하세요.
>
>
>

`Object.prototype` (en-US)의 `__proto__` 속성은 접근하고자 하는 객체의 내부 속성인 `[[Prototype]]`(객체 또는 `null`)를 노출하는 접근자 속성(getter 및 setter 함수)입니다.

`__proto__`의 사용은 논란의 여지가 있으며 권장하지 않습니다. 원래는 ECMAScript 언어 사양에 포함되지 않았음에도 불구하고 최신 브라우저에서는 이를 구현했습니다. 최근에서야 ECMAScript 2015 사양에서 웹 브라우저와의 호환성을 위해 표준화되었으므로 향후에도 지원은 될 것입니다. 그러나 `__proto__`는 더이상 사용하지 않길 바라며, 대신 `Object.getPrototypeOf` / `Reflect.getPrototypeOf` 및 `Object.setPrototypeOf` (en-US) / `Reflect.setPrototypeOf`를 권장합니다(객체의 `[[Prototype]]` 설정은 성능을 고려할 경우 피해야 하는 느린 작업입니다).

객체 리터럴을 정의할 때 `Object.create()` 대신 `__proto__` 속성을 사용함으로써 객체의 `[[Prototype]]`을 설정할 수도 있습니다. 참고: object initializer / literal syntax.

설명
--

`__proto__` getter 함수는 객체의 내부 `[[Prototype]]` 값을 노출합니다. 객체 리터럴을 사용하여 생성된 객체의 경우 이 값은 `Object.prototype` (en-US)입니다. 배열 리터럴을 사용하여 생성된 객체의 경우 이 값은 `Array.prototype`입니다. 함수의 경우 이 값은 `Function.prototype`입니다. `new fun`을 사용하여 생성된 객체의 경우 (여기서 `fun`은 JavaScript에서 제공하는 내장 생성자 함수 중 하나입니다. `Array`, `Boolean`, `Date`, `Number`, `Object`, `String` 등 - JavaScript가 발전함에 따라 추가된 새로운 생성자 포함) 이 값은 항상 `fun.prototype`입니다. `new fun`을 사용하여 생성된 객체의 경우 `fun`은 스크립트에 정의된 함수이며 이 값은 `fun.prototype`의 값입니다. (즉, 생성자가 다른 객체를 명시적으로 반환하지 않았거나 인스턴스가 생성된 이후에 `fun.prototype`이 다시 할당된 경우입니다.)

`__proto__` setter를 사용하면 객체의 `[[Prototype]]`이 변경될 수 있습니다. 객체는 `Object.isExtensible()`에 따라 확장 가능해야 합니다. 그렇지 않으면 `TypeError`가 발생합니다. 제공된 값은 객체 또는 `null`여야 합니다. 다른 값을 제공하면 아무 효과가 없습니다.

프로토타입이 상속에 사용되는 방식을 이해하려면 가이드 문서 상속과 프로토타입 체인를 참조하세요.

`__proto__` 속성은 getter 및 setter 함수로 구성된 `Object.prototype` (en-US)의 간단한 접근자 속성입니다. `Object.prototype` (en-US)를 참조하는 경우 `__proto__`에 접근하면 `Object.prototype` (en-US)를 찾지만, `Object.prototype` (en-US)를 참조하지 않는 경우에는 찾을 수 없습니다. `Object.prototype` (en-US)보다 먼저 다른 `__proto__` 속성이 발견되는 경우 이 속성에 의해 `Object.prototype` (en-US)는 숨겨집니다.

예제
--

### \_\_proto\_\_ 사용하기

```js
function Circle() {}
const shape = {};
const circle = new Circle();

// Set the object prototype
// DEPRECATED. 예시용일 뿐입니다. 실제 코드에서는 이렇게 하지 마세요.
shape.__proto__ = circle;

// Get the object prototype
console.log(shape.__proto__ === Circle); // false

const ShapeA = function () {};
const ShapeB = {
  a() {
    console.log("aaa");
  },
};
console.log((ShapeA.prototype.__proto__ = ShapeB));

const shapea = new ShapeA();
shapea.a(); // aaa
console.log(ShapeA.prototype === shapea.__proto__); // true

// 또는
const ShapeC = function () {};
const ShapeD = {
  a() {
    console.log("a");
  },
};

const shapeC = new ShapeC();
shapeC.__proto__ = ShapeD;
shapeC.a(); // a
console.log(ShapeC.prototype === shapeC.__proto__); // false

// 또는
function Test() {}
Test.prototype.myname = function () {
  console.log("myname");
};

const a = new Test();
console.log(a.__proto__ === Test.prototype); // true
a.myname(); // myname

// 또는
const fn = function () {};
fn.prototype.myname = function () {
  console.log("myname");
};

var obj = {
  \_\_proto\_\_: fn.prototype,
};

obj.myname(); // myname
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.\_\_proto\_\_ |

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

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

같이 보기
-----

* `Object.prototype.isPrototypeOf()`
* `Object.getPrototypeOf()`
* `Object.setPrototypeOf()` (en-US)


Object.freeze() - JavaScript

Object.freeze()
===============

**`Object.freeze()`** 메서드는 객체를 **동결**합니다. 동결된 객체는 더 이상 변경될 수 없습니다. 즉, 동결된 객체는 새로운 속성을 추가하거나 존재하는 속성을 제거하는 것을 방지하며 존재하는 속성의 불변성, 설정 가능성(configurability), 작성 가능성이 변경되는 것을 방지하고, 존재하는 속성의 값이 변경되는 것도 방지합니다. 또한, 동결 객체는 그 프로토타입이 변경되는것도 방지합니다. `freeze()`는 전달된 동일한 객체를 반환합니다.

시도해보기
-----

구문
--

```js
Object.freeze(obj);
```

### 매개변수

`obj`

동결할 객체.

### 반환 값

함수로 전달된 객체.

설명
--

동결 객체의 속성 집합에는 어떠한 것도 추가하거나 제거할 수 없으며, 그리 하려는 모든 시도는 조용히 넘어가거나, `TypeError` 예외가 발생하며 실패합니다. 예외 발생은 보통 엄격 모드인 경우 발생하지만, 반드시 엄격 모드로만 제한되는 것은 아닙니다.

동결 객체가 가진 데이터 속성에 대해선, 값을 변경할 수 없으며 설정 가능 여부와 쓰기 가능 여부 속성 모두 거짓이 됩니다. 접근자 속성(접근자와 설정자)도 동일하게 동작합니다(또한 값을 변경하고 있다는 환상을 줍니다). 수정되는 값이 객체이고 동결된 것이 아니라면 여전히 수정이 가능함을 유의하세요. 객체로써, 배열도 동결될 수 있습니다. 동결한 이후에는 그 엘리먼트를 변경할 수 없으며 배열에 어떠한 엘리먼트도 추가하거나 제거할 수 없습니다.

`freeze()`는 함수에 전달한 객체를 그대로 반환하며, 동결된 객체 사본을 생성하는 것이 아닙니다.

예제
--

### 객체 동결하기

```js
var obj = {
  prop: function () {},
  foo: "bar",
};

// 동결 이전: 새 속성을 추가할 수 있고,
// 기존 속성을 변경하거나 제거할 수 있음
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;

// 동결
var o = Object.freeze(obj);

// 반환 값은 전달된 객체와 동일함.
o === obj; // true

// 객체가 동결 상태가 됨.
Object.isFrozen(obj); // === true

// 이제 모든 변경 시도는 실패함
obj.foo = "quux"; // 조용하게 아무것도 하지 않음
// 조용하게 속성을 추가하지 않음
obj.quaxxor = "the friendly duck";

// 엄격 모드에서는 이러한 시도에 대해 TypeError 발생
function fail() {
  "use strict";
  obj.foo = "sparky"; // TypeError 발생
  delete obj.foo; // TypeError 발생
  delete obj.quaxxor; // 'quaxxor' 속성은 추가된 적이 없으므로 true 반환
  obj.sparky = "arf"; // TypeError 발생
}

fail();

// Object.defineProperty를 통한 변경 시도
// 아래 두 구문 모두에서 TypeError 발생
Object.defineProperty(obj, "ohai", { value: 17 });
Object.defineProperty(obj, "foo", { value: "eit" });

// 프로토타입을 변경하는 것 또한 불가함
// 아래 두 구문 모두에서 TypeError 발생
Object.setPrototype(obj, { x: 20 });
obj.__proto__ = { x: 20 };
```

### 배열 동결

```js
let a = [0];
Object.freeze(a); // 이제 배열을 수정할 수 없음.

a[0] = 1; // 조용하게 실패
a.push(2); // 조용하게 실패

// 엄격 모드에서는 이런 시도에 대해 TypeError 발생
function fail() {
  "use strict";
  a[0] = 1;
  a.push(2);
}

fail();
```

동결된 객체는 변경할 수 없습니다. 하지만, 꼭 그렇지만은 않습니다. 다음 예제는 동결된 객체가 변경될 수 있음을(얕은 동결) 보여줍니다.

```js
obj = {
  internal: {},
};

Object.freeze(obj);
obj.internal.a = "aValue";

obj.internal.a; // 'aValue'
```

변경될 수 없는 객체가 되려면, 모든 참조 그래프(다른 객체로의 직간접적 참조)가 오로지 불변의 동결 객체만을 참조해야 합니다. 동결된 객체는 객체 내의 모든 상태(다른 객체로의 값과 참조)가 고정되기 때문에 불변하다고 합니다. 문자열, 숫자, 불리언 값은 언제나 불변하고, 함수와 배열은 객체임을 유의하세요.

#### "얕은 동결"이 무엇인가요?

`Object.freeze(object)` 호출의 결과는 `object` 스스로의 직속 속성에만 적용되며, `object`에 대해서만 속성 추가, 제거, 재할당 연산을 방지합니다. 만약 그 속성의 값이 객체라면, 그 객체는 동결되지 않으며 속성 추가, 제거, 재할당의 대상이 될 수 있습니다.

```js
var employee = {
  name: "Mayank",
  designation: "Developer",
  address: {
    street: "Rohini",
    city: "Delhi",
  },
};

Object.freeze(employee);

employee.name = "Dummy"; // 비엄격 모드에서 조용하게 실패
employee.address.city = "Noida"; // 자식 객체의 속성은 수정 가능

console.log(employee.address.city); // 출력: "Noida"
```

객체를 불변하게 만들려면, 각 객체 타입의 속성을 재귀적으로 동결해야합니다(깊은 동결). 객체가 그 참조 그래프에서 순환을 포함하지 않는다는 것을 인지하고 있을 때, 디자인을 기반으로 상황에 따라 패턴을 적용해야하며, 그렇지 않을 경우 반복문이 무한히 실행될 수 있습니다. `deepFreeze()`에 대한 개선은 객체가 불변하게 되는 과정에 있을 때 `deepFreeze()`의 재귀적인 호출을 차단할 수 있도록 경로(예, 배열) 인자를 받는 내부 함수를 소유하는 것입니다. [window]와 같은, 동결되면 안되는 객체를 동결하는 것에 대한 위험은 여전히 남아 있습니다.

```js
function deepFreeze(object) {
  // 객체에 정의된 속성명을 추출
  var propNames = Object.getOwnPropertyNames(object);

  // 스스로를 동결하기 전에 속성을 동결

  for (let name of propNames) {
    let value = object[name];

    object[name] =
      value && typeof value === "object" ? deepFreeze(value) : value;
  }

  return Object.freeze(object);
}

var obj2 = {
  internal: {
    a: null,
  },
};

deepFreeze(obj2);

obj2.internal.a = "anotherValue"; // 비엄격 모드에서 조용하게 실패
obj2.internal.a; // null
```

사용 노트
-----

ES5에서는, 이 메소드에 대한 인자가 객체(원시형)가 아닐 경우, `TypeError`가 발생합니다. ES2015에서는, 비객체 인자가 동결된 평범한 객체인것처럼 다루어져 반환됩니다.

```js
> Object.freeze(1)
TypeError: 1 is not an object // ES5 code

> Object.freeze(1)
1                             // ES2015 code
```

엘리먼트를 갖는 `ArrayBufferView` (en-US)는 메모리를 통한 뷰이므로 다른 가능한 문제를 유발 할 수 있어 `TypeError`가 발생합니다.

```js
> Object.freeze(new Uint8Array(0)) // 엘리먼트가 없음
Uint8Array []

> Object.freeze(new Uint8Array(1)) // 엘리먼트를 가짐
TypeError: Cannot freeze array buffer views with elements

> Object.freeze(new DataView(new ArrayBuffer(32))) // 엘리먼트가 없음
DataView {}

> Object.freeze(new Float64Array(new ArrayBuffer(64), 63, 0)) // 엘리먼트가 없음
Float64Array []

> Object.freeze(new Float64Array(new ArrayBuffer(64), 32, 2)) // 엘리먼트를 가짐
TypeError: Cannot freeze array buffer views with elements
```

세 가지 표준 속성(`buf.byteLength`, `buf.byteOffset`, `buf.buffer`)은 읽기 전용(이들은 {jsxref("ArrayBuffer")}} 또는 `SharedArrayBuffer`이므로)이므로, 이러한 속성에 대해 동결을 시도할 이유가 없음을 유의합니다.

### `Object.seal()`과의 비교

`Object.seal()`을 사용해 봉인된 객체는 존재하는 속성을 변경할 수 있습니다. `Object.freeze()`로 동결된 객체에서는 존재하는 속성이 불변입니다.

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.freeze |

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

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

함께 보기
-----

* `Object.isFrozen()`
* `Object.preventExtensions()`
* `Object.isExtensible()`
* `Object.seal()`
* `Object.isSealed()`


Object.isFrozen() - JavaScript

Object.isFrozen()
=================

\*\*`Object.isFrozen()`\*\*은 객체가 동결됐는지 판별합니다.

시도해보기
-----

구문
--

```js
Object.isFrozen(obj);
```

### 매개변수

`obj`

판별할 객체.

### 반환 값

객체의 동결 여부를 나타내는 `Boolean`.

설명
--

객체는 확장 불가이며 모든 속성이 설정 불가 및 모든 데이터 속성(즉, getter 또는 setter 요소가 있는 접근자 속성이 아닌 속성)이 쓰기 불가인 경우에만 동결됩니다.

예제
--

```js
// 새로운 객체는 확장 가능해서 동결되지 않습니다.
Object.isFrozen({}); // === false

// 확장 불가인 빈 객체는 빈 채로 동결됩니다.
var vacuouslyFrozen = Object.preventExtensions({});
Object.isFrozen(vacuouslyFrozen); // === true

// 속성이 하나 있는 새 객체도 확장 가능하므로 동결되지 않습니다.
var oneProp = { p: 42 };
Object.isFrozen(oneProp); // === false

// 객체 확장을 막아도 여전히 동결되지 않습니다,
// 속성이 여전히 설정 가능(및 쓰기 가능)하기에.
Object.preventExtensions(oneProp);
Object.isFrozen(oneProp); // === false

// ...그렇지만 그 속성 삭제는 객체를 빈 채로 동결되게 합니다.
delete oneProp.p;
Object.isFrozen(oneProp); // === true

// 쓰기 불가지만 여전히 설정 가능한 속성이 있는 확장 불가 객체는 동결되지 않습니다.
var nonWritable = { e: "plep" };
Object.preventExtensions(nonWritable);
Object.defineProperty(nonWritable, "e", { writable: false }); // 쓰기 불가로 함
Object.isFrozen(nonWritable); // === false

// 그 속성을 설정 불가로 바꾸면 객체를 동결되게 합니다.
Object.defineProperty(nonWritable, "e", { configurable: false }); // 설정 불가로 함
Object.isFrozen(nonWritable); // === true

// 설정 불가지만 여전히 쓰기 가능 속성이 있는 확장 불가 객체도 동결되지 않습니다.
var nonConfigurable = { release: "the kraken!" };
Object.preventExtensions(nonConfigurable);
Object.defineProperty(nonConfigurable, "release", { configurable: false });
Object.isFrozen(nonConfigurable); // === false

// 그 속성을 쓰기 불가로 바꾸면 객체를 동결되게 합니다.
Object.defineProperty(nonConfigurable, "release", { writable: false });
Object.isFrozen(nonConfigurable); // === true

// 설정 가능 접근자 속성이 있는 확장 불가 객체는 동결되지 않습니다.
var accessor = {
  get food() {
    return "yum";
  },
};
Object.preventExtensions(accessor);
Object.isFrozen(accessor); // === false

// ...하지만 그 속성을 설정 불가로 하면 동결됩니다.
Object.defineProperty(accessor, "food", { configurable: false });
Object.isFrozen(accessor); // === true

// 하지만 동결되는 객체를 위한 가장 쉬운 방법은 객체에 Object.freeze가 호출된 경우입니다.
var frozen = { 1: 81 };
Object.isFrozen(frozen); // === false
Object.freeze(frozen);
Object.isFrozen(frozen); // === true

// 정의에 의해, 동결된 객체는 확장 불가입니다.
Object.isExtensible(frozen); // === false

// 또한 정의에 의해, 동결된 객체는 봉인됩니다.
Object.isSealed(frozen); // === true
```

주의
--

ES5에서, 이 메서드의 인수가 비객체(원시형)인 경우, 그러면 `TypeError`가 발생합니다. ES6에서, 비객체 인수는 마치 동결된 보통 객체였던 것처럼 취급됩니다, 그저 `true`를 반환하는.

```js
Object.isFrozen(1);
// TypeError: 1은 객체가 아닙니다 (ES5 코드)

Object.isFrozen(1);
// true (ES6 코드)
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.isfrozen |

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

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

같이 보기
-----

* `Object.freeze()`
* `Object.preventExtensions()`
* `Object.isExtensible()`
* `Object.seal()`
* `Object.isSealed()`


Object.prototype.toLocaleString() - JavaScript

Object.prototype.toLocaleString()
=================================

**`toLocaleString()`** 메서드는 객체로 된 문자열을 반환합니다. 이 메서드는 지역별로 다른 객체로 재정의되어 표시됩니다.

시도해보기
-----

구문
--

```js
obj.toLocaleString();
```

### 반환 값

객체를 나타내는 문자열.

설명
--

`Object`의 `toLocaleString`은 `toString()`을 호출 한 결과를 반환합니다.

이 함수는 모든 객체가 사용할 수는 없지만 객체에 일반 `toLocaleString` 메소드를 제공하기 위해 제공됩니다. 아래 목록을 참조하십시오.

### `toLocaleString()`을 재정의하는 객체

* `Array`: `Array.prototype.toLocaleString()`
* `Number`: `Number.prototype.toLocaleString()` (en-US)
* `Date`: `Date.prototype.toLocaleString()`
명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.tolocalestring |

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

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

같이 보기
-----

* `Object.prototype.toString()`


Object.defineProperties() - JavaScript

Object.defineProperties()
=========================

**`Object.defineProperties()`** 메서드는 객체에 새로운 속성을 정의하거나 기존의 속성을 수정하고, 그 객체를 반환한다.

시도해보기
-----

문법
--

```js
Object.defineProperties(obj, props);
```

### 인자

* `obj`
    + : 속성을 정의하거나 수정할 객체.
* `props`
    + : 정의하거나 수정할 속성의 이름을 키로, 그 속성을 서술하는 객체를 값으로 갖는 객체. `props`의 각 값은 데이터 서술자(data descriptor) 혹은 접근자 서술자(accessor descriptor) 중 하나여야 하며, 동시에 두 유형을 포함할 수 없다(`Object.defineProperty()` 참조).데이터 서술자와 접근자 서술자 모두 다음 키를 선택적으로 포함할 수 있다.
* `configurable`
    + : `true`일 경우 이 속성 서술자의 형태를 변경하거나, 속성을 해당 객체에서 삭제할 수 있다.
     **기본값은 `false`이다.**
* `enumerable`
    + : `true`일 경우 해당 객체의 속성을 열거할 때 이 속성이 열거된다.
     **기본값은 `false`이다.**
     데이터 서술자의 경우 다음 키를 추가로 포함할 수 있다:
* `value`
    + : 이 속성에 설정할 값. 올바른 JavaScript 값(숫자, 객체, 함수 등)이면 무엇이든 설정할 수 있다.
     **기본값은 `undefined`이다.**
* `writable`
    + : `true`일 경우 이 속성에 설정된 값을 할당 연산자 (en-US)로 수정할 수 있다.
     **기본값은 `false`이다.**
     접근자 서술자의 경우 다음 키를 추가로 포함할 수 있다.
* `get`
    + : 해당 속성의 getter가 될 함수, 혹은 getter가 없을 경우 `undefined`. 이 함수의 반환값이 속성의 값으로 사용된다.
    **기본값은 `undefined`이다.**
* `set`
    + : 해당 속성의 setter가 될 함수, 혹은 setter가 없을 경우 `undefined`. 이 함수는 이 속성에 할당되는 새로운 값을 유일한 인자로 받는다.
     **기본값은 `undefined`이다.**<
     서술자가 `value`, `writable`, `get`, `set` 키를 모두 가지고 있지 않을 경우 데이터 서술자로 취급한다. 서술자가 `value`이나 `writable`과 `get`이나 `set` 키를 모두 가지고 있을 경우 예외가 발생한다.
### 반환값

함수에 넘겨주었던 객체.

설명
--

`Object.defineProperties`는 기본적으로 `props`의 모든 열거가능한 속성에 따라 객체 `obj`의 속성을 정의한다.

예시
--

```js
var obj = {};
Object.defineProperties(obj, {
  property1: {
    value: true,
    writable: true,
  },
  property2: {
    value: "Hello",
    writable: false,
  },
  // 등등
});
```

폴리필
---

모든 이름과 속성이 원래 값을 가리키는 깨끗한 실행 환경에서 `Object.defineProperties`는 다음 JavaScript 재구현과 거의 완벽하게 똑같이(`isCallable`의 주석에 주목) 실행된다.

```js
function defineProperties(obj, properties) {
  function convertToDescriptor(desc) {
    function hasProperty(obj, prop) {
      return Object.prototype.hasOwnProperty.call(obj, prop);
    }

    function isCallable(v) {
      // NB: 함수가 아닌 값이 호출가능할 경우 필요할 시 수정할 것
      return typeof v === 'function';
    }

    if (typeof desc !== 'object' || desc === null)
      throw new TypeError('bad desc');

    var d = {};

    if (hasProperty(desc, 'enumerable'))
      d.enumerable = !!desc.enumerable;
    if (hasProperty(desc, 'configurable'))
      d.configurable = !!desc.configurable;
    if (hasProperty(desc, 'value'))
      d.value = desc.value;
    if (hasProperty(desc, 'writable'))
      d.writable = !!desc.writable;
    if (hasProperty(desc, 'get')) {
      var g = desc.get;

      if (!isCallable(g) && typeof g !== 'undefined')
        throw new TypeError('bad get');
      d.get = g;
    }
    if (hasProperty(desc, 'set')) {
      var s = desc.set;
      if (!isCallable(s) && typeof s !== 'undefined')
        throw new TypeError('bad set');
      d.set = s;
    }

    if (('get' in d || 'set' in d) && ('value' in d || 'writable' in d))
      throw new TypeError('identity-confused descriptor');

    return d;
  }

  if (typeof obj !== 'object' || obj === null)
    throw new TypeError('bad obj');

  properties = Object(properties);

  var keys = Object.keys(properties);
  var descs = [];

  for (var i = 0; i < keys.length; i++)
    descs.push([keys[i], convertToDescriptor(properties[keys[i]])]);

  for (var i = 0; i < descs.length; i++)
    Object.defineProperty(obj, descs[i][0], descs[i][1]);

  return obj;
}
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.defineproperties |

브라우저 지원 현황
----------

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

같이 보기
-----

* `Object.defineProperty()`
* `Object.keys()`
* Enumerability and ownership of properties (en-US)


Object.prototype.__defineGetter__() - JavaScript

Object.prototype.\_\_defineGetter\_\_()
=======================================

**경고:** 이 기능은 object initializer 문법 혹은 `Object.defineProperty()` API를 사용한 getter 정의가 표준화됨으로써 비표준화되었습니다.
 이 기능은 이제까지의 ECMAScript 사양에서만 사용되고 있습니다.
 보다 좋은 방법이 있으므로, 이 메소드는 사용하지 말아야합니다.

**`__defineGetter__`** 메소드는 오브젝트의 프로퍼티와 함수를 바인드합니다.
 프로퍼티의 값이 조회될 때 바인드된 함수가 호출됩니다.

문법
--

```js
obj.\_\_defineGetter\_\_(prop, func);
```

### 인자

`prop`

함수와 바인드된 프로퍼티의 이름을 나타내는 문자열

`func`

프로퍼티 값이 조회되었을 때 호출되는 함수

### 리턴 값

`undefined`.

Description
-----------

`__defineGetter__` 를 사용하여 기존 오브젝트의 getter (en-US)를 사용할 수 있습니다.

Examples
--------

```js
// Non-standard and deprecated way

var o = {};
o.\_\_defineGetter\_\_("gimmeFive", function () {
  return 5;
});
console.log(o.gimmeFive); // 5

// Standard-compliant ways

// Using the get operator
var o = {
  get gimmeFive() {
    return 5;
  },
};
console.log(o.gimmeFive); // 5

// Using Object.defineProperty
var o = {};
Object.defineProperty(o, "gimmeFive", {
  get: function () {
    return 5;
  },
});
console.log(o.gimmeFive); // 5
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.\_\_defineGetter\_\_ |

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

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

See also
--------

* `Object.prototype.__defineSetter__()` (en-US)
* `get` (en-US) operator
* `Object.defineProperty()`
* `Object.prototype.__lookupGetter__()` (en-US)
* `Object.prototype.__lookupSetter__()` (en-US)
* JS Guide: Defining Getters and Setters
* [Blog Post] Deprecation of \_\_defineGetter\_\_ and \_\_defineSetter\_\_
* Firefox bug 647423


Object() constructor - JavaScript

Object() constructor
====================

**`Object`의 생성자**는 주어진 값를 객체 래퍼로 만들어 줍니다.

* 만약 값이 `null` 또는 `undefined` 라면, 빈 객체를 생성하여 반환합니다.
* 그렇지 않으면, 주어진 값의 타입 객체를 반환합니다.
* 만약 주어진 값이 객체라면, 해당 값을 그대로 반환합니다.

비 생성자 컨텍스트로 호출되면, `Object` 는 `new Object()` 와 동일하게 동작합니다.

구문
--

```js
new Object();
new Object(value);
```

### 매개변수

`value`

아무 값

예시
--

### 새로운 객체 생성

```js
let o = new Object();
o.foo = 42;

console.log(o);
// Object { foo: 42 }
```

### undefined와 null을 받는 객체 types

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

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

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

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

명세
--

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

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

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

같이보기
----

* 객체 초기자


Object.entries() - JavaScript

Object.entries()
================

**`Object.entries()`** 메서드는 `for...in`와 같은 순서로 주어진 객체 자체의 enumerable 속성 `[key, value]` 쌍의 배열을 반환합니다. (`for-in` 루프가 다른점은 프로토 타입 체인의 속성도 열거한다는 점입니다).

**`Object.entries()`** 에 의해 반환된 배열(array)의 순서는 객체가 정의된 방법과 관련이 없습니다. 배열 순서가 쓸 곳이 있다면, 다음과 같이 정렬을 먼저 하시는 것이 좋습니다 `Object.entries(obj).sort((a, b) => b[0].localeCompare(a[0]));`.

시도해보기
-----

Syntax
------

```js
Object.entries(obj);
```

### Parameters

`obj`

객체 자체의 열거 가능한 문자열 키를 가진 속성 `[key, value]` 쌍이 반환되는 객체입니다.

### Return value

지정된 객체 자체의 열거 가능한 문자속성 `[key, value]` 쌍의 배열입니다.

Description
-----------

`Object.entries()`는 `object`에 직접있는 enumerable 속성 `[key, value]` 쌍에 해당하는 배열을 반환합니다. 속성의 순서는 개체의 속성 값을 수동으로 반복하여 주어진 순서와 동일합니다.

Polyfill
--------

기본적으로 지원하지 않는 이전 환경에서 호환 가능한 `Object.entries` 지원을 추가하려면 tc39/proposal-object-values-entries에 Object.entries의 데모 구현을 찾을 수 있습니다 (IE에 대한 지원이 필요하지 않은 경우) , es-shims/Object.entries 저장소에있는 polyfill을 사용하거나 아래에 나열된 polyfill을 간단하게 배치 할 수 있습니다.

```js
if (!Object.entries)
  Object.entries = function (obj) {
    var ownProps = Object.keys(obj),
      i = ownProps.length,
      resArray = new Array(i); // preallocate the Array
    while (i--) resArray[i] = [ownProps[i], obj[ownProps[i]]];

    return resArray;
  };
```

For the above polyfill code snippet, if you need support for IE < 9, then you will also need an Object.keys polyfill (such as the one found on the `Object.keys` page).

위의 polyfill 코드 스 니펫의 경우 Internet Explorer (9버전 이전)를 지원해야하는 경우 Object.keys polyfill ( `Object.keys` 페이지에 있는 것과 같은)도 필요합니다.

Examples
--------

```js
const obj = { foo: "bar", baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]

// array like object
const obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]

// array like object with random key ordering
const anObj = { 100: "a", 2: "b", 7: "c" };
console.log(Object.entries(anObj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]

// getFoo is property which isn't enumerable
const myObj = Object.create(
  {},
  {
    getFoo: {
      value() {
        return this.foo;
      },
    },
  },
);
myObj.foo = "bar";
console.log(Object.entries(myObj)); // [ ['foo', 'bar'] ]

// non-object argument will be coerced to an object
console.log(Object.entries("foo")); // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]

// returns an empty array for any primitive type, since primitives have no own properties
console.log(Object.entries(100)); // [ ]

// iterate through key-value gracefully
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
}

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});
```

### Converting an `Object` to a `Map`

`new Map()` 생성자는 반복 가능한 항목을 허용합니다. `Object.entries`를 사용하면 `Object`에서 `Map`로 쉽게 변환 할 수 있습니다.

```js
const obj = { foo: "bar", baz: 42 };
const map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }
```

### Iterating through an `Object`

Array Destructuring을 사용하면 객체를 쉽게 반복 할 수 있습니다.

```js
const obj = { foo: "bar", baz: 42 };
Object.entries(obj).forEach(([key, value]) => console.log(`${key}: ${value}`)); // "foo: bar", "baz: 42"
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.entries |

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

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

See also
--------

* Enumerability and ownership of properties (en-US)
* `Object.keys()`
* `Object.values()`
* `Object.prototype.propertyIsEnumerable()`
* `Object.create()`
* `Object.getOwnPropertyNames()`
* `Map.prototype.entries()`
* `Map.prototype.keys()`
* `Map.prototype.values()`


Object.prototype.valueOf() - JavaScript

Object.prototype.valueOf()
==========================

**`valueOf()`** 메서드는 특정 객체의 원시 값을 반환합니다.

시도해보기
-----

구문
--

```js
object.valueOf();
```

### 반환 값

객체의 원시 값.

**참고:** (단항) 더하기 기호 는 가끔 `valueOf` 의 단축 표현으로 사용됩니다. 예를 들면, 다음과 같은 표현을 보세요. `+new Number()`. 단항 더하기 사용하기.도 참조 하세요.

설명
--

JavaScript는 객체를 원시 값으로 변환할 때 `valueOf` 메서드를 호출합니다. 보통 원시 값을 필요로 할 때 알아서 사용하므로 직접 호출해야 하는 경우는 매우 드뭅니다.

기본적으로 `Object`의 모든 후손 객체는 `valueOf`를 상속받습니다. 내장된 핵심 객체는 모두 `valueOf`를 재정의해 적합한 값을 반환합니다. 어떤 객체가 원시 값을 가지고 있지 않다면, `valueOf`는 객체 스스로를 반환합니다.

여러분의 코드에서 `valueOf`를 호출해 내장 객체를 원시 값으로 변환할 수 있습니다. 사용자 정의 객체를 만들 땐 `valueOf`를 재정의해 `Object`의 메서드 대신 다른 행동을 부여할 수도 있습니다.

### 사용자 정의 객체의 valueOf 오버라이딩

기본 `valueOf` 메서드 대신 사용할 함수를 생성할 수 있습니다. 이 때 함수는 매개변수를 받지 않아야 합니다.

`MyNumberType`이라는 객체 형태가 존재하고, 이 객체의 `valueOf` 메서드를 만들고 싶다고 가정하겠습니다. 다음의 코드는 객체의 `valueOf` 메서드에 사용자 정의 함수를 할당합니다.

```js
MyNumberType.prototype.valueOf = function () {
  return customPrimitiveValue;
};
```

위의 코드가 활성화된 상태에서 어떤 `MyNumberType` 객체를 원시 값으로 표현해야 하면 JavaScript가 자동으로 저 함수를 실행합니다.

이 객체의 `valueOf` 메서드는 보통 JavaScript가 호출하겠지만 다음처럼 직접 호출할 수도 있습니다.

```js
myNumberType.valueOf();
```

**참고:** 문자열 문맥에서 객체-문자열 변환은 `toString()` 메서드를 사용하며, `String` 객체의 `valueOf`를 사용해 원시 문자열로 변환하는 것과는 다릅니다. 모든 객체는, 비록 결과가 "`[object type]`" 뿐이라도 문자열 변환 기능을 가지고 있습니다. 그러나 대다수의 객체는 숫자, 불리언, 함수 등으로 변환되지 않습니다.

예제
--

### 커스텀 타입에 valueOf 사용하기

```js
function MyNumberType(n) {
  this.number = n;
}

MyNumberType.prototype.valueOf = function () {
  return this.number;
};

var myObj = new MyNumberType(4);
myObj + 3; // 7
```

### 단항 더하기 사용하기

```js
+"5"; // 5 (string to number)
+""; // 0 (string to number)
+"1 + 2"; // NaN (doesn't evaluate)
+new Date(); // same as (new Date()).getTime()
+"foo"; // NaN (string to number)
+{}; // NaN
+[]; // 0 (toString() returns an empty string list)
+[1]; // 1
+[1, 2]; // NaN
+new Set([1]); // NaN
+BigInt(1); // Uncaught TypeError: Cannot convert a BigInt value to a number
+undefined; // NaN
+null; // 0
+true; // 1
+false; // 0
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.valueof |

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

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

함께 보기
-----

* `Object.prototype.toString()`
* `parseInt()`
* `Symbol.toPrimitive()`


Object.prototype.constructor - JavaScript

Object.prototype.constructor
============================

인스턴스의 프로토타입을 만든 `Object` 함수의 참조를 반환합니다. 이 속성값은 함수 자체의 참조임을 주의하세요, 함수 이름을 포함하는 문자열이 아니라. 그 값은 `1`, `true` 및 `"test"`와 같은 원시(primitive) 값에 대해서만 읽기 전용입니다.

설명
--

모든 객체는 자신의 `prototype`으로부터 `constructor` 속성을 상속합니다:

```js
var o = {};
o.constructor === Object; // true

var o = new Object();
o.constructor === Object; // true

var a = [];
a.constructor === Array; // true

var a = new Array();
a.constructor === Array; // true

var n = new Number(3);
n.constructor === Number; // true
```

예제
--

### 객체의 생성자 표시하기

다음 예는 프로토타입이 `Tree`인 그 형의 객체 `theTree`를 만듭니다. 그 다음 객체 `theTree`의 `constructor`를 표시합니다.

```js
function Tree(name) {
  this.name = name;
}

var theTree = new Tree("Redwood");
console.log("theTree.constructor is " + theTree.constructor);
```

이 예는 다음 출력을 표시합니다:

```js
theTree.constructor is function Tree(name) {
  this.name = name;
}
```

### 객체의 생성자 바꾸기

다음 예는 일반 객체의 constructor 값을 수정하는 법을 보입니다. `true`, `1` 및 `"test"`만이 원래 읽기 전용 생성자를 갖기에 영향을 받지 않습니다. 이 예는 객체의 `constructor` 속성에 의존하는 게 항상 안전하지는 않음을 보입니다.

```js
function Type() {}

var types = [
  new Array(),
  [],
  new Boolean(),
  true, // 바뀌지 않음
  new Date(),
  new Error(),
  new Function(),
  function () {},
  Math,
  new Number(),
  1, // 바뀌지 않음
  new Object(),
  {},
  new RegExp(),
  /(?:)/,
  new String(),
  "test", // 바뀌지 않음
];

for (var i = 0; i < types.length; i++) {
  types[i].constructor = Type;
  types[i] = [
    types[i].constructor,
    types[i] instanceof Type,
    types[i].toString(),
  ];
}

console.log(types.join("\n"));
```

이 예는 다음 출력을 표시합니다:

```js
function Type() {},false,
function Type() {},false,
function Type() {},false,false
function Boolean() {
    [native code]
},false,true
function Type() {},false,Mon Sep 01 2014 16:03:49 GMT+0600
function Type() {},false,Error
function Type() {},false,function anonymous() {

}
function Type() {},false,function () {}
function Type() {},false,[object Math]
function Type() {},false,0
function Number() {
    [native code]
},false,1
function Type() {},false,[object Object]
function Type() {},false,[object Object]
function Type() {},false,/(?:)/
function Type() {},false,/(?:)/
function Type() {},false,
function String() {
    [native code]
},false,test
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.constructor |

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

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


Object.prototype.isPrototypeOf() - JavaScript

Object.prototype.isPrototypeOf()
================================

**`isPrototypeOf()`** 메소드는 해당 객체가 다른 객체의 프로토타입 체인에 속한 객체인지 확인하기 위해 사용됩니다.

**참고:** `isPrototypeOf` 는 `instanceof` 연산자와 다릅니다. "`object instanceof AFunction`" 표현식에서는 `object` 의 프로토타입 체인을 AFunction 자체가 아니라 `AFunction.prototype` 에 대해 확인을 합니다.

구문
--

```js
prototypeObj.isPrototypeOf(obj);
```

### 매개변수

`object`

프로토타입 체인을 가지고 있는 객체가 검색될 것 입니다.

설명
--

`isPrototypeOf` 메소드는 또 다른 객체의 프로토타입 체인에 해당 객체가 존재하는지 여부를 확인할수 있습니다.

예를들어, 다음의 프로토타입체인을 고려해봅시다.

```js
function Fee() {
  // ...
}

function Fi() {
  // ...
}
Fi.prototype = new Fee();

function Fo() {
  // ...
}
Fo.prototype = new Fi();

function Fum() {
  // ...
}
Fum.prototype = new Fo();
```

실행되고 나면 **Fum** 인스턴스의 프로토타입체인이 **Fi**의 프로토타입과 연결되어있는지를 확인할 필요가 있습니다. 다음과 같은 방법으로 확인할 수 있습니다:

```js
var fum = new Fum();
// ...

if (Fi.prototype.isPrototypeOf(fum)) {
  // do something safe
}
```

이 메소드는 `instanceof` 연산자와 함께 특정 프로토타입으로부터 상속된 객체만 작동하게 하려는(예를 들어 특정 메소드나 속성이 객체에 있다는걸 보장하려는 때) 코드에서 특히 쓸모가 많다.

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.isprototypeof |

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

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

같이 보기
-----

* `instanceof`
* `Object.getPrototypeOf()`
* `Object.setPrototypeOf()` (en-US)
* `Object.prototype.__proto__`


Object.prototype.toString() - JavaScript

Object.prototype.toString()
===========================

The **`toString()`** 은 문자열을 반환하는 object의 대표적인 방법이다

시도해보기
-----

구문
--

```js
obj.toString();
```

Description
-----------

모든 객체에는 객체가 텍스트 값으로 표시되거나 객체가 문자열이 예상되는 방식으로 참조 될 때 자동으로 호출되는 `toString()` 메서드가 있습니다. 기본적으로 `toString()` 메서드는 Object에서 비롯된 모든 객체에 상속됩니다. 이 메서드가 사용자 지정 개체에서 재정의되지 않으면 `toString()`은 "`[object type]`"을 반환합니다. 여기서 `type`은 object type입니다. 다음 코드는 이것을 설명합니다

```js
var o = new Object();
o.toString(); // returns [object Object]
```

**참고:** JavaScript 1.8.5부터 `null`의 `toString()`을 호출하는 경우 `[object Null]`을 반환하며, `undefined`는 `[object Undefined]`를 반환합니다. 이는 ECMAScript 제 5판과 후속 정오표에 정의되어 있습니다. See toString으로 객체 클래스 검사.

매개변수
----

숫자 및 BigInts의 경우 `toString()`은 선택적으로 기수(radix)를 매개변수로 취합니다. 기수의 값은 최소 2부터 36까지입니다.

`기수`를 이용함으로써 10진수를 (1, 2, 3, 4, 5...) 다른 진수로 변환할 수 있습니다. 아래는 10진수를 2진수로 변환하는 예제입니다.

```js
let baseTenInt = 10;
console.log(baseTenInt.toString(2));
// "1010"이 출력됩니다
```

big integers도 이와 같습니다

```js
let bigNum = BigInt(20);
console.log(bigNum.toString(2));
// "10100"이 출력됩니다
```

몇 가지 일반적인 기수들은 아래와 같습니다

* 2 : 2진법
* 8 : 8진법
* 10 : 10진법
* 16 : 16진법
Examples
--------

### 기본 `toString` 메소드 재정의

기본 `toString()` 메서드 대신에 호출될 함수를 정의할 수 있습니다. `toString()` 메서드는 인자를 취하지 않고 문자열을 반환합니다. 직접 생성한 `toString()` 메서드는 원하는 어떤 값이든 될 수 있지만 해당 객체에 대한 정보를 전달하고 있을 때 가장 유용할 것입니다.

다음 코드는 `Dog` 객체 타입을 정의하고 `Dog` 타입을 따르는 `theDog`를 생성합니다:

```js
function Dog(name, breed, color, sex) {
  this.name = name;
  this.breed = breed;
  this.color = color;
  this.sex = sex;
}

theDog = new Dog("Gabby", "Lab", "chocolate", "female");
```

커스텀 객체의 `toString()` 메서드를 호출하는 경우 `Object`로부터 상속받은 기본 값을 반환하게 됩니다:

```js
theDog.toString(); // returns [object Object]
```

다음 코드는 기본 `toString()` 메서드를 재정의하는 `dogToString()`을 생성하고 할당합니다. 이 함수는 객체의 name, breed, color, sex를 포함하는 문자열을 "`property = value;`"의 형태로 만들어냅니다.

```js
Dog.prototype.toString = function dogToString() {
  var ret =
    "Dog " +
    this.name +
    " is a " +
    this.sex +
    " " +
    this.color +
    " " +
    this.breed;
  return ret;
};
```

앞선 코드를 사용하면 문자열 컨텍스트에서 `theDog`가 사용될 때마다 JavaScript는 자동으로 `dogToString()` 함수를 호출하여 다음 문자열을 반환합니다:

```js
"Dog Gabby is a female chocolate Lab";
```

### `toString()`으로 객체 클래스 검사

`toString()`은 모든 객체에 사용되어 해당 객체의 클래스를 가져올 수 있습니다. Object.prototype.toString()을 모든 객체에 사용하기 위해서는 `Function.prototype.call()` 나 `Function.prototype.apply()`를 사용해서 검사하고자 하는 객체를 `thisArg`로 불리는 첫번째 파라미터로 넘겨야 합니다.

```js
var toString = Object.prototype.toString;

toString.call(new Date()); // [object Date]
toString.call(new String()); // [object String]
toString.call(Math); // [object Math]

// Since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.tostring |

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

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

See also
--------

* `Object.prototype.toSource()` (en-US)
* `Object.prototype.valueOf()`
* `Number.prototype.toString()`
* `Symbol.toPrimitive`


Object.isExtensible() - JavaScript

Object.isExtensible()
=====================

**`Object.isExtensible()`** 메서드는 객체가 확장 가능한지(객체에 새 속성을 추가할 수 있는지 여부)를 결정합니다.

시도해보기
-----

구문
--

```js
Object.isExtensible(obj);
```

### 매개변수

`obj`

판별할 객체.

### 반환 값

객체의 확장 가능 여부를 나타내는 `Boolean`.

설명
--

객체는 기본으로 확장 가능입니다: 새로운 속성이 추가될 수 있고 (`Object.prototype.__proto__`
지원이 중단되었습니다
 속성을 지원하는 엔진에서는) 수정될 수 있습니다. 객체는 `Object.preventExtensions()`, `Object.seal()` 또는 `Object.freeze()`를 사용하여 확장 불가로 표시될 수 있습니다.

예제
--

```js
// 새로운 객체는 확장 가능입니다.
var empty = {};
Object.isExtensible(empty); // === true

// ...하지만 변경될 수 있습니다.
Object.preventExtensions(empty);
Object.isExtensible(empty); // === false

// 봉인된 객체는 정의에 의해 확장 불가입니다.
var sealed = Object.seal({});
Object.isExtensible(sealed); // === false

// 동결된 객체 또한 정의에 의해 확장 불가입니다.
var frozen = Object.freeze({});
Object.isExtensible(frozen); // === false
```

주의
--

ES5에서, 이 메서드의 인수가 비객체(원시형)인 경우, 그러면 `TypeError`가 발생합니다. ES6에서, 비객체 인수는 확장 불가인 보통 객체처럼 다뤄집니다, 그저 `false`를 반환하는.

```js
Object.isExtensible(1);
// TypeError: 1은 객체가 아닙니다 (ES5 코드)

Object.isExtensible(1);
// false (ES6 코드)
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.isextensible |

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

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

같이 보기
-----

* `Object.preventExtensions()`
* `Object.seal()`
* `Object.isSealed()`
* `Object.freeze()`
* `Object.isFrozen()`
* `Reflect.isExtensible()`


Object.assign() - JavaScript

Object.assign()
===============

**`Object.assign()`** 메서드는 출처 객체들의 모든 열거 가능한 자체 속성 (en-US)을 복사해 대상 객체에 붙여넣습니다. 그 후 대상 객체를 반환합니다.

시도해보기
-----

구문
--

```js
Object.assign(target, ...sources);
```

### 매개변수

`target`

목표 객체. 출처 객체의 속성을 복사해 반영한 후 반환할 객체입니다.

`sources`

출처 객체. 목표 객체에 반영하고자 하는 속성들을 갖고 있는 객체들입니다.

### 반환 값

목표 객체.

설명
--

목표 객체의 속성 중 출처 객체와 동일한 키를 갖는 속성의 경우, 그 속성 값은 출처 객체의 속성 값으로 덮어씁니다. 출처 객체들의 속성 중에서도 키가 겹칠 경우 뒤쪽 객체의 속성 값이 앞쪽 객체의 속성 값보다 우선합니다.

`Object.assign()` 메서드는 출처 객체의 '열거 가능한 자체 속성'만 목표 객체로 복사합니다. 출처 객체에서 속성 값을 가져올 땐 `[[Get]]`, 목표 객체에 속성 값을 지정할 땐 `[[Set]]`을 사용하므로 각각 접근자와 설정자를 호출합니다. 그러므로 `Object.assign()`은 속성을 단순히 복사하거나 새로 정의하는 것이 아니라, 할당(*assign*)하는 것입니다. 따라서 출처 객체가 접근자를 포함하는 경우, 프로토타입에 새로운 속성을 추가하는 용도로는 적합하지 않을 수도 있습니다.

열거성을 포함한 속성 정의를 프로토타입으로 복사하려면 `Object.getOwnPropertyDescriptor()`와 `Object.defineProperty()`를 사용하세요.

`Object.assign()`은 `String` 키와 `Symbol` 키 속성 모두 복사합니다.

오류(대상 객체의 속성이 쓰기 불가한 상태 등)를 마주치면 `TypeError`가 발생합니다. 그러나 오류가 발생하기 전에 이미 추가/변경한 다른 속성의 값은 대상 객체에 유지됩니다.

**참고:** `Object.assign()`의 출처에 `null` 또는 `undefined`를 제공해도 예외는 발생하지 않습니다.

예제
--

### 객체 복제

```js
const obj = { a: 1 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
```

### 깊은 복사 주의점

`Object.assign()`은 속성의 값을 복사하기 때문에, 깊은 복사를 수행하려면 다른 방법을 사용해야 합니다.

만약 출처 값이 객체에 대한 참조라면 참조 값만 복사합니다.

```js
function test() {
  "use strict";

  let obj1 = { a: 0, b: { c: 0 } };
  let obj2 = Object.assign({}, obj1);
  console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}

  obj1.a = 1;
  console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
  console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}

  obj2.a = 2;
  console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
  console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}}

  obj2.b.c = 3;
  console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}}
  console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}}

  // 깊은 복사
  obj1 = { a: 0, b: { c: 0 } };
  let obj3 = JSON.parse(JSON.stringify(obj1));
  obj1.a = 4;
  obj1.b.c = 4;
  console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}}
}

test();
```

### 객체 병합

```js
const o1 = { a: 1 };
const o2 = { b: 2 };
const o3 = { c: 3 };

const obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1, b: 2, c: 3 }, 목표 객체 자체가 변경됨.
```

### 같은 속성을 가진 객체 병합

```js
const o1 = { a: 1, b: 1, c: 1 };
const o2 = { b: 2, c: 2 };
const o3 = { c: 3 };

const obj = Object.assign({}, o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
```

같은 키를 가진 속성의 경우 매개변수 순서에서 더 뒤에 위치한 객체의 값으로 덮어씁니다.

### 심볼 속성 복사

```js
const o1 = { a: 1 };
const o2 = { [Symbol("foo")]: 2 };

const obj = Object.assign({}, o1, o2);
console.log(obj); // { a : 1, [Symbol("foo")]: 2 } (cf. bug 1207182 on Firefox)
Object.getOwnPropertySymbols(obj); // [Symbol(foo)]
```

### 프로토타입 체인의 속성과 열거 불가능한 속성은 복사 불가

```js
const obj = Object.create(
  { foo: 1 },
  {
    // foo는 obj의 프로토타입 체인에 있음
    bar: {
      value: 2, // bar는 열거 불가능
    },
    baz: {
      value: 3,
      enumerable: true, // baz는 열거 가능한 자체 속성
    },
  },
);

const copy = Object.assign({}, obj);
console.log(copy); // { baz: 3 }
```

### 원시 값은 객체로 래핑

```js
const v1 = "abc";
const v2 = true;
const v3 = 10;
const v4 = Symbol("foo");

const obj = Object.assign({}, v1, null, v2, undefined, v3, v4);
// 원시 값은 래핑하고, null과 undefined는 무시
// 참고: 문자열 래퍼만 자체 열거형 속성을 가질 수 있음
console.log(obj); // { "0": "a", "1": "b", "2": "c" }
```

### 예외로 인한 복사 작업 중단

```js
const target = Object.defineProperty({}, "foo", {
  value: 1,
  writable: false,
}); // target.foo는 읽기 전용 속성

Object.assign(target, { bar: 2 }, { foo2: 3, foo: 3, foo3: 3 }, { baz: 4 });
// TypeError: "foo" is read-only
// target.foo에 할당할 때 예외 발생

console.log(target.bar); // 2, 첫 번째 출처 객체는 성공적으로 복사함
console.log(target.foo2); // 3, 두 번째 출처 객체 중 첫 번째 속성도 성공적으로 복사함
console.log(target.foo); // 1, 여기에서 예외가 발생했음
console.log(target.foo3); // undefined, assign 메서드가 종료됨, foo3은 복사되지 않음
console.log(target.baz); // undefined, 세 번째 출처 객체도 복사되지 않음
```

### 접근자 복사

```js
const obj = {
  foo: 1,
  get bar() {
    return 2;
  },
};

let copy = Object.assign({}, obj);
console.log(copy);
// { foo: 1, bar: 2 }, copy.bar의 값은 obj.bar의 접근자가 반환한 값

// 속성의 온전한 기술자를 복사해 할당하는 함수
function completeAssign(target, ...sources) {
  sources.forEach((source) => {
    let descriptors = Object.keys(source).reduce((descriptors, key) => {
      descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
      return descriptors;
    }, {});

    // 기본적으로 Object.assign은 열거 가능한 심볼도 복사함
    Object.getOwnPropertySymbols(source).forEach((sym) => {
      let descriptor = Object.getOwnPropertyDescriptor(source, sym);
      if (descriptor.enumerable) {
        descriptors[sym] = descriptor;
      }
    });
    Object.defineProperties(target, descriptors);
  });
  return target;
}

copy = completeAssign({}, obj);
console.log(copy);
// { foo:1, get bar() { return 2 } }
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.assign |

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

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

같이 보기
-----

* `core-js`의 `Object.assign` 폴리필
* `Object.defineProperties()`
* 속성의 소유권과 열거 가능성 (en-US)
* 객체 리터럴에서의 전개 구문


Object.fromEntries() - JavaScript

Object.fromEntries()
====================

**`Object.fromEntries()`** 메서드는 키값 쌍의 목록을 객체로 바꿉니다.

시도해보기
-----

구문
--

```js
Object.fromEntries(iterable);
```

### 매개변수

`iterable`

반복 가능한 객체. 즉, `Array`, `Map` 또는 반복 규약을 구현한 기타 객체.

### 반환 값

속성의 키와 값을 반복 가능한 객체에서 가져온 새로운 객체.

설명
--

`Object.fromEntries()` 메서드는 키값 쌍 목록을 받고, 그 목록을 사용해 속성을 부여한 새로운 객체를 반환합니다. `iterable` 인자는 `@@iterator` 메서드를 구현하여 반복기 객체를 반환해야 하고, 그 반복기는 또 배열 형태의 객체로 요소 2개를 반환해야 합니다. 반환된 요소 중 첫 번째는 생성할 객체의 속성 키로, 두 번째는 속성 값으로 사용합니다.

`Object.fromEntries()`는`Object.entries()`의 역을 수행합니다.

예제
--

### `Map`에서 `Object`로

```js
const map = new Map([
  ["foo", "bar"],
  ["baz", 42],
]);
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
```

### `Array`에서 `Object`로

```js
const arr = [
  ["0", "a"],
  ["1", "b"],
  ["2", "c"],
];
const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }
```

### 객체 변환

`Object.fromEntries()`와 그 역인 `Object.entries()`, 그리고 배열 변형 메서드를 통해 객체를 변환할 수 있습니다.

```js
const object1 = { a: 1, b: 2, c: 3 };

const object2 = Object.fromEntries(
  Object.entries(object1).map(([key, val]) => [key, val \* 2]),
);

console.log(object2);
// { a: 2, b: 4, c: 6 }
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.fromentries |

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

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

같이 보기
-----

* `Object.entries()`
* `Object.keys()`
* `Object.values()`
* `Map.prototype.entries()`
* `Map.prototype.keys()`
* `Map.prototype.values()`


Object.getOwnPropertyNames() - JavaScript

Object.getOwnPropertyNames()
============================

**`Object.getOwnPropertyNames()`** 메서드는 전달된 객체의 모든 속성 (심볼을 사용하는 속성을 제외한 열거할 수 없는 속성 포함) 들을 배열로 반환합니다.

시도해보기
-----

구문
--

```js
Object.getOwnPropertyNames(obj);
```

### 매개변수

`obj`

반환 받을 열거형 속성과 열거형이 아닌 속성을 가진 객체

### 반환 값

전달된 객체에 있는 속성들의 문자열 배열을 반환합니다.

설명
--

`Object.getOwnPropertyNames()` 는 전달된 객체(`obj`)의 열거형 및 열거할 수 없는 속성들을 문자열 배열로 반환합니다.
 배열의 열거할 수 있는 속성들의 순서는 `for...in` 반복문 (또는 `Object.keys()`)이 처리되는 순서와 일치합니다.
 ES6 문법에 따라, 객체의 정수형 키 (열거형 및 비-열거형 포함)가 먼저 배열에 오름차순으로 추가된 다음 문자열 키를 삽입하는 순서로 추가됩니다.

 ES5에서는 인수(`obj`)가 객체가 아닌 경우 (원시 타입) `TypeError` 가 발생합니다.
 ES2015에서는, 객체가 아닌 인수를 객체 타입으로 강제 형변환합니다.

```js
Object.getOwnPropertyNames("foo");
// TypeError: "foo" is not an object (ES5 code)

Object.getOwnPropertyNames("foo");
// ["0", "1", "2", "length"] (ES2015 code)
```

예시
--

### Using Object.getOwnPropertyNames()

```js
var arr = ["a", "b", "c"];
console.log(Object.getOwnPropertyNames(arr).sort()); // .sort() 는 배열 메서드입니다.
// logs ["0", "1", "2", "length"]

// 배열형 객체
var obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.getOwnPropertyNames(obj).sort()); // .sort() 는 배열 메서드입니다.
// logs ["0", "1", "2"]

// 속성 명과 속성 값을 Array.forEach 메서드를 사용하여 로깅합니다.
Object.getOwnPropertyNames(obj).forEach(function (val, idx, array) {
  console.log(val + " -> " + obj[val]);
});
// logs
// 0 -> a
// 1 -> b
// 2 -> c

// 열거할 수 없는 속성
var my_obj = Object.create(
  {},
  {
    getFoo: {
      value: function () {
        return this.foo;
      },
      enumerable: false,
    },
  },
);
my_obj.foo = 1;

console.log(Object.getOwnPropertyNames(my_obj).sort());
// logs ["foo", "getFoo"]
```

 만약 열거 가능한 속성만 사용한다면, `Object.keys()` 또는 `for...in` 반복문을 사용하는걸 권장합니다.
 (이는 객체의 프로토타입 체인을 먼저 사용하여 열거 가능한 속성을 반환합니다. 단, 후자는`hasOwnProperty()` (en-US)에 필터 됩니다.)

프로토타입 체인에 있는 요소들은 나열되지 않음:

```js
function ParentClass() {}
ParentClass.prototype.inheritedMethod = function () {};

function ChildClass() {
  this.prop = 5;
  this.method = function () {};
}
ChildClass.prototype = new ParentClass();
ChildClass.prototype.prototypeMethod = function () {};

console.log(
  Object.getOwnPropertyNames(
    new ChildClass(), // ["prop", "method"]
  ),
);
```

### 열거할 수 없는 속성만 가져오기

이 방법은 `Array.prototype.filter()` 함수를 사용해 (`Object.getOwnPropertyNames()` 을 통해 얻은) 모든 키 중 (`Object.keys()` 을 통해 얻은) 열거 가능한 키들을 제거하여 열거할 수 없는 키들만 출력합니다.

```js
var target = myObject;
var enum_and_nonenum = Object.getOwnPropertyNames(target);
var enum_only = Object.keys(target);
var nonenum_only = enum_and_nonenum.filter(function (key) {
  var indexInEnum = enum_only.indexOf(key);
  if (indexInEnum == -1) {
    // enum\_only 에 키 값이 없다는 것은
    // 그 키가 열거할 수 없는 키 임을 의미합니다.
    // 그래서 이 필터에서 true를 반환합니다.
    return true;
  } else {
    return false;
  }
});

console.log(nonenum_only);
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.getownpropertynames |

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

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

같이 보기
-----

* `Object.getOwnPropertyNames` 의 폴리필 코드는 아래에서 확인 할 수 있습니다. `core-js`
* Enumerability and ownership of properties (en-US)
* `Object.prototype.hasOwnProperty()` (en-US)
* `Object.prototype.propertyIsEnumerable()`
* `Object.create()`
* `Object.keys()`
* `Array.forEach()`


String.prototype.charAt() - JavaScript

String.prototype.charAt()
=========================

**charAt()** 함수는 문자열에서 특정 인덱스에 위치하는 유니코드 단일문자를 반환합니다.

시도해보기
-----

구문
--

```js
str.charAt(index);
```

### 매개변수

* 0과 문자열의 길이 - 1 사이의 정수값.
* 인자를 생략하면 기본값으로 0를 설정되고 첫 문자를 반환한다.

`index`
### 반환 값

* 지정된 인덱스에 해당하는 유니코드 단일문자를 반환한다.
* 만약 인덱스가 문자열 길이보다 큰 경우 빈 문자열 (예) " " 을 반환한다.
설명
--

문자열 내의 문자는 왼쪽에서 오른쪽으로 순번(인덱스)이 매겨집니다. 첫 번째 문자의 순번은 0, 그리고 `stringName` 이라는 이름을 가진 문자열의 마지막 문자 순번은 `stringName.length - 1` 입니다. `index`가 문자열 길이를 벗어나면 빈 문자열을 반환하게 됩니다.

`index`를 제공하지 않으면 기본값은 0입니다.

예제
--

### 문자열 내의 다른 위치에 있는 문자들을 출력하기

아래 예제는 문자열 `"Brave new world"`의 다른 위치에 있는 문자들을 출력합니다.

```js
var anyString = "Brave new world";
console.log("The character at index 0 is '" + anyString.charAt() + "'");
// No index was provided, used 0 as default

console.log("The character at index 0 is '" + anyString.charAt(0) + "'");
console.log("The character at index 1 is '" + anyString.charAt(1) + "'");
console.log("The character at index 2 is '" + anyString.charAt(2) + "'");
console.log("The character at index 3 is '" + anyString.charAt(3) + "'");
console.log("The character at index 4 is '" + anyString.charAt(4) + "'");
console.log("The character at index 999 is '" + anyString.charAt(999) + "'");
```

프로그램의 실행 결과는 아래와 같습니다.

```js
The character at index 0   is 'B'
The character at index 1   is 'r'
The character at index 2   is 'a'
The character at index 3   is 'v'
The character at index 4   is 'e'
The character at index 999 is ''
```

### 문자열 내의 모든 문자 얻기

아래 예제는 문자열 전체를 순회하며 각 문자가 완전한지 확인하는 프로그램입니다. 심지어 기본 다국어 평면(Basic Multilingual Plane)에 포함되지 않은 문자들이 포함되어 있다고 하더라도 잘 동작합니다.

```js
var str = "A \uD87E\uDC04 Z"; // 기본 다국어 평면에 포함되지 않는 문자를 사용합니다.
for (var i = 0, chr; i < str.length; i++) {
  if ((chr = getWholeChar(str, i)) === false) {
    continue;
  }
  // Adapt this line at the top of each loop, passing in the whole string and
  // the current iteration and returning a variable to represent the
  // individual character

  console.log(chr);
}

function getWholeChar(str, i) {
  var code = str.charCodeAt(i);

  if (Number.isNaN(code)) {
    return ""; // Position not found
  }
  if (code < 0xd800 || code > 0xdfff) {
    return str.charAt(i);
  }

  // High surrogate (could change last hex to 0xDB7F to treat high private
  // surrogates as single characters)
  if (0xd800 <= code && code <= 0xdbff) {
    if (str.length <= i + 1) {
      throw "High surrogate without following low surrogate";
    }
    var next = str.charCodeAt(i + 1);
    if (0xdc00 > next || next > 0xdfff) {
      throw "High surrogate without following low surrogate";
    }
    return str.charAt(i) + str.charAt(i + 1);
  }
  // Low surrogate (0xDC00 <= code && code <= 0xDFFF)
  if (i === 0) {
    throw "Low surrogate without preceding high surrogate";
  }
  var prev = str.charCodeAt(i - 1);

  // (could change last hex to 0xDB7F to treat high private
  // surrogates as single characters)
  if (0xd800 > prev || prev > 0xdbff) {
    throw "Low surrogate without preceding high surrogate";
  }
  // We can pass over low surrogates now as the second component
  // in a pair which we have already processed
  return false;
}
```

비구조화 할당을 허용하는 ECMAScript 2016 환경에서는 아래 예제 코드가 더 간결하고, 문자가 서러게이트 페어가 되는 것을 허용할 때는 증가해야 하는 변수를 자동적으로 증가하기에 위의 코드보다 다소 더 유연합니다.

```js
var str = "A\uD87E\uDC04Z"; // We could also use a non-BMP character directly
for (var i = 0, chr; i < str.length; i++) {
  [chr, i] = getWholeCharAndI(str, i);
  // Adapt this line at the top of each loop, passing in the whole string and
  // the current iteration and returning an array with the individual character
  // and 'i' value (only changed if a surrogate pair)

  console.log(chr);
}

function getWholeCharAndI(str, i) {
  var code = str.charCodeAt(i);

  if (Number.isNaN(code)) {
    return ""; // Position not found
  }
  if (code < 0xd800 || code > 0xdfff) {
    return [str.charAt(i), i]; // Normal character, keeping 'i' the same
  }

  // High surrogate (could change last hex to 0xDB7F to treat high private
  // surrogates as single characters)
  if (0xd800 <= code && code <= 0xdbff) {
    if (str.length <= i + 1) {
      throw "High surrogate without following low surrogate";
    }
    var next = str.charCodeAt(i + 1);
    if (0xdc00 > next || next > 0xdfff) {
      throw "High surrogate without following low surrogate";
    }
    return [str.charAt(i) + str.charAt(i + 1), i + 1];
  }
  // Low surrogate (0xDC00 <= code && code <= 0xDFFF)
  if (i === 0) {
    throw "Low surrogate without preceding high surrogate";
  }
  var prev = str.charCodeAt(i - 1);

  // (could change last hex to 0xDB7F to treat high private surrogates
  // as single characters)
  if (0xd800 > prev || prev > 0xdbff) {
    throw "Low surrogate without preceding high surrogate";
  }
  // Return the next character instead (and increment)
  return [str.charAt(i + 1), i + 1];
}
```

### 기본다국어평면(Basic-Multilingual-Plane)이 아닌 문자들을 지원하도록 `charAt()` 수정하기

어떠한 non-BMP 문자들이 나타났는지 호출자가 알 필요가 없기 때문에 non-BMP 문자들을 지원하도록 하는데는 앞의 예제들이 더 자주 사용되지만, 인덱스로 문자를 선택하는데 있어서 문자열 내에 서로게이트 페어들이 하나의 문자들로 처리되길 원한다면, 아래 예제 코드를 사용하면 됩니다.

```js
function fixedCharAt(str, idx) {
  var ret = "";
  str += "";
  var end = str.length;

  var surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
  while (surrogatePairs.exec(str) != null) {
    var li = surrogatePairs.lastIndex;
    if (li - 2 < idx) {
      idx++;
    } else {
      break;
    }
  }

  if (idx >= end || idx < 0) {
    return "";
  }

  ret += str.charAt(idx);

  if (
    /[\uD800-\uDBFF]/.test(ret) &&
    /[\uDC00-\uDFFF]/.test(str.charAt(idx + 1))
  ) {
    // Go one further, since one of the "characters" is part of a surrogate pair
    ret += str.charAt(idx + 1);
  }
  return ret;
}
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-string.prototype.charat |

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

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

관련문서
----

* `String.prototype.indexOf()`
* `String.prototype.lastIndexOf()`
* `String.prototype.charCodeAt()` (en-US)
* `String.prototype.codePointAt()` (en-US)
* `String.prototype.split()`
* `String.fromCodePoint()` (en-US)
* JavaScript has a Unicode problem – Mathias Bynens