new operator - JavaScript

new operator
============

**`new` 연산자**는 사용자 정의 객체 타입 또는 내장 객체 타입의 인스턴스를 생성한다.

시도해보기
-----

구문
--

```js
new constructor[([arguments])];
```

### 매개변수

`constructor`

객체 인스턴스의 타입을 기술(명세)하는 함수

`arguments`

`constructor`와 함께 호출될 값 목록

설명
--

사용자 정의 객체를 생성에는 두 단계가 필요하다:

1. 함수를 작성하여 객체 타입을 정의한다.
2. `new` 연산자로 객체의 인스턴스를 생성한다.

객체의 타입을 정의하기 위해, 객체의 이름과 속성을 명세하는 함수를 만든다. 객체는 그 자체가 또 다른 객체인 속성을 가질 수 있다. 아래의 예를 본다.

코드 `new Foo(...)`가 실행될 때 다음과 같은 일이 발생한다:

1. `Foo.prototype` 을 상속하는 새로운 객체가 하나 생성된다.
2. 명시된 인자 그리고 새롭게 생성된 객체에 바인드된 this와 함께 생성자 함수 `Foo`가 호출된다.`new Foo`는 `new Foo()`와 동일하다. 즉 인자가 명시되지 않은 경우, 인자 없이 `Foo`가 호출된다.
3. 생성자 함수에 의해 리턴된 객체는 전체 `new` 호출 결과가 된다. 만약 생성자 함수가 명시적으로 객체를 리턴하지 않는 경우, 첫 번째 단계에서 생성된 객체가 대신 사용된다.(일반적으로 생성자는 값을 리턴하지 않는다. 그러나 일반적인 객체 생성을 재정의(override)하기 원한다면 그렇게 하도록 선택할 수 있다.)

언제든 이전에 정의된 객체에 속성을 추가할 수 있다. 예를 들면, `car1.color = "black"` 구문은 `color` 속성을 `car1`에 추가하고 해당 속성에 "`black`"이란 값을 할당한다. 그러나, 이것이 다른 객체들에게는 영향을 주지 않는다. 동일한 타입의 모든 객체들에게 새로운 속성을 추가하려면, `Car` 객체 타입의 정의에 이 속성을 추가해야한다.

`Function.prototype` 속성을 사용하여 이전에 정의된 객체 타입에 공유 속성을 추가할 수 있다. 이것은 객체 타입의 인스턴스 하나에만 적용되는 것이 아니라 이 함수로 생성하는 모든 객체와 공유하는 속성을 정의한다.

다음의 코드는 `car` 타입의 모든 객체에 "`original color`" 값을 갖는 color 속성을 추가한다. 그리고 `car1` 객체 인스턴스에서만 이 값을 문자열 "`black`"으로 덮어쓴다. 더 많은 정보는 prototype을 참조한다.

```js
function Car() {}
car1 = new Car();
car2 = new Car();

console.log(car1.color); // undefined

Car.prototype.color = "original color";
console.log(car1.color); // original color

car1.color = "black";
console.log(car1.color); // black

console.log(car1.__proto__.color); //original color
console.log(car2.__proto__.color); //original color
console.log(car1.color); // black
console.log(car2.color); // original color
```

예제
--

### 객체 타입과 객체 인스턴스

cars를 위한 객체 타입을 생성하기 원한다고 가정해 보자. 이 객체 타입이 `car`로 불리기 원하고, make, model, 그리고 year 속성을 갖게 하고 싶다. 이렇게 하기 위해서 다음과 같은 함수를 작성할 것이다:

```js
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
```

이제 다음과 같이, `mycar`로 불리는 객체를 생성할 수 있다:

```js
var mycar = new Car("Eagle", "Talon TSi", 1993);
```

이 구문은 `mycar` 를 생성하고 명시한 값을 속성값으로 설정한다. 그래서 `mycar.make`의 값은 문자열 "Eagle"이고, `mycar.year`는 정수 1993이며 나머지도 마찬가지이다.

`new`를 호출해서 얼마든지 `car` 객체를 생성할 수 있다. 예를 들면:

```js
var kenscar = new Car("Nissan", "300ZX", 1992);
```

### 속성 그 자신이 다른 객체인 객체의 속성

`person`이라고 불리는 객체를 다음과 같이 정의한다고 가정해보자:

```js
function Person(name, age, sex) {
  this.name = name;
  this.age = age;
  this.sex = sex;
}
```

그리고 다음과 같이 두 개의 `person` 객체 인스턴스를 새롭게 생성한다:

```js
var rand = new Person("Rand McNally", 33, "M");
var ken = new Person("Ken Jones", 39, "M");
```

그런 다음 `owner` 속성을 포함하는 `car`의 정의를 다시 쓸 수 있다. 이 owner 속성은 다음과 같은 person 객체를 취한다:

```js
function Car(make, model, year, owner) {
  this.make = make;
  this.model = model;
  this.year = year;
  this.owner = owner;
}
```

새로운 객체의 인스턴스를 생성하기 위해 다음과 같이 사용한다:

```js
var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
var car2 = new Car("Nissan", "300ZX", 1992, ken);
```

새로운 객체를 생성할 때 문자열이나 숫자 값을 넘겨주는 대신에, 위의 구문은 owner를 위한 매개변수로 `rand`와 `ken` 객체를 넘겨준다. `car2`의 owner name을 확인해보기 위해서, 다음의 속성에 접근할 수 있다:

```js
car2.owner.name;
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-new-operator |

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

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

관련 문서
-----

* `Function`
* `Reflect.construct()`
* `Object.prototype` (en-US)


class 식 - JavaScript

class 식
=======

**class 표현식**은 ECMAScript 2015 (ES6)에서 클래스를 정의하는 한 방법입니다. function 식과 비슷하게, class 식은 기명(named) 또는 익명(unnamed)일 수 있습니다. 기명인 경우, 클래스명은 클래스 본체(body)에서만 지역(local)입니다. JavaScript 클래스는 프로토타입(원형) 기반 상속을 사용합니다.

시도해보기
-----

구문
--

```js
    var MyClass = class [className] [extends] {
      // class body
    };
```

설명
--

class 식은 class 문과 구문이 비슷합니다. 그러나, class 식의 경우 클래스명("binding identifier")을 생략할 수 있는데 class 문으로는 할 수 없습니다.

class 문과 같이, class 식의 본체는 엄격 모드에서 실행됩니다.

예제
--

### 간단한 class 식

이게 바로 변수 "Foo"를 사용하여 참조할 수 있는 간단한 익명 class 식입니다.

```js
var Foo = class {
  constructor() {}
  bar() {
    return "Hello World!";
  }
};

var instance = new Foo();
instance.bar(); // "Hello World!"
Foo.name; // ""
```

### Named class 식

당신이 클래스 몸통 내에서 현재 클래스를 참조하고 싶다면, 유명 class 식을 만들 수 있습니다. 이 이름은 오직 class 식 자체 범위에서만 볼 수 있습니다.

```js
var Foo = class NamedFoo {
  constructor() {}
  whoIsThere() {
    return NamedFoo.name;
  }
};
var bar = new Foo();
bar.whoIsThere(); // "NamedFoo"
NamedFoo.name; // ReferenceError: NamedFoo가 정의되지 않음
Foo.name; // "NamedFoo"
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-class-definitions |

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

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

같이 보기
-----

* `function` 식
* `class` 문
* Classes


빼기 할당 (-=) - JavaScript

빼기 할당 (-=)
==========

빼기 할당 연산자(`-=`)는 오른쪽 피연산자의 값을 변수에서 뺀 결과를 다시 변수에 할당합니다.

시도해보기
-----

구문
--

```js
x -= y; // x = x - y
```

예제
--

### 빼기 할당 사용하기

```js
// bar = 5
// 위와 같은 변수를 가정할 때

bar -= 2; // 3
bar -= "foo"; // NaN
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

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

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

같이 보기
-----

* JavaScript 안내서의 할당 연산자
* 빼기 연산자


instanceof - JavaScript

instanceof
==========

**`instanceof` 연산자**는 생성자의 `prototype` 속성이 객체의 프로토타입 체인 어딘가 존재하는지 판별합니다.

시도해보기
-----

구문
--

```js
object instanceof constructor;
```

### 매개변수

`object`

판별할 객체.

`constructor`

판별 목표 함수.

설명
--

`instanceof` 연산자는 `object`의 프로토타입 체인에 `constructor.prototype`이 존재하는지 판별합니다.

```js
// 생성자 정의
function C() {}
function D() {}

var o = new C();

// true, 왜냐하면 Object.getPrototypeOf(o) === C.prototype
o instanceof C;

// false, 왜냐하면 D.prototype이 o 객체의 프로토타입 체인에 없음
o instanceof D;

o instanceof Object; // true, 왜냐하면
C.prototype instanceof Object; // true

C.prototype = {};
var o2 = new C();

o2 instanceof C; // true

// false, 왜냐하면 C.prototype이
// 더 이상 o의 프로토타입 체인에 없음
o instanceof C;

D.prototype = new C(); // C를 D의 [[Prototype]] 링크로 추가
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true, 왜냐하면 이제 C.prototype이 o3의 프로토타입 체인에 존재
```

`instanceof` 의 값은 생성자 `prototype` 프로퍼티의 변화에 따라 바뀔수 있으며, `Object.setPrototypeOf`의 사용함에 따라서도 바뀔 수 있음에 주의하세요. 또한 non-standard의 `__proto__` 슈도-프로퍼티도 사용할 수 있도록 만들어 줍니다.

### `instanceof` 와 multiple context (예. 프레임 또는 창)

다른 스코프는 다른 실행 환경을 가집니다. 이것은 다른 스코프는 다른 고정된 요소들(다른 전역 오브젝트, 다른 생성자들 등)을 가지고 있음을 의미합니다. 이 사실은 예상치 못한 결과를 가져올 수도 있습니다. 예를 들면, [] `instanceof window.frames[0].Array`는 `false`를 리턴할 것입니다. 왜냐하면, `Array.prototype !== window.frames[0].Array` 이며, arrays 는 상위로부터 상속받기 때문입니다. 이것은 처음에는 말이 되지 않을 수도 있습니다. 하지만, 스크립트에서 여러 프레임이나 창을 다루며, 객체를 함수를 통하여 하나의 컨텍스트에서 다른 컨텍스트로 오브젝트를 넘기게 된다면, 이건 충분히 일어날 수 있는 일이며, 아주 큰 이슈가 될 것입니다. 예를 들어, 주어진 오브젝트가 실제로 `Array.isArray(myObj)`를 사용한 Array인지 안전하게 확인 할 수 있습니다.

>
> **Note:** XPCOM `instanceof` 을 사용하는 코드에서는 특별한 효과를 가집니다. : `obj instanceof xpcomInterface` (예. `Components.interfaces.nsIFile`)가 `obj.QueryInterface(xpcomInterface)`를 호출하고, 만약 QueryInterface 가 성공하면 `true` 를 리턴합니다. 이 호출의 부가 효과로는 `obj` 에서 성공적인 `instanceof` 테스트 후에 `xpcomInterface`'s의 프로퍼티를 사용할 수 있습니다. 스탠다드 JavaScript 전역속성들과는 달리, 테스트 `obj instanceof xpcomInterface`는 `obj`가 다른 스코프에 있더라도 작동합니다.
>
>
>

예제
--

### `String`과 `Date`는 타입 `Object`이며, 예외적인 경우임을 입증하기

아래의 코드는 `instanceof` 를 `String` 과 `Date` 오브젝트도 타입 `Object`임을 확인하기 위해 사용합니다.(이 오브젝트들은 `Object` 로부터 파생되었습니다.)

그러나, 여기서 오브젝트 리터럴 노테이션으로 생성된 오브젝트는 예외적입니다. : 비록 프로토 타입이 정의되지 않았지만, `instanceof Object` 는 `true`를 리턴합니다.

```js
var simpleStr = "This is a simple string";
var myString = new String();
var newStr = new String("String created with constructor");
var myDate = new Date();
var myObj = {};

simpleStr instanceof String; // returns false, prototype chain을 확인하고, undefined를 찾는다.
myString instanceof String; // returns true
newStr instanceof String; // returns true
myString instanceof Object; // returns true

myObj instanceof Object; // returns true, undefined prototype 임에도 불구하고 true.
({}) instanceof Object; // returns true, 위의 경우와 동일.

myString instanceof Date; // returns false

myDate instanceof Date; // returns true
myDate instanceof Object; // returns true
myDate instanceof String; // returns false
```

### `mycar`는 타입 `Car`와 타입 `Object`임을 입증하기

다음의 코드는 `Car` 오브젝트 타입과 그 오브젝트 타입의 인스턴스 `mycar` 를 생성합니다. `instanceof` 연산자는 `mycar` 오브젝트는 타입 `Car` 와 타입 `Object` 라는 것은 보여줍니다.

```js
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
var mycar = new Car("Honda", "Accord", 1998);
var a = mycar instanceof Car; // returns true
var b = mycar instanceof Object; // returns true
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-relational-operators |

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

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

같이 보기
-----

* `typeof`
* `Symbol.hasInstance`


async function 표현식 - JavaScript

async function 표현식
==================

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2017.

* Learn more
* See full compatibility
* Report feedback
**`async function`** 키워드는 표현식 내에서 `async` 함수를 정의하기 위해 사용됩니다.

또한 async function statement을 사용하여 async 함수를 정의할 수 있습니다.

문법
--

```js
  async function (param0) {
    statements
  }

  async function (param0, param1) {
    statements
  }

  async function (param0, param1, /\* ... \*/ paramN) {
    statements
  }

  async function name(param0) {
    statements
  }

  async function name(param0, param1) {
    statements
  }

  async function name(param0, param1, /\* ... \*/ paramN) {
    statements
  }
```

arrow functions를 사용해도 됩니다.

```js
async (param) => expression;

async (param1, param2, ...paramN) => {
  statements;
};
```

### 인수

`name`

함수 이름. 생략가능하며 이경우함수는 *anonymous* 형식임 이름은 함수 몸체에 대해 지역적으로 사용.

`paramN`

함수에 전달될 인수의 이름.

`statements`

함수 몸체를 구성하는 명령문들.

설명
--

`async function` 표현식은 ``async function` 선언` 문법과 유사하며, 거의 동일합니다. `async function` 표현식과 `async function` 선언문의 주요 차이점은 익명함수로써의 사용 여부로, `async function` 표현식은 함수 이름을 생략하면 익명함수를 만듭니다. `async function` 표현식은 IIFE(즉시실행함수)로 사용할 수 있습니다. `functions`문서를 참고하세요.

예제
--

### 간단한 예시

```js
function resolveAfter2Seconds(x) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

// async function 표현식을 변수에 할당
const add = async function (x) {
  const a = await resolveAfter2Seconds(20);
  const b = await resolveAfter2Seconds(30);
  return x + a + b;
};

add(10).then((v) => {
  console.log(v); // 4초 뒤에 60 출력
});

// async function 표현식을 IIFE로 사용
(async function (x) {
  const p1 = resolveAfter2Seconds(20);
  const p2 = resolveAfter2Seconds(30);
  return x + (await p1) + (await p2);
})(10).then((v) => {
  console.log(v); // 2초 뒤에 60 출력
});
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-async-function-definitions |

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

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

같이 보기
-----

* `async function`
* `AsyncFunction` object
* `await`


async function* 표현식 - JavaScript

async function\* 표현식
====================

**`async function*`** 키워드는 표현식 내부에서 비동기 제너레이터 함수를 정의하는데 사용됩니다.

시도해보기
-----

구문
--

```js
async function\* (param0) {
  statements
}
async function\* (param0, param1) {
  statements
}
async function\* (param0, param1, /\* … ,\*/ paramN) {
  statements
}

async function\* name(param0) {
  statements
}
async function\* name(param0, param1) {
  statements
}
async function\* name(param0, param1, /\* … ,\*/ paramN) {
  statements
}
```

### 매개변수

`name` Optional

함수 이름입니다. 익명 함수의 경우 생략할 수 있습니다. 이름은 함수 본문 내에서만 유효합니다.

`paramN` Optional

함수에 전달되는 인수의 이름입니다. 함수는 최대 255개의 인수를 가질 수 있습니다.

`statements` Optional

함수 본문을 구성하는 구문입니다.

설명
--

`async function*` 표현식은 async function\* statement (en-US)과 상당히 유사하며 문법도 거의 동일합니다. 둘의 큰 차이점은 함수 이름인데, `async function*` 표현식에서는 함수 이름을 생략해 익명 비동기 제너레이터 함수를 만들 수 있습니다. 더 자세한 내용은 `함수`에 대한 챕터를 참고하세요.

예제
--

### async function\* 사용하기

다음 예제는 이름이 없는 비동기 제너레이터 함수를 정의하고 `x`에 할당한 후, 인수를 제곱한 값을 반환합니다.

```js
const x = async function\* (y) {
  yield Promise.resolve(y \* y);
};
x(6)
  .next()
  .then((res) => console.log(res.value)); // 36
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-async-generator-function-definitions |

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

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

같이 보기
-----

* `async function*` (en-US) statement
* `AsyncGeneratorFunction` (en-US) object
* 이터레이션 프로토콜
* `GeneratorFunction` object
* `yield`
* `yield*`
* `Function` object
* Functions


나누기 할당 (/=) - JavaScript

나누기 할당 (/=)
===========

나누기 할당 연산자(`/=`)는 오른쪽 피연산자의 값으로 변수를 나눈 결과를 다시 변수에 할당합니다.

시도해보기
-----

구문
--

```js
x /= y; // x = x / y
```

예제
--

### 나누기 할당 사용하기

```js
// bar = 5
// 위와 같은 변수를 가정하고, 아래의 모든 연산을 순서대로 실행할 때

bar /= 2; // 2.5
bar /= 2; // 1.25
bar /= 0; // Infinity
bar /= "foo"; // NaN
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

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

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

같이 보기
-----

* JavaScript 안내서의 할당 연산자
* 나누기 연산자


단항 부정 (-) - JavaScript

단항 부정 (-)
=========

단항 부정 연산자(`-`)는 피연산자 앞에 위치하며, 피연산자의 부호를 부정합니다. 즉 양수는 음수로, 음수는 양수로 바꿉니다.

시도해보기
-----

구문
--

```js
-x;
```

예제
--

### 숫자 부정하기

```js
const x = 3;
const y = -x;

// y = -3
// x = 3
```

### 숫자가 아닌 값을 부정하기

단항 부정 연산자는 숫자가 아닌 값을 숫자로 변환할 수 있습니다.

```js
const x = "4";
const y = -x;

// y = -4
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-unary-minus-operator |

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

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

같이 보기
-----

* 더하기 연산자
* 빼기 연산자
* 나누기 연산자
* 곱하기 연산자
* 나머지 연산자
* 지수 연산자
* 증가 연산자
* 감소 연산자
* 단항 더하기 연산자


구조 분해 할당 - JavaScript

구조 분해 할당
========

**구조 분해 할당** 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식입니다.

시도해보기
-----

구문
--

```js
var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]

({ a, b } = { a: 10, b: 20 });
console.log(a); // 10
console.log(b); // 20

// Stage 4(finished) proposal
({ a, b, ...rest } = { a: 10, b: 20, c: 30, d: 40 });
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}
```

설명
--

객체 및 배열 리터럴 표현식을 사용하면 즉석에서 쉽게 데이터 뭉치를 만들 수 있습니다.

```js
var x = [1, 2, 3, 4, 5];
```

구조 분해 할당의 구문은 위와 비슷하지만, 대신 할당문의 좌변에서 사용하여, 원래 변수에서 어떤 값을 분해해 할당할지 정의합니다.

```js
var x = [1, 2, 3, 4, 5];
var [y, z] = x;
console.log(y); // 1
console.log(z); // 2
```

구조 분해 할당은 Perl이나 Python 등 다른 언어가 가지고 있는 기능입니다.

배열 구조 분해
--------

### 기본 변수 할당

```js
var foo = ["one", "two", "three"];

var [red, yellow, green] = foo;
console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // "three"
```

### 선언에서 분리한 할당

변수의 선언이 분리되어도 구조 분해를 통해 값을 할당할 수 있습니다.

```js
var a, b;

[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
```

### 기본값

변수에 기본값을 할당하면, 분해한 값이 `undefined`일 때 그 값을 대신 사용합니다.

```js
var a, b;

[a = 5, b = 7] = [1];
console.log(a); // 1
console.log(b); // 7
```

### 변수 값 교환하기

하나의 구조 분해 표현식만으로 두 변수의 값을 교환할 수 있습니다.

구조 분해 할당 없이 두 값을 교환하려면 임시 변수가 필요합니다. (일부 로우 레벨 언어에서는 XOR 교체 트릭을 사용할 수 있습니다)

```js
var a = 1;
var b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
```

### 함수가 반환한 배열 분석

함수는 이전부터 배열을 반환할 수 있었습니다. 구조 분해를 사용하면 반환된 배열에 대한 작업을 더 간결하게 수행할 수 있습니다.

아래 예제에서 `f()`는 출력으로 배열 `[1, 2]`을 반환하는데, 하나의 구조 분해만으로 값을 분석할 수 있습니다.

```js
function f() {
  return [1, 2];
}

var a, b;
[a, b] = f();
console.log(a); // 1
console.log(b); // 2
```

### 일부 반환 값 무시하기

다음과 같이 필요하지 않은 반환 값을 무시할 수 있습니다.

```js
function f() {
  return [1, 2, 3];
}

var [a, , b] = f();
console.log(a); // 1
console.log(b); // 3
```

반환 값을 모두 무시할 수도 있습니다.

```js
[, ,] = f();
```

### 변수에 배열의 나머지를 할당하기

배열을 구조 분해할 경우, 나머지 구문을 이용해 분해하고 남은 부분을 하나의 변수에 할당할 수 있습니다.

```js
var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]
```

나머지 요소의 오른쪽 뒤에 쉼표가 있으면 `SyntaxError`가 발생합니다.

```js
var [a, ...b,] = [1, 2, 3];
// SyntaxError: rest element may not have a trailing comma
```

### 정규 표현식과 일치하는 값 해체하기

정규 표현식의 `exec()` (en-US) 메서드는 일치하는 부분를 찾으면 그 문자열에서 정규식과 일치하는 부분 전체를 배열의 맨 앞에, 그리고 그 뒤에 정규식에서 괄호로 묶인 각 그룹과 일치하는 부분을 포함하는 배열을 반환합니다. 구조 분해 할당은 필요하지 않은 경우 일치하는 전체 부분은 무시하고 필요한 부분만 쉽게 빼올 수 있습니다.

```js
function parseProtocol(url) {
  var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.\*)$/.exec(url);
  if (!parsedURL) {
    return false;
  }
  console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]

  var [, protocol, fullhost, fullpath] = parsedURL;
  return protocol;
}

console.log(
  parseProtocol("https://developer.mozilla.org/en-US/Web/JavaScript"),
); // "https"
```

객체 구조 분해
--------

### 기본 할당

```js
var o = { p: 42, q: true };
var { p, q } = o;

console.log(p); // 42
console.log(q); // true
```

### 선언 없는 할당

구조 분해를 통해 변수의 선언과 분리하여 변수에 값을 할당할 수 있습니다.

```js
var a, b;

({ a, b } = { a: 1, b: 2 });
```

**참고**: 할당 문을 둘러싼 `( .. )`는 선언 없이 객체 리터럴(object literal) 비구조화 할당을 사용할 때 필요한 구문입니다.

`{a, b} = {a:1, b:2}`는 유효한 독립 구문이 아닙니다. 좌변의 `{a, b}`이 객체 리터럴이 아닌 블록으로 간주되기 때문입니다.

하지만, `({a, b} = {a:1, b:2})`는 유효한데, `var {a, b} = {a:1, b:2}`와 같습니다.

`( .. )` 표현식 앞에는 세미콜론이 있어야 합니다. 그렇지 않을 경우 이전 줄과 연결되어 함수를 실행하는데 이용될 수 있습니다.

### 새로운 변수 이름으로 할당하기

객체로부터 속성을 해체하여 객체의 원래 속성명과는 다른 이름의 변수에 할당할 수 있습니다.

```js
var o = { p: 42, q: true };
var { p: foo, q: bar } = o;

console.log(foo); // 42
console.log(bar); // true
```

### 기본값

객체로부터 해체된 값이 `undefined`인 경우, 변수에 기본값을 할당할 수 있습니다.

```js
var { a = 10, b = 5 } = { a: 3 };

console.log(a); // 3
console.log(b); // 5
```

### 기본값 갖는 새로운 이름의 변수에 할당하기

새로운 변수명 할당과 기본값 할당을 한번에 할 수 있습니다.

```js
var { a: aa = 10, b: bb = 5 } = { a: 3 };

console.log(aa); // 3
console.log(bb); // 5
```

### 함수 매개변수의 기본값 설정하기

#### ES5 버전

```js
function drawES5Chart(options) {
  options = options === undefined ? {} : options;
  var size = options.size === undefined ? "big" : options.size;
  var cords = options.cords === undefined ? { x: 0, y: 0 } : options.cords;
  var radius = options.radius === undefined ? 25 : options.radius;
  console.log(size, cords, radius);
  // 이제 드디어 차트 그리기 수행
}

drawES5Chart({
  cords: { x: 18, y: 30 },
  radius: 30,
});
```

#### ES2015 버전

```js
function drawES2015Chart({
  size = "big",
  cords = { x: 0, y: 0 },
  radius = 25,
} = {}) {
  console.log(size, cords, radius);
  // 차트 그리기 수행
}

drawES2015Chart({
  cords: { x: 18, y: 30 },
  radius: 30,
});
```

위의 **`drawES2015Chart`** 함수의 원형에서 구조 분해된 좌변에 빈 오브젝트 리터럴을 할당하는 것을 볼 수 있습니다 `{size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}`. 빈 오브젝트를 우변에 할당하지 않고도 함수를 작성할 수 있습니다. 하지만, 지금의 형태에서는 단순히 `**drawES2015Chart()**`와 같이 어떤 매개변수 없이도 호출할 수 있지만, 우변의 빈 오브젝트 할당을 없앤다면 함수 호출시 적어도 하나의 인자가 제공되어야만 합니다. 이 함수가 어떠한 매개변수 없이도 호출할 수 있길 원한다면 지금 형태가 유용하고, 무조건 객체를 넘기길 원하는 경우에는 빈 객체 할당을 하지 않는 것이 유용할 수 있습니다.

### 중첩된 객체 및 배열의 구조 분해

```js
var metadata = {
  title: "Scratchpad",
  translations: [
    {
      locale: "de",
      localization\_tags: [],
      last\_edit: "2014-04-14T08:43:37",
      url: "/de/docs/Tools/Scratchpad",
      title: "JavaScript-Umgebung",
    },
  ],
  url: "/ko/docs/Tools/Scratchpad",
};

var {
  title: englishTitle,
  translations: [{ title: localeTitle }],
} = metadata;

console.log(englishTitle); // "Scratchpad"
console.log(localeTitle); // "JavaScript-Umgebung"
```

### for of 반복문과 구조 분해

```js
var people = [
  {
    name: "Mike Smith",
    family: {
      mother: "Jane Smith",
      father: "Harry Smith",
      sister: "Samantha Smith",
    },
    age: 35,
  },
  {
    name: "Tom Jones",
    family: {
      mother: "Norah Jones",
      father: "Richard Jones",
      brother: "Howard Jones",
    },
    age: 25,
  },
];

for (var {
  name: n,
  family: { father: f },
} of people) {
  console.log("Name: " + n + ", Father: " + f);
}

// "Name: Mike Smith, Father: Harry Smith"
// "Name: Tom Jones, Father: Richard Jones"
```

### 함수 매개변수로 전달된 객체에서 필드 해체하기

```js
function userId({ id }) {
  return id;
}

function whois({ displayName: displayName, fullName: { firstName: name } }) {
  console.log(displayName + " is " + name);
}

var user = {
  id: 42,
  displayName: "jdoe",
  fullName: {
    firstName: "John",
    lastName: "Doe",
  },
};

console.log("userId: " + userId(user)); // "userId: 42"
whois(user); // "jdoe is John"
```

이 예제는 user 객체로부터 `id`, `displayName` 및 `firstName` 을 해체해 출력합니다.

### 계산된 속성 이름과 구조 분해

계산된 속성 이름(computed property name)은, 객체 리터럴과 비슷하게 구조 분해에도 사용될 수 있습니다.

```js
let key = "z";
let { [key]: foo } = { z: "bar" };

console.log(foo); // "bar"
```

### 객체 구조 분해에서 Rest

Rest/Spread Properties for ECMAScript 제안(stage 3)에서는 구조 분해에 rest 구문을 추가하고 있습니다. rest 속성은 구조 분해 패턴으로 걸러지지 않은 열거형 속성의 키를 가진 나머지 항목들을 모읍니다.

```js
let { a, b, ...rest } = { a: 10, b: 20, c: 30, d: 40 };
a; // 10
b; // 20
rest; // { c: 30, d: 40 }
```

### 속성 이름이 유효한 JavaScript 식별자명이 아닌 경우

구조 분해는 JavaScript 식별자 이름으로 적합하지 않은 속성명이 제공된 경우에도 이용할 수 있습니다. 이 때는 대체할 유효한 식별자명을 제공해야 합니다.

```js
const foo = { "fizz-buzz": true };
const { "fizz-buzz": fizzBuzz } = foo;

console.log(fizzBuzz); // "true"
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-destructuring-assignment |
| ECMAScript Language Specification # sec-destructuring-binding-patterns |

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

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

같이 보기
-----

* 할당 연산자 (en-US)
* "ES6 in Depth: Destructuring" on hacks.mozilla.org


왼쪽 시프트 할당 연산자 (<<=) - JavaScript

왼쪽 시프트 할당 연산자 (<<=)
===================

**왼쪽 시프트 할당 (`<<=`)** 연산자는 지정된 비트 수 만큼 왼쪽으로 비트를 이동시키고 그 결과를 변수에 반영합니다.

시도해보기
-----

구문
--

```js
x <<= y // x = x << y
```

예제
--

### 왼쪽 시프트 할당하기

```js
let a = 5;
// 00000000000000000000000000000101
a <<= 2; // 20
// 00000000000000000000000000010100
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

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

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

같이 보기
-----

* JavaScript 가이드에서 할당 연산자
* 왼쪽 시프트 연산자


속성 접근자 - JavaScript

속성 접근자
======

**속성 접근자**는 점 또는 괄호 표기법으로 객체의 속성에 접근할 수 있도록 해줍니다.

시도해보기
-----

구문
--

```js
object.property;
object["property"];
```

설명
--

객체는 속성의 이름을 키로 사용하는 연관 배열(다른 이름으로는 맵, 딕셔너리, 해시, 룩업 테이블)로 생각할 수 있습니다. 보통 객체의 속성을 메서드와 구별해서 말하곤 하지만, 서로의 차이는 관례에 불과합니다. 메서드는 호출할 수 있는 속성일 뿐으로, 속성의 값이 `Function`을 가리키는 참조라면 그 속성을 메서드라고 합니다.

속성에 접근하는 법은 점 표기법과 괄호 표기법 두 가지가 있습니다.

### 점 표기법

```js
get = object.property;
object.property = set;
```

이 코드에서, `property`는 유효한 JavaScript 식별자여야합니다. 따라서 `object.$1`은 유효하지만 `object.1`은 아닙니다.

```js
document.createElement("pre");
```

여기서는 "createElement"라는 이름을 가진 메서드를 `document`에서 찾아 호출하고 있습니다.

소숫점 없는 숫자 리터럴의 메서드를 호출하고 싶으면, 메서드의 접근자 앞에 공백을 한 칸 추가해 점이 소숫점으로 인식되지 않도록 해야 합니다.

```js
(77).toExponential();
// or
(77).toExponential();
// or
(77).toExponential();
// or
(77).toExponential();
// or
(77.0).toExponential();
// because 77. === 77.0, no ambiguity
```

### 괄호 표기법

```js
get = object[property_name];
object[property_name] = set;
```

괄호 표기법에서는 `property_name` 으로 문자열이나 `Symbol`을 사용할 수 있습니다. 문자열은 유효한 식별자가 아니어도 괜찮습니다. "`1foo`", "`!bar!`", 심지어 " "(공백)도 가능합니다.

```js
document["createElement"]("pre");
```

이 코드는 점 표기법의 예시와 동일합니다.

괄호 앞에 공백이 올 수도 있습니다.

```js
document["createElement"]("pre");
```

### 속성 이름

속성의 이름은 문자열이나 `Symbol`입니다. 숫자 등의 다른 자료형은 문자열로 변환됩니다.

```js
var object = {};
object["1"] = "value";
console.log(object[1]);
```

위 코드의 `1`은 `'1'`로 변환되므로, 출력 결과는 "value"입니다.

```js
var foo = { unique\_prop: 1 },
  bar = { unique\_prop: 2 },
  object = {};
object[foo] = "value";
console.log(object[bar]);
```

위의 코드 역시 `foo`와 `bar`가 같은 문자열(SpiderMonkey JavaScript 엔진에서는 문자열 "`['object Object']`")로 변환되므로, 출력 결과는 동일하게 "value"입니다.

### 메서드 바인딩

메서드는 해당 메서드의 객체에 바인딩되지 않습니다. 특히 `this`는 메서드 내에 고정되지 않으므로 `this`가 항상 현재 메서드를 포함하는 객체를 참조하는건 아닙니다. 대신, `this`는 함수 호출 방식에 따라 "전달"됩니다. 메서드 바인딩을 참고하세요.

### `eval()` 주의사항

JavaScript 초심자로써는 괄호 표기법을 사용할 수 있는 장소에 `eval()` (en-US)을 남용하기 쉽습니다. 간혹 스크립트에서 다음과 같은 구문을 찾아볼 수 있습니다.

```js
x = eval("document.forms.form\_name.elements." + strFormControl + ".value");
```

`eval()`은 느리고, 가능하다면 최대한 피해야 합니다. 또한, `strFormControl`은 유효한 식별자여야 하지만, 폼 컨트롤의 ID나 이름은 식별자가 아닐 수도 있습니다. 따라서 괄호 표기법을 대신 사용하는 것이 좋습니다.

```js
x = document.forms["form\_name"].elements[strFormControl].value;
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-property-accessors |

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

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

같이 보기
-----

* `Object`
* `Object.defineProperty()`


비트 NOT (~) - JavaScript

비트 NOT (~)
==========

비트 NOT 연산자(`~`)는 피연산자의 비트를 반전시킵니다. 다른 비트 연산자와 마찬가지로 피연산자를 32비트 정수로 변환합니다.

시도해보기
-----

구문
--
```

~a
```

설명
--

피연산자는 32비트 정수로 변환되며 일련의 비트(0과 1)로 표현됩니다. 32비트를 넘어가는 숫자는 최상위 비트를 기준으로 하여 삭제합니다. 예를 들어 다음과 같은 32비트 이상인 정수는 32비트 정수로 변환됩니다.
```

Before: 11100110111110100000000000000110000000000001
After:              10100000000000000110000000000001
```

피연산자의 각 비트는 반전됩니다.

`NOT` 연산에 대한 진리표는 다음과 같습니다.

| a | NOT a |
| --- | --- |
| 0 | 1 |
| 1 | 0 |

```js
 9 (base 10) = 00000000000000000000000000001001 (base 2)
               --------------------------------
~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
```

32비트 정수 피연산자는 2의 보수에 따라 반전됩니다. 즉, 최상위 비트는 음수인 정수를 표현하는 데 사용합니다.

어떤 수 `x`에 대해 NOT 비트 연산을 하면 `-(x + 1)`의 결과를 도출합니다. 예를 들면 `~-5`는 `4`로 계산됩니다.

32비트 표현을 사용하기 때문에 `~-1`과 `~4294967295` (232 - 1) 의 결과가 둘 다 `0`으로 계산되는 점을 유의해주세요.

예제
--

### 비트 NOT 연산 사용하기

```js
~0; // -1
~-1; // 0
~1; // -2
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-bitwise-not-operator |

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

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

같이 보기
-----

* 비트 연산자


왼쪽 시프트 (<<) - JavaScript

왼쪽 시프트 (<<)
===========

**왼쪽 시프트 (`<<`)** 연산자는 첫 번째 피연산자를 명시된 비트 수(32의 나머지)만큼 왼쪽으로 이동합니다. 왼쪽으로 이동된 초과 비트는 폐기됩니다. 오른쪽은 움직인 비트 수 만큼 0비트로 채워집니다.

시도해보기
-----

구문
--

```js
a << b
```

설명
--

이 연산자는 첫 번째 피연산자를 명시한 비트 수만큼 왼쪽으로 이동합니다. 왼쪽으로 이동된 초과 비트는 폐기됩니다. 오른쪽은 움직인 비트 수 만큼 0 비트로 채워집니다.

예를 들어, `9 << 2`은 36이 도출됩니다.
```

     9 (10진수): 00000000000000000000000000001001 (2진수)
                  --------------------------------
9 << 2 (10진수): 00000000000000000000000000100100 (2진수) = 36 (10진수)
```

 임의의 숫자 `x`를 왼쪽으로 `y`비트 단위로 이동하면 `x * 2 ** y`입니다. 그래서 예를 들어
 `9 << 3`은 `9 * (2 ** 3) = 9 * (8) = 72`으로 해석됩니다.

왼쪽 피연산자는 32비트 정수로 변환됩니다. 즉, 부동 소수점 숫자는 잘리고 32비트 경계 내에 있지 않은 숫자는 오버플로우/언더플로우됩니다.

 오른쪽 피연산자는 부호 없는 32비트 정수로 변환된 다음 32 나머지 연산의 값을 가져오므로 실제 시프트 오프셋은 항상 0에서 31 사이의
 양의 정수입니다. 예를 들어, `100 << 32`는 `100 << 0`과 동일(이 결과값은 `100`입니다)합니다. 32 나머지 연산은
 0이기 때문입니다.

예제
--

### 왼쪽 시프트 사용하기

```js
9 << 3; // 72
// 9 \* (2 \*\* 3) = 9 \* (8) = 72
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-left-shift-operator |

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

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

같이 보기
-----

* JavaScript에서 비트 연산자 가이드
* 왼쪽 시프트 할당 연산자


function* expression - JavaScript

function\* expression
=====================

**`function*`** keyword 는 표현식 내에서 generator function 을 정의합니다.

시도해보기
-----

Syntax
------

```js
    function\* [name]([param1[, param2[, ..., paramN]]]) {
       statements
    }
```

### Parameters

`name`

함수명. 생략하면, 익명 함수가 됩니다. 함수명은 함수내에만 한정됩니다.

`paramN`

함수에 전달되는 인수의 이름. 함수는 최대 255 개의 인수를 가질 수 있습니다.

`statements`

함수의 본체를 구성하는 구문들.

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

`function*` expression 은 `function* statement` 과 매우 유사하고 형식도 같습니다. `function*` expression 과 `function*` statement 의 주요한 차이점은 함수명으로, *`function*`* expressions 에서는 익명 함수로 만들기 위해 함수명이 생략될 수 있습니다.보다 자세한 내용은 functions 을 참조하십시오.

Examples
--------

아래의 예제는 이름이 없는 generator function 을 정의하고 이를 x 에 할당합니다. function 은 인자로 들어온 값의 제곱을 생산(yield)합니다.

```js
var x = function\* (y) {
  yield y \* y;
};
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-generator-function-definitions |

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

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

See also
--------

* `function* statement`
* `GeneratorFunction` object
* The Iterator protocol (en-US)
* `yield`
* `yield*`
* `Function` object
* `function statement`
* `function expression`
* `Functions and function scope` (en-US)


단항 더하기 (+) - JavaScript

단항 더하기 (+)
==========

단항 더하기 연산자(`+`)는 피연산자 앞에 위치하며 피연산자를 평가하지만, 만약 피연산자가 숫자가 아니라면 숫자로 변환을 시도합니다.

시도해보기
-----

구문
--

```js
+x;
```

설명
--

 단항 부정 (`-`)도 숫자가 아닌 값을 변환할 수 있지만, 단항 더하기는
 어떤 것을 숫자로 변환하는 가장 빠르고 선호하는 방법입니다. 왜냐하면 숫자에 대해 다른 연산을 수행하지 않기 때문입니다.
 정수와 실수의 문자열 표현뿐 아니라 문자열이 아닌 값인 `true`, `false` 및 `null` 또한 변환할 수 있습니다.
 10진수 및 16진수(`0x` 접두사) 형식의 정수 모두 지원됩니다. 음수도 지원됩니다(16진수 제외).
 BigInt 값에 연산자를 사용하면 TypeError가 발생합니다. 특정 값을 구문 분석할 수 없으면 `NaN`으로 평가됩니다.

예제
--

### 숫자에 사용하기

```js
const x = 1;
const y = -1;

console.log(+x);
// 1
console.log(+y);
// -1
```

### 숫자가 아닌 값에 사용하기

```js
+true; // 1
+false; // 0
+null; // 0
+function (val) {
  return val;
}; // NaN
+1n; // TypeError 발생: BigInt 값을 숫자로 변경할 수 없습니다
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-unary-plus-operator |

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

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

같이 보기
-----

* 더하기 연산자
* 빼기 연산자
* 나누기 연산자
* 곱하기 연산자
* 나머지 연산자
* 지수 연산자
* 증가 연산자
* 감소 연산자
* 단항 부정 연산자


증가 연산자(++) - JavaScript

증가 연산자(++)
==========

**증가(`++`) 연산자** 는 피연산자를 증가(1을 더함)시키고 연산자의 위치에 따라 증가하기 전이나 후의 값을 반환합니다.

시도해보기
-----

구문
--

```js
x++
++x
```

설명
--

만약 피연산자 뒤에 연산자를 붙여서 사용한다면 (예를 들어 `x++`) 증가 연산자는 수를 증가시키고 증가하기 전 값을 반환합니다.

만약 피연산자 앞에 연산자를 붙여서 사용한다면(예를 들어 `++x`) 증가 연산자는 수를 증가시키고 증가 후 값을 반환합니다.

증가 연산자는 참조인 피연산자 변수 및 객체 속성, 다시말해 유효한 할당 대상에만 적용할 수 있습니다. `++x` 자체는 참조가 아닌 값으로 평가되기 때문에 여러 증가 연산자를 연속적으로 사용할 수 없습니다.

```js
++(++x); // SyntaxError: Invalid left-hand side expression in prefix operation
```

예제
--

### 후위 증가

```js
let x = 3;
const y = x++;

// x = 4
// y = 3
```

### 전위 증가

```js
let x = 3;
const y = ++x;

// x = 4
// y = 4
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-postfix-increment-operator |

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

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

같이 보기
-----

* 더하기 연산자
* 빼기 연산자
* 나누기 연산자
* 곱하기 연산자
* 나머지 연산자
* 거듭제곱 연산자
* 감소 연산자
* 단항 부정 연산자
* 단항 더하기 연산자


void - JavaScript

void
====

**`void` 연산자**는 주어진 표현식을 평가하고 `undefined`를 반환합니다.

시도해보기
-----

구문
--

```js
void expression;
```

설명
--

`void`는 값을 생성하는 표현식을 평가해서 `undefined`를 반환합니다.

오직 `undefined` 원시값을 얻기 위해 `void 0` 또는 `void(0)`처럼 사용하는 경우도 볼 수 있습니다. 이런 경우 전역 `undefined`를 대신 사용해도 됩니다.

`void` 연산자의 우선순위도 유념해야 합니다. 그룹 연산자(괄호)를 사용하면 `void` 연산자를 사용한 식의 평가 과정을 더 명확하게 보일 수 있습니다.

```js
void 2 == "2"; // undefined == '2', false
void (2 == "2"); // void true, undefined
```

IIFE
----

즉시 실행 함수 표현식(IIFE)을 사용할 때 `void`를 사용하면 `function` 키워드를 선언문이 아니라 표현식처럼 간주하도록 강제할 수 있습니다.

```js
void (function iife() {
  var bar = function () {};
  var baz = function () {};
  var foo = function () {
    bar();
    baz();
  };
  var biz = function () {};

  foo();
  biz();
})();
```

JavaScript URI
--------------

`javascript:`로 시작하는 URI를 지원하는 브라우저에서는, URI에 있는 코드의 평가 결과가 `undefined`가 아니라면 페이지의 콘텐츠를 반환 값으로 대체합니다. `void` 연산자를 사용하면 `undefined`를 반환할 수 있습니다. 다음 예제를 확인하세요.

```html
<a href="javascript:void(0);">클릭해도 아무 일도 없음</a>
<a href="javascript:void(document.body.style.backgroundColor='green');">
  클릭하면 배경색이 녹색으로
</a>
```

**참고**: `javascript:` 의사 프로토콜보다 이벤트 처리기와 같은 대체재 사용을 권장합니다.

새지 않는 화살표 함수
------------

Arrow functions introduce a short-hand braceless syntax that returns an expression. This can cause unintended side effects by returning the result of a function call that previously returned nothing. To be safe, when the return value of a function is not intended to be used, it can be passed to the void operator to ensure that (for example) changing APIs do not cause arrow functions' behaviors to change.

```js
button.onclick = () => void doSomething();
```

This ensures the return value of `doSomething` changing from `undefined` to `true` will not change the behavior of this code.

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-void-operator |

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

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

같이 보기
-----

* `undefined`


감소 연산자 (--) - JavaScript

감소 연산자 (--)
===========

**감소(`--`) 연산자** 는 피연산자를 감소(1을 뺌)시키고 연산자의 위치에 따라 감소하기 전이나 후의 값을 반환합니다.

시도해보기
-----

구문
--

```js
x--
--x
```

설명
--

만약 피연산자 뒤에 연산자를 붙여서 사용한다면 (예를 들어 `x--`) 감소 연산자는 수를 감소시키고 감소하기 전 값을 반환합니다.

만약 피연산자 앞에 연산자를 붙여서 사용한다면(예를 들어 `--x`) 감소 연산자는 수를 감소시키고 감소 후 값을 반환합니다.

 감소 연산자는 참조인 피연산자(변수 및 객체 속성, 다시 말해 유효한
 할당 대상에만 적용할 수 있습니다.
 `--x` 자체는 참조가 아닌 값으로 평가되기 때문에 여러 감소 연산자를 연속적으로 사용할 수 없습니다.

```js
--(--x); // SyntaxError: Invalid left-hand side expression in prefix operation
```

예제
--

### 후위 감소

```js
let x = 3;
const y = x--;
// x = 2
// y = 3
```

### 전위 감소

```js
let x = 3;
const y = --x;
// x = 2
// y = 2
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-postfix-decrement-operator |

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

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

같이 보기
-----

* 더하기 연산자
* 빼기 연산자
* 나누기 연산자
* 곱하기 연산자
* 나머지 연산자
* 거듭제곱 연산자
* 증가 연산자
* 단항 부정 연산자
* 단항 더하기 연산자


그룹 연산자 - JavaScript

그룹 연산자
======

**그룹 연산자 `()`** 는 표현식 내에서 평가의 우선순위를 제어합니다.

시도해보기
-----

구문
--

```js
     ( )
```

설명
--

그룹 연산자는 표현식이나 중첩 표현식 주위를 감싸는 한 쌍의 괄호로 이루어진 연산자로, 감싸인 식이 더 높은 우선순위를 갖도록 일반적인 연산자 우선순위를 재정의합니다. 이름 그대로, 그룹 연산자는 괄호 안의 내용을 묶습니다.

예제
--

다음 예제에서는 곱셈과 나눗셈 이후 덧셈과 뺄셈을 사용하는 일반적인 연산 순서를 그룹 연산자를 사용해 바꿉니다.

```js
var a = 1;
var b = 2;
var c = 3;

// 기본 우선순위
a + b \* c; // 7
// 이것과 같음
a + (b \* c); // 7

// 더하기를 곱하기보다 먼저 하도록
// 우선순위 변경
(a + b) \* c; // 9

// 이것과 같음
a \* c + b \* c; // 9
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-grouping-operator |

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

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

같이 보기
-----

* 연산자 우선순위
* `delete` (en-US)
* `typeof`


할당 연산자 (=) - JavaScript

할당 연산자 (=)
==========

**할당(`=`)** 연산자는 변수에 값을 대입하는 데 사용됩니다. 할당 연산은 할당된 값으로 평가됩니다. 할당 연산자를
 연결하여 사용하면 단일 값을 여러 변수에 할당할 수 있습니다.

시도해보기
-----

구문
--

```js
x = y
```

예제
--

### 간단한 대입과 연결하여 사용

```js
let x = 5;
let y = 10;
let z = 25;

x = y; // x 는 10입니다.
x = y = z; // x, y, z 는 모두 25입니다.
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

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

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

같이 보기
-----

* JavaScript 가이드에서 할당 연산자
* 구조 분해 할당


조건 (삼항) 연산자 - JavaScript

조건 (삼항) 연산자
===========

**조건 (삼항) 연산자**는 JavaScript에서 세 개의 피연산자를 받는 유일한 연산자입니다. 앞에서부터 조건문, 물음표(`?`), 조건문이 참(truthy)일 경우 실행할 표현식, 콜론(`:`), 조건문이 거짓(falsy)일 경우 실행할 표현식이 배치됩니다. 해당 연산자는 `if...else`문의 대체재로 빈번히 사용됩니다.

시도해보기
-----

구문
--

```js
condition ? exprIfTrue : exprIfFalse;
```

### 매개변수

`condition`

조건문으로 사용되는 표현식

`exprIfTrue`

`condition`이 truthy한 값으로 평가될 경우 실행되는 표현식 (`true`와 같거나, `true`로 치환될 수 있는 값)

`exprIfFalse`

`condition`이 falsy한 값으로 평가될 경우 실행되는 표현식 (`false`와 같거나, `false`로 치환될 수 있는 값)

설명
--

`false` 이외의 falsy한 표현식에는 `null`, `NaN`, `0`, 비어있는 문자열 (`""`), 그리고 `undefined`가 있습니다. `condition`이 이 중 하나일 경우 조건 연산자의 결괏값은 `exprIfFalse` 표현식을 실행한 결괏값입니다.

예제
--

### 간단한 예제

```js
var age = 26;
var beverage = age >= 21 ? "Beer" : "Juice";
console.log(beverage); // "Beer"
```

### null 값 처리하기

`null`일 수 있는 값을 처리할 때 흔히 사용됩니다:

```js
let greeting = (person) => {
  let name = person ? person.name : `stranger`;
  return `Howdy, ${name}`;
};

console.log(greeting({ name: `Alice` })); // "Howdy, Alice"
console.log(greeting(null)); // "Howdy, stranger"
```

### 연결된 조건문 처리하기

조건 연산자는 아래와 같이 연결해 사용할 수 있습니다. 이는 연결된 `if … else if … else if … else`와 유사합니다.

```js
function example(…) {
    return condition1 ? value1
         : condition2 ? value2
         : condition3 ? value3
         : value4;
}
```

위 코드는 아래의 연결된 `if … else`와 동등합니다.

```js
function example(…) {
    if (condition1) { return value1; }
    else if (condition2) { return value2; }
    else if (condition3) { return value3; }
    else { return value4; }
}
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-conditional-operator |

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

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

같이 보기
-----

* if statement


비트 AND 할당 연산 (&=) - JavaScript

비트 AND 할당 연산 (&=)
=================

**비트 AND 할당 (`&=`)** 연산자는 두 피연산자의 이진 표현을 사용하고, 피연산자에 대한 AND 비트 연산 수행 결과를 변수에 할당합니다.

시도해보기
-----

구문
--

```js
x &= y // x = x & y
```

예제
--

### 비트 AND 할당 연산 사용하기

```js
let a = 5;
// 5: 00000000000000000000000000000101
// 2: 00000000000000000000000000000010
a &= 2; // 0
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

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

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

같이 보기
-----

* JS의 할당 연산자 안내서
* AND 비트 연산자


new.target - JavaScript

new.target
==========

**`new.target`** 속성(property)은 함수 또는 생성자가 new 연산자를 사용하여 호출됐는지를 감지할 수 있습니다. new 연산자로 인스턴스화된 생성자 및 함수에서, `new.target`은 생성자 또는 함수 참조를 반환합니다. 일반 함수 호출에서는, `new.target`은 `undefined`입니다.

시도해보기
-----

구문
--

```js
new.target;
```

설명
--

`new.target` 구문은 키워드 "`new`", 점 및 속성명 "`target`"으로 구성됩니다. 보통 "`new.`"은 속성 접근을 위한 문맥(context)으로 제공하지만 여기서 "`new.`"은 정말 객체가 아닙니다. 그러나, 생성자 호출에서 `new.target`은 `new`에 의해 호출된 생성자를 가리키고 그래서 "`new.`"은 가상 문맥이 됩니다.

`new.target` 속성은 모든 함수가 이용할 수 있는 메타 속성입니다. 화살표 함수에서, `new.target`은 둘러싸는 함수의 `new.target`을 말합니다.

예
-

### 함수 호출에서 new.target

일반 함수 호출(생성자 함수 호출과는 반대로)에서, `new.target`은 `undefined`입니다. 이는 함수가 생성자로서 new로 호출된 경우를 감지할 수 있습니다.

```js
function Foo() {
  if (!new.target) throw "Foo() must be called with new";
  console.log("Foo instantiated with new");
}

Foo(); // throws "Foo() must be called with new"
new Foo(); // logs "Foo instantiated with new"
```

### 생성자에서 new.target

클래스 생성자에서, `new.target`은 `new`에 의해 직접 호출된 생성자를 가리킵니다. 이는 그 생성자가 부모 클래스에 있고 자식 생성자로부터 위임받은 경우도 그 경우입니다.

```js
class A {
  constructor() {
    console.log(new.target.name);
  }
}

class B extends A {
  constructor() {
    super();
  }
}

var a = new A(); // logs "A"
var b = new B(); // logs "B"
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-built-in-function-objects |

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

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

같이 보기
-----

* 함수
* 클래스
* `new`
* `this`


거듭제곱 (**) - JavaScript

거듭제곱 (\*\*)
===========

 거듭제곱 연산자(`**`)는 왼쪽 피연산자를 밑, 오른쪽 피연산자를 지수로 한 값을 구합니다.
 `BigInt`도 피연산자로 받을 수 있다는 점을 제외하면 `Math.pow()`와 같습니다.

시도해보기
-----

구문
--

```js
x \*\* y;
```

설명
--

거듭제곱 연산자는 우측 결합성을 가집니다. 따라서 `a ** b ** c`는 `a ** (b ** c)`와 같습니다.

 PHP, Python 등 거듭제곱 연산자(`**`)를 포함하는 언어의 대부분은 거듭제곱 연산자가 단항 연산자(단항
 `+`, `-` 등)보다 높은 우선순위를 가집니다. 그러나 Bash처럼 단항 연산자가 더 높은 우선순위를
 가지는 예외의 언어도 있습니다.

 반면 JavaScript에서는 모호한 거듭제곱 표현식을 작성하는 것이 불가능합니다. 단항
 연산자(`+/-/~/!/delete/void/typeof`)를 밑 피연산자의 바로 앞에 사용할 수 없으며, 사용하려고 하면
 `SyntaxError`가 발생합니다.

```js
-2 \*\* 2;
// Bash에서는 4, 다른 언어에서는 -4
// 모호한 식이므로 JavaScript에서 유효하지 않음

-(2 \*\* 2);
// JavaScript에서 -4, 저자의 의도가 명확함
```

 참고로 어떤 언어에선 캐럿 기호 `^`를 거듭제곱에 사용하지만, JavaScript에서 캐럿은
 비트 XOR 연산자 (en-US)에서
 사용합니다.

예제
--

### 기본 거듭제곱

```js
2 \*\* 3; // 8
3 \*\* 2; // 9
3 \*\* 2.5; // 15.588457268119896
10 \*\* -1; // 0.1
NaN \*\* 2; // NaN
```

### 연관성

```js
2 \*\* 3 \*\* 2; // 512
2 \*\* (3 \*\* 2); // 512
(2 \*\* 3) \*\* 2; // 64
```

### 단항 연산자와 사용하기

거듭제곱 결과의 부호를 반전하려면,

```js
-(2 \*\* 2); // -4
```

거듭제곱 표현식의 밑에 음수를 제공하려면,

```js
(-2) \*\* 2; // 4
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-exp-operator |

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

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

같이 보기
-----

* 더하기 연산자
* 빼기 연산자
* 나누기 연산자
* 곱하기 연산자
* 나머지 연산자
* 증가 연산자
* 감소 연산자
* 단항 부정 연산자
* 단항 플러스 연산자


논리적 NOT (!) - JavaScript

논리적 NOT (!)
===========

**논리적 NOT (`!`)** (논리적 보수, 부정) 연산자는 참을 거짓으로 만들고, 반대로 거짓을 참으로 만듭니다. 일반적으로 불리언 (논리적) 값과 함께 사용됩니다. 불리언이 아닌 값들과 함께 사용된다면, 단일 피연산자가 `true`로 변환될 수 있으면 `false`를 반환하고, 그렇지 않으면 `true`를 반환합니다.

시도해보기
-----

구문
--

```js
!x
```

설명
--

 단일 피연산자가 `true`로 변환될 수 있으면 `false`를 반환합니다.
 그렇지 않으면, `true`를 반환합니다.

만약 어떤 값이 `true`로 변환 가능하다면, 그 값은 소위 참 같은 값입니다. 만약 어떤 값이 `false`로 변환 가능하다면, 그 값은 소위 거짓 같은 값 이라고 합니다.

거짓으로 변환될 수 있는 표현식의 예시는 다음과 같습니다.

* `null`;
* `NaN`;
* `0`;
* 빈 문자열 (`""` or `''` or ````);
* `undefined`.

`!` 연산자는 불리언 값이 아닌 피연산자와 함께 사용할 수 있지만, 반환값이 항상 원시형 불리언으로 변환될 수 있기 때문에 여전히 불리언 연산자로 간주할 수 있습니다. 명시적으로 반환값을 (또는 일반적으로 어떤 표현식을) 대응하는 불리언 값으로 변환하기 위해서는 이중 NOT 연산자 (`!!`) 또는 `Boolean` 생성자를 사용하시기 바랍니다.

예제
--

### NOT 사용하기

다음 코드는 `!`(논리적 NOT) 연산자의 예제를 보여줍니다.

```js
!true; // !t 는 false를 반환합니다
!false; // !f 는 true를 반환합니다
!""; // !f 는 true를 반환합니다
!"Cat"; // !t 는 false를 반환합니다
```

### 이중 NOT (`!!`)

 NOT 연산자를 연속으로 2개 사용해서 명시적으로 어떤 값을 그에 대응하는 원시형 불리언으로 변환하도록 강제할 수 있습니다.
 변환은 값의 "참 같음" 또는 "거짓 같음"에 기반합니다(참 같은 값과 거짓 같은 값을 참고하세요).

`Boolean` 함수를 통해서도 똑같은 변환을 수행할 수 있습니다.

```js
!!true; // !!truthy는 true를 반환합니다.
!!{}; // !!truthy는 true를 반환합니다. 임의의 object는 참 같은 객체입니다.
!!new Boolean(false); // .valueOf()에서 false값을 가지는 불리언 객체도요!
!!false; // !!falsy는 false를 반환합니다.
!!""; // !!falsy는 false를 반환합니다.
!!Boolean(false); // !!falsy는 false를 반환합니다.
```

### NOT 사이에서의 변환

**불리언**울 포함하는 다음 연산

```js
!!bCondition
```

는 항상 아래와 같습니다.

```js
bCondition
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-logical-not-operator |

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

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

같이 보기
-----

* `Boolean`
* Truthy
* Falsy


부등 연산자(!=) - JavaScript

부등 연산자(!=)
==========

부등 연산자(!=)는 두 피연산자가 같지 않은지 확인하여 불리언 결과를 반환합니다. 엄격한 부등 연산자와는 달리 다른 유형의 피연산자를 암묵적으로 변환하고 비교합니다.

시도해보기
-----

구문
--

```js
x != y;
```

설명
--

부등식 연산자는 피연산자가 같지 않은지 여부를 확인합니다. 동등 연산자의 부정이므로 다음 두 줄은 항상 같은 결과를 제공합니다.

```js
x != y;

!(x == y);
```

비교 알고리즘에 대한 자세한 내용은 동등 연산자 페이지를 참조하십시오.

동등 연산자와 마찬가지로 부등 연산자도 다른 유형의 피연산자를 변환하여 비교합니다.

```js
3 != "3"; // false
```

이를 방지하고 다른 유형이 다른 것으로 간주되게 하려면 엄격한 불일치 연산자 (en-US)를 사용해야 합니다.

```js
3 !== "3"; // true
```

예제
--

### 타입 변환이 없는 비교

```js
1 != 2; // true
"hello" != "hola"; // true

1 != 1; // false
"hello" != "hello"; // false
```

### 타입 변환이 있는 비교

```js
"1" != 1; // false
1 != "1"; // false
0 != false; // false
0 != null; // true
0 != undefined; // true
0 != !!null; // false, look at Logical NOT operator
0 != !!undefined; // false, look at Logical NOT operator
null != undefined; // false

const number1 = new Number(3);
const number2 = new Number(3);
number1 != 3; // false
number1 != number2; // true
```

### 객체의 비교

```js
const object1 = { key: "value" };
const object2 = { key: "value" };

object1 != object2; // true
object2 != object2; // false
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-equality-operators |

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

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

관련 문서
-----

* Equality
operator
* Strict
equality operator (en-US)
* Strict
inequality operator (en-US)


Logical OR (

Logical OR (||)
===============

**논리적 OR (`||`)** (논리적 분리) 연산자는 피연산자 중 하나 이상이 참인 경우에만 참입니다. 일반적으로 불리언(논리적) 값과 함께 사용되며, 이 경우에는 불리언 값을 반환합니다. 그러나 `||` 연산자는 실제로 지정된 피연산자 중 하나의 값을 반환하므로, 이 연산자를 불리언이 아닌 값과 함께 사용하면 불리언이 아닌 값이 반환됩니다.

시도해보기
-----

문법
--

```js
x || y
```

구문
--

만약 `x`를 `true`로 반환할 수 있으면 `x`를 반환하고, 그렇지 않으면 `y`를 반환합니다.

값을 `true`로 변환할 수 있는 경우, 해당 값은 소위 truthy하다고 할 수 있습니다. 값을 `false`로 변환할 수 있으면, 해당 값을 falsy하다고 할 수 있습니다.

false로 변환할 수 있는 표현식의 예는 다음과 같습니다.

* `null`;
* `NaN`;
* `0`;
* 빈 문자열 (`""` 또는 `''` 또는 ````);
* `undefined`.

`||` 연산자는 불리언 값이 아닌 피연산자와 함께 사용할 수 있지만, 반환 값은 항상 불리언 원시 값으로 변환할 수 있으므로 불리언 연산자로 간주할 수 있습니다. 반환 값(또는 일반적으로 모든 표현식)을 해당 불리언 값으로 명시적으로 변환하려면 이중 [NOT operator] 또는 `Boolean` 생성자를 사용합니다.

### 단락 평가

논리적 OR 표현식은 왼쪽에서 오른쪽으로 평가되며, 다음 규칙을 사용하여 "단락" 평가가 가능한지 테스트합니다.

`(some truthy expression) || expr`은 참 같은 값(truthy) 표현식으로 단락 평가됩니다.

단락은 위의 `expr` 부분이 **평가되지 않으므로** 이로 인한 부작용이 발생하지 않음을 의미합니다. (예: `expr`이 함수 호출인 경우 호출이 수행되지 않음) 이는 첫 번째 피연산자를 평가한 후에 피연산자 값이 이미 결정되었기 때문에 발생합니다. 아래 예제를 참조하세요.

```js
function A() {
  console.log("called A");
  return false;
}
function B() {
  console.log("called B");
  return true;
}

console.log(B() || A());
// 함수 호출로 인해 "called B"를 콘솔에 출력합니다.
// 그런 다음 true(연산자의 결과 값)를 기록합니다.
```

### 연산자 우선순위

다음 표현식은 동일해 보일 수 있지만, `&&` 연산자가 `||` 연산자보다 먼저 실행되기 때문에 동일하지 않습니다. (연산자 우선순위를 참조).

```js
true || false && false; // &&이 먼저 실행되어 true를 반환합니다.
(true || false) && false; // 그룹화가 가장 우선순위가 높으므로, false를 반환합니다.
```

예제
--

### OR 사용하기

다음 코드는 `||` (논리적 OR) 연산자의 예를 보여줍니다.

```js
true || true; // t || t returns true
false || true; // f || t returns true
true || false; // t || f returns true
false || 3 === 4; // f || f returns false
"Cat" || "Dog"; // t || t returns "Cat"
false || "Cat"; // f || t returns "Cat"
"Cat" || false; // t || f returns "Cat"
"" || false; // f || f returns false
false || ""; // f || f returns ""
false || varObject; // f || object returns varObject
```

**참고:** 이 연산자를 사용하여 일부 변수에 기본값을 제공하는 경우, 거짓 같은 값(falsy)은 사용되지 않으므로 주의해야 합니다.
 `null` 또는 `undefined`만 필터링해야 하는 경우, 널 병합 연산자를 사용하는 것이 좋습니다.

### 불리언에 대한 변환 규칙

#### AND를 OR로 변환하기

**불리언**을 포함하는 아래 연산은

```js
bCondition1 && bCondition2
```

항상 아래와 같습니다.

```js
!(!bCondition1 || !bCondition2)
```

#### OR을 AND로 변환하기

**불리언**을 포함하는 아래의 연산은

```js
bCondition1 || bCondition2
```

항상 아래와 같습니다.

```js
!(!bCondition1 && !bCondition2)
```

### 중첩된 괄호 제거

논리적 표현식은 왼쪽에서 오른쪽으로 평가되기 때문에 특정 규칙을 따르는 경우 복잡한 식에서 괄호를 제거할 수 있습니다.

**불리언**을 포함하는 다음 복합적인 연산은

```js
bCondition1 && (bCondition2 || bCondition3)
```

언제나 다음과 같습니다.

```js
!(!bCondition1 || !bCondition2 && !bCondition3)
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-LogicalORExpression |

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

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

같이 보기
-----

* Nullish coalescing operator (`??`)
* `Boolean`
* Truthy
* Falsy


전개 구문 - JavaScript

전개 구문
=====

**전개 구문**을 사용하면 배열이나 문자열과 같이 반복 가능한 문자를 0개 이상의 인수 (함수로 호출할 경우) 또는 요소 (배열 리터럴의 경우)로 확장하여, 0개 이상의 키-값의 쌍으로 객체로 확장시킬 수 있습니다.

시도해보기
-----

구문
--

함수 호출:

```js
myFunction(...iterableObj);
```

배열 리터럴과 문자열:

```js
[...iterableObj, "4", "five", 6];
```

객체 리터럴(ECMAScript 2018에서 추가):

```js
let objClone = { ...obj };
```

예제
--

### 함수 호출에서의 전개

#### `apply()` 대체

일반적으로 배열의 엘리먼트를 함수의 인수로 사용하고자 할 때 `Function.prototype.apply()` 를 사용하였습니다.

```js
function myFunction(x, y, z) {}
var args = [0, 1, 2];
myFunction.apply(null, args);
```

전개 구문을 사용해 위 코드는 다음과 같이 작성될 수 있습니다.

```js
function myFunction(x, y, z) {}
var args = [0, 1, 2];
myFunction(...args);
```

인수 목록의 모든 인수는 전개 구문을 사용할 수 있으며, 여러번 사용될 수도 있습니다.

```js
function myFunction(v, w, x, y, z) {}
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);
```

#### `new`에 적용

`new`를 사용해 생성자를 호출 할 때, 배열과 `apply` (`apply` 는 `[[Call]]` 을 하지만 `[[Construct]]` 는 그렇지 않음) 를 **직접** 사용하는 것은 불가했습니다. 하지만, 전개 구문 덕분에 배열을 `new` 와 함께 쉽게 사용될 수 있습니다.

```js
var dateFields = [1970, 0, 1]; // 1 Jan 1970
var d = new Date(...dateFields);
```

전개 구문 없이 파라미터의 배열과 함께 `new`를 사용하려면, 부분적인 어플리케이션을 통해 **간접적**으로 해야 합니다.

```js
function applyAndNew(constructor, args) {
  function partial() {
    return constructor.apply(this, args);
  }
  if (typeof constructor.prototype === "object") {
    partial.prototype = Object.create(constructor.prototype);
  }
  return partial;
}

function myConstructor() {
  console.log("arguments.length: " + arguments.length);
  console.log(arguments);
  this.prop1 = "val1";
  this.prop2 = "val2";
}

var myArguments = ["hi", "how", "are", "you", "mr", null];
var myConstructorWithArguments = applyAndNew(myConstructor, myArguments);

console.log(new myConstructorWithArguments());
// (internal log of myConstructor): arguments.length: 6
// (internal log of myConstructor): ["hi", "how", "are", "you", "mr", null]
// (log of "new myConstructorWithArguments"): {prop1: "val1", prop2: "val2"}
```

### 배열 리터럴에서의 전개

#### 더 강력한 배열 리터럴

전개 구문 없이, 이미 존재하는 배열을 일부로 하는 새로운 배열을 생성하기에, 배열 리터럴 문법은 더 이상 충분하지 않으며 `push()`, `splice()`, `concat()` 등의 조합을 사용하는 대신 명령형 코드를 사용해야 했습니다. 전개 구문으로 이는 훨씬 더 간결해졌습니다.

```js
var parts = ["shoulders", "knees"];
var lyrics = ["head", ...parts, "and", "toes"];
// ["head", "shoulders", "knees", "and", "toes"]
```

인수 목록을 위한 spread 처럼, `...` 은 배열 리터럴의 어디에서든 사용될 수 있으며 여러번 사용될 수도 있습니다.

#### 배열 복사

```js
var arr = [1, 2, 3];
var arr2 = [...arr]; // arr.slice() 와 유사
arr2.push(4);

// arr2 은 [1, 2, 3, 4] 이 됨
// arr 은 영향을 받지 않고 남아 있음
```

**참고:** Spread 문법은 배열을 복사할 때 1 레벨 깊이에서 효과적으로 동작합니다. 그러므로, 다음 예제와 같이 다차원 배열을 복사하는것에는 적합하지 않을 수 있습니다. (`Object.assign()` 과 전개 구문이 동일합니다)

```js
var a = [[1], [2], [3]];
var b = [...a];
b.shift().shift(); // 1
// 이제 배열 a 도 영향을 받음: [[], [2], [3]]
```

#### 배열을 연결하는 더 나은 방법

`Array.prototype.concat()` 은 배열을 존재하는 배열의 끝에 이어붙이는데 종종 사용됩니다. 전개 구문 없이, 이는 다음과 같이 작성됩니다.

```js
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// arr2 의 모든 항목을 arr1 에 붙임
arr1 = arr1.concat(arr2);
```

전개 구문을 사용해 이는 다음과 같아집니다.

```js
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2]; // arr1 은 이제 [0, 1, 2, 3, 4, 5]
```

`Array.prototype.unshift()`는 존재하는 배열의 시작 지점에 배열의 값들을 삽입하는데 종종 사용됩니다. 전개 구문 없이, 이는 다음과 같이 작성됩니다.

```js
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// arr2 의 모든 항목을 arr1 의 앞에 붙임
Array.prototype.unshift.apply(arr1, arr2); // arr1 은 이제 [3, 4, 5, 0, 1, 2] 가 됨
```

전개 구문으로, 이는 다음과 같아집니다.

```js
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr2, ...arr1]; // arr1 은 이제 [3, 4, 5, 0, 1, 2] 가 됨
```

**참고**: `unshift()`와 달리, 위 예제는 새로운 `arr1`을 만들며 기존 배열을 변형하지 않습니다.

### 객체 리터럴에서의 전개

ECMAScript의 Rest/Spread 프로퍼티 제안 (stage 4) 은 객체 리터럴에 속성 전개를 추가합니다. 이는 제공된 객체가 소유한 열거형 프로퍼티를 새로운 객체로 복사합니다.

얕은 복제(prototype 제외) 또는 객체의 병합은 이제 `Object.assign()` 보다 더 짧은 문법을 사용해 가능합니다.

```js
var obj1 = { foo: "bar", x: 42 };
var obj2 = { foo: "baz", y: 13 };

var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }
```

`Object.assign()` 은 setters 를 트리거하지만 전개 구문은 그렇지 않음을 유의합니다.

`Object.assign()` 함수를 대체하거나 흉내낼 수 없음을 유의합니다.

```js
var obj1 = { foo: "bar", x: 42 };
var obj2 = { foo: "baz", y: 13 };
const merge = (...objects) => ({ ...objects });

var mergedObj = merge(obj1, obj2);
// Object { 0: { foo: 'bar', x: 42 }, 1: { foo: 'baz', y: 13 } }

var mergedObj = merge({}, obj1, obj2);
// Object { 0: {}, 1: { foo: 'bar', x: 42 }, 2: { foo: 'baz', y: 13 } }
```

위 예제에서, 전개 구문은 예상대로 동작하지 않습니다. 나머지 매개변수로 인해, 인수 배열을 객체 리터럴로 전개합니다.

### 이터러블 전용

전개 구문 (spread 프로퍼티인 경우 제외) 은 iterable 객체에만 적용됩니다.

```js
var obj = { key1: "value1" };
var array = [...obj]; // TypeError: obj is not iterable
```

### 많은 값과 Spread

함수 호출에서 spread 문법을 사용할 때, JavaScript 엔진의 인수 길이 제한을 초과하지 않도록 주의합니다. 자세한 내용은 `apply()` 를 보세요.

나머지 구문 (매개변수)
-------------

나머지 구문은 전개 구문과 정확히 같아보이지만, 대신 배열이나 객체를 분해할 때 사용됩니다. 어떤 면에서, 나머지 구문은 전개 구문과 반대입니다. 전개는 배열을 그 엘리먼트로 '확장' 하는 반면, 나머지는 여러 엘리먼트를 수집하며 이를 하나의 엘리먼트로 '압축' 합니다. 나머지 매개변수 문서를 보세요.

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-SpreadElement |
| ECMAScript Language Specification # prod-ArgumentList |
| ECMAScript Language Specification # prod-PropertyDefinition |

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

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

같이 보기
-----

* 나머지 매개변수 (또한 '`...`')
* fn.apply (또한 '`...`')


yield* - JavaScript

yield\*
=======

**`yield*` 표현식**은 다른 `generator` 또는 이터러블(iterable) 객체에 yield를 위임할 때 사용됩니다.

시도해보기
-----

구문
--

```js
yield\* [[expression]];
```

`expression`

이터러블(iterable) 객체를 반환하는 표현식.

설명
--

yield\* 표현은 피연산자를 반복하고 반환되는 값을 yield합니다.

yield\* 표현 자체의 값은 반복자(iterator)가 종료될 때 반환되는 값입니다. (i.e., done이 true일 때)

예제
--

### 다른 생성기(generator)에 위임하기

다음 코드는, next() 호출을 통해 g1()으로부터 yield 되는 값을 g2()에서 yield 되는 것처럼 만듭니다.

```js
function\* g1() {
  yield 2;
  yield 3;
  yield 4;
}

function\* g2() {
  yield 1;
  yield\* g1();
  yield 5;
}

var iterator = g2();

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: 4, done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
```

### 다른 이터러블(iterable) 객체

생성기 객체 말고도, yield\*는 다른 반복 가능한 객체도 yield 할 수 있습니다. e.g. 배열, 문자열 또는 arguments 객체

```js
function\* g3() {
  yield\* [1, 2];
  yield\* "34";
  yield\* Array.from(arguments);
}

var iterator = g3(5, 6);

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: "3", done: false }
console.log(iterator.next()); // { value: "4", done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: 6, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
```

### `yield*` 표현 자체의 값

`yield*` 는 구문이 아닌 표현입니다. 따라서 값으로 평가됩니다.

```js
function\* g4() {
  yield\* [1, 2, 3];
  return "foo";
}

var result;

function\* g5() {
  result = yield\* g4();
}

var iterator = g5();

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true },
// g4() 는 여기서 { value: "foo", done: true }를 반환합니다

console.log(result); // "foo"
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-generator-function-definitions-runtime-semantics-evaluation |

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

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

같이 보기
-----

* The Iterator protocol (en-US)
* `function*`
* `function* expression`
* `yield`


typeof - JavaScript

typeof
======

**`typeof`** 연산자는 피연산자의 평가 전 자료형을 나타내는 문자열을 반환합니다.

시도해보기
-----

구문
--

`typeof` 연산자는 피연산자 앞에 위치합니다.

```js
typeof operand;
typeof (operand);
```

### 매개변수

`operand`

자료형을 가져올 객체 또는 원시값을 나타내는 표현식.

설명
--

`typeof`가 반환할 수 있는 값을 아래 표에서 볼 수 있습니다. 자료형과 원시값에 대한 자세한 정보는 JavaScript 자료형과 자료구조 페이지를 참고하세요.

| Type | Result |
| --- | --- |
| Undefined | `"undefined"` |
| Null | `"object"` (아래 참고) |
| Boolean | `"boolean"` |
| Number | `"number"` |
| BigInt | `"bigint"` |
| String | `"string"` |
| Symbol (ECMAScript 2015에서 추가) | `"symbol"` |
| 호스트 객체 (JS 환경에서 제공) | *구현체마다 다름* |
| Function 객체 (ECMA-262 표현으로는 [[Call]]을 구현하는 객체) | `"function"` |
| 다른 모든 객체 | `"object"` |

**참고:** ECMAScript 2019 and older permitted implementations to have `typeof` return any implementation-defined string value for non-callable non-standard exotic objects.

The only known browser to have actually taken advantage of this is old Internet Explorer (see below).

예제
--

```js
// Numbers
typeof 37 === "number";
typeof 3.14 === "number";
typeof Math.LN2 === "number";
typeof Infinity === "number";
typeof NaN === "number"; // Despite being "Not-A-Number"
typeof Number(1) === "number"; // but never use this form!

typeof 42n === "bigint";

// Strings
typeof "" === "string";
typeof "bla" === "string";
typeof typeof 1 === "string"; // typeof always returns a string
typeof String("abc") === "string"; // but never use this form!

// Booleans
typeof true === "boolean";
typeof false === "boolean";
typeof Boolean(true) === "boolean"; // but never use this form!

// Symbols
typeof Symbol() === "symbol";
typeof Symbol("foo") === "symbol";
typeof Symbol.iterator === "symbol";

// Undefined
typeof undefined === "undefined";
typeof declaredButUndefinedVariable === "undefined";
typeof undeclaredVariable === "undefined";

// Objects
typeof { a: 1 } === "object";

// use Array.isArray or Object.prototype.toString.call
// to differentiate regular objects from arrays
typeof [1, 2, 4] === "object";

typeof new Date() === "object";

// The following is confusing. Don't use!
typeof new Boolean(true) === "object";
typeof new Number(1) === "object";
typeof new String("abc") === "object";

// Functions
typeof function () {} === "function";
typeof class C {} === "function";
typeof Math.sin === "function";
```

추가 정보
-----

### `null`

```js
// This stands since the beginning of JavaScript
typeof null === "object";
```

JavaScript를 처음 구현할 때, JavaScript 값은 타입 태그와 값으로 표시되었습니다. 객체의 타입 태그는 0이었습니다. `null`은 Null pointer(대부분의 플랫폼에서 `0x00`)로 표시되었습니다. 그 결과 null은 타입 태그로 0을 가지며, 따라서 `typeof`는 object를 반환합니다. (참고 문서)

ECMAScript에 수정이 제안(opt-in을 통해)되었으나 거절되었습니다. 제안된 것은 다음과 같습니다. `typeof null === 'null'.`

### Regular expressions

Callable regular expressions were a non-standard addition in some browsers.

```js
typeof /s/ === "function"; // Chrome 1-12 Non-conform to ECMAScript 5.1
typeof /s/ === "object"; // Firefox 5+ Conform to ECMAScript 5.1
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-typeof-operator |

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

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

IE 참고사항
-------

On IE 6, 7, and 8 a lot of host objects are objects and not functions. For example:

```js
typeof alert === "object";
```

같이 보기
-----

* `instanceof`


in 연산자 - JavaScript

in 연산자
======

**`in` 연산자**는 명시된 속성이 명시된 객체에 존재하면 `true`를 반환합니다.

구문
--

```js
속성 in 객체명;
```

### 인자

`속성`

속성의 이름이나 배열의 인덱스를 뜻하는 문자열 또는 수 값입니다.

`객체명`

객체의 이름입니다.

설명
--

다음 예제들은 `in` 연산자의 용도를 보여 줍니다.

```js
// 배열
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
0 in trees; // true를 반환합니다.
3 in
  trees(
    // true를 반환합니다.
    1 + 2,
  ) in
  trees; // true를 반환합니다. 연산자 우선 순위에 의하여 이 구문의 괄호는 없어도 됩니다.
6 in trees; // false를 반환합니다.
"bay" in trees; // false를 반환합니다. 당신은 배열의 내용이 아닌, 인덱스 값을 명시하여야 합니다.
"length" in trees; // true를 반환합니다. length는 Array(배열) 객체의 속성입니다.

// 미리 정의된 객체
"PI" in Math; // true를 반환합니다.
"P" + "I" in Math; // true를 반환합니다.

// 사용자가 정의한 객체
var myCar = {
  company: "Lamborghini",
  model: "Lamborghini Veneno Roadster",
  year: 2014,
};
"company" in myCar; // true를 반환합니다.
"model" in myCar; // true를 반환합니다.
```

당신은 반드시 `in` 연산자의 오른쪽에 객체를 명시하여야 합니다. 예컨대 당신은 `String` 생성자로 만들어진 문자열을 명시할 수 있지만 문자열 리터럴은 명시할 수 없습니다.

```js
var color1 = new String("green");
"length" in color1; // true를 반환합니다.

var color2 = "coral";
"length" in color2; // color2는 String 객체가 아니기에 오류를 냅니다.
```

### 제거되었거나 정의되지 않은 속성에 대하여 `in` 연산자 사용하기

`in` 연산자는 `delete` (en-US) 연산자로 제거된 속성에 대하여 `false`를 반환합니다.

```js
var myCar = {
  company: "Lamborghini",
  model: "Lamborghini Veneno Roadster",
  year: 2014,
};
delete myCar.company;
"company" in myCar; // false를 반환합니다.

var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
delete trees[3];
3 in trees; // false를 반환합니다.
```

만약 당신이 속성을 `undefined`로 설정하였는데 그것을 제거하지 않으면, `in` 연산자는 그 속성에 대하여 `true`를 반환합니다.

```js
var myCar = {
  company: "Lamborghini",
  model: "Lamborghini Veneno Roadster",
  year: 2014,
};
myCar.company = undefined;
"company" in myCar; // true를 반환합니다.
```

```js
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
trees[3] = undefined;
3 in trees; // true를 반환합니다.
```

### 상속된 속성

`in` 연산자는 프로토타입 체인에 의하여 접근할 수 있는 속성에 대하여 `true`를 반환합니다.

```js
"toString" in {}; // true를 반환합니다.
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-relational-operators |

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

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

관련 문서
-----

* `delete` (en-US)
* `Object.prototype.hasOwnProperty()` (en-US)
* `Reflect.has()`
* 속성의, 소유와 셀 수 있는 성질 (en-US)


동등 연산자(==) - JavaScript

동등 연산자(==)
==========

동등 연산자(==)는 두 개의 피연산자가 동일한지 확인하며, 불리언 결과를 반환합니다. 일치 연산자 (en-US)와는 다르게 다른 타입의 피연산자들끼리의 비교를 시도합니다.

시도해보기
-----

문법
--

```js
x == y
```

상세 설명
-----

동등 연산자 (`==` 와 `!=`)는 두 피연산자를 비교하기 위해 느슨한 같음을 사용합니다. 다음과 같이 간략히 설명할 수 있습니다.

1. 두 피연산자가 동일한 타입일 때는 다음과 같이 비교합니다.
    * 객체: 두 피연산자가 동일한 객체를 참조할 때만 `true`를 반환합니다.
    * 문자열: 두 피연산자가 동일한 문자를 동일한 순서로 가질 때만 `true`를 반환합니다.
    * 숫자: 두 피연산자가 동일한 값을 가질 때만 `true`를 반환합니다. `+0`과 `-0`은 동일한 값으로 취급합니다. 만약 두 피연산자가 모두 `NaN`이라면 `false`를 반환합니다. `NaN`은 항상 `NaN`과 다릅니다.
    * 불리언: 두 피연산자가 모두 `true`이거나 모두 `false`일 때만 `true`를 반환합니다.
    * BigInt: 두 피연산자가 동일한 값을 가질 때만 `true`를 반환합니다.
    * 심볼: 두 피연산자가 동일한 심볼을 참조할 때만 `true`를 반환합니다.
2. 하나의 피연산자가 `null`이거나 `undefined`인 경우, `true`를 반환하기 위해선 다른 하나가 무조건 `null`이거나 `undefined`여야 합니다. 그렇지 않으면 `false`를 반환합니다.
3. 하나의 피연산자가 객체이고 다른 하나가 원시 타입인 경우, 객체를 원시 타입으로 변환합니다.
4. 이 경우, 두 피연산자를 모두 원시 타입(문자열, 숫자, 불리언, 심볼, BigInt 중 하나)으로 변환합니다. 나머지 변환은 다음 순서를 따릅니다.
    * 두 피연산자의 타입이 같다면, 1단계를 이용해 비교합니다.
    * 하나의 피연산자가 심볼이고 다른 하나가 심볼이 아닌 경우, `false`를 반환합니다.
    * 하나의 피연산자가 불리언이고 다른 하나가 불리언이 아닌 경우, 불리언을 숫자로 변환합니다. `true`는 1로 변환하고 `false`는 0으로 변환합니다. 그 후 두 피연산자를 다시 느슨하게 비교합니다.
    * 숫자와 문자열: 문자열을 숫자로 변환합니다. 변환 실패의 결괏값은 `NaN`이므로, 비교 결과가 `false`라는 것을 보장합니다.
    * 숫자와 BigInt: 숫자 값으로 비교합니다. 숫자가 ±Infinity 혹은 `NaN`이면 `false`를 반환합니다.
    * 문자열과 BigInt: 문자열을 BigInt() 생성자와 같은 알고리즘으로 BigInt로 변환합니다. 만약 변환이 실패하면 `false`를 반환합니다.

동등 연산자는 대칭적입니다. A와 B가 어떤 값을 가져도 `A == B`는 `B == A`와 항상 동일한 의미입니다(타입 변환의 적용 순서를 제외하고).

일치 연산자 (en-US) (`===`)와의 가장 두드러지는 차이점은 일치 연산자는 타입 변환을 시도하지 않는다는 것입니다. 일치 연산자는 다른 타입을 가진 피연산자는 다르다고 판단합니다. 일치 연산자는 기본적으로 1단계만 수행하고 다른 모든 경우에 `false`를 반환합니다.

위 알고리즘에는 "고의적 위반"이 있습니다. 한 피연산자가 `document.all`인 경우, `undefined`처럼 처리됩니다. 이는 `document.all == null`은 `true`지만, `document.all === undefined && document.all === null`이 `false`라는 것을 의미합니다.

예시
--

### 타입변환 없이 비교

```js
1 == 1; // true
"hello" == "hello"; // true
```

### 타입변환을 이용한 비교

```js
"1" == 1; // true
1 == "1"; // true
0 == false; // true
0 == null; // false
0 == undefined; // false
0 == !!null; // true, look at Logical NOT operator
0 == !!undefined; // true, look at Logical NOT operator
null == undefined; // true

const number1 = new Number(3);
const number2 = new Number(3);
number1 == 3; // true
number1 == number2; // false
```

### 객체들 간의 비교

```js
const object1 = {
  key: "value",
};

const object2 = {
  key: "value",
};

console.log(object1 == object2); // false
console.log(object1 == object1); // true
```

### String과 String objects의 비교

`new String()` 을 통해 생성된 문자열들은 객체입니다. 이 객체 중 하나를 문자열과 비교한다면, `String` 객체가 문자열로 변환된 후 비교될 것입니다. 그러나 두 개의 피연산자 모두 `String` 객체라면, 객체로써 비교가 이루어지기 때문에 같은 값으로 취급되려면 같은 객체를 참조하고 있어야 합니다.

```js
const string1 = "hello";
const string2 = String("hello");
const string3 = new String("hello");
const string4 = new String("hello");

console.log(string1 == string2); // true
console.log(string1 == string3); // true
console.log(string2 == string3); // true
console.log(string3 == string4); // false
console.log(string4 == string4); // true
```

### Dates와 문자열의 비교

```js
const d = new Date("December 17, 1995 03:24:00");
const s = d.toString(); // for example: "Sun Dec 17 1995 03:24:00 GMT-0800 (Pacific Standard Time)"
console.log(d == s); //true
```

### 배열과 문자열의 비교

```js
const a = [1, 2, 3];
const b = "1,2,3";
a == b; // true, `a` converts to string

const c = [true, 0.5, "hey"];
const d = c.toString(); // "true,0.5,hey"
c == d; // true
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-equality-operators |

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

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

See also
--------

* Inequality operator
* Strict equality operator (en-US)
* Strict inequality operator (en-US)


super - JavaScript

super
=====

**`super`** 키워드는 객체 리터럴 또는 클래스의 [[Prototype]] 속성에 접근하거나 슈퍼클래스의 생성자를 호출하는 데 사용됩니다.

`super.prop`와 `super[expr]` 표현식은 클래스와 객체 리터럴의 메서드 정의에서 모두 사용할 수 있습니다. `super(...args)` 표현식은 클래스 생성자에서 유효합니다.

시도해보기
-----

구문
--

```js
super([arguments]) // 부모 생성자 호출.
super.propertyOnParent
super[expression]
```

설명
--

`super` 키워드는 "함수 호출"(`super(...args)`) 또는 "속성 조회"(`super.prop`와 `super[expr]`)의 두 가지 방법으로 사용할 수 있습니다.

**참고:** `super`는 키워드이며 특수한 구문 구조입니다. `super`는 프로토타입 객체를 가리키는 변수가 아닙니다. `super` 자체를 읽으려는 시도는 `SyntaxError`입니다.

```js
const child = {
  myParent() {
    console.log(super); // SyntaxError: 'super' keyword unexpected here
  },
};
```

파생 클래스(`extends`를 사용)의 생성자 본문에서 `super` 키워드는 "함수 호출"(`super(...args)`)로 나타날 수 있으며 `this` 키워드가 사용되기 전과 생성자가 반환되기 전에 호출되어야 합니다. 부모 클래스의 생성자를 호출하고 부모 클래스의 퍼블릭 필드를 바인딩한 후 파생 클래스의 생성자는 `this`를 추가로 접근하고 수정할 수 있습니다.

"속성 조회" 형식은 객체 리터럴 또는 클래스의 [[Prototype]] 메서드와 속성에 접근하는 데 사용할 수 있습니다. 클래스 본문 내에서 `super`의 참조는 실행 맥락이 인스턴스 생성인지 클래스 초기화인지에 따라 슈퍼클래스의 생성자 자체 이거나 생성자의 `prototype`이 될 수 있습니다. 자세한 내용은 예제 구획을 참조하세요.

`super`의 참조는 메서드가 호출된 객체가 아니라 `super`가 선언된 클래스 또는 객체 리터럴에 의해 결정됩니다. 따라서 메서드를 바인딩 해제하거나 다시 바인딩해도 메서드의 `super` 참조는 변경되지 않습니다.(`this`의 참조는 변경되지만요.) 메서드가 클로저를 생성하는 클래스 또는 객체 리터럴 범위의 변수로 `super`를 볼 수 있습니다. (그러나 위에서 설명한 것처럼 실제로는 변수가 아니라는 점에 유의하세요.)

`super`를 통해 속성을 설정할 때, 속성은 `this`에 대신 설정됩니다.

예제
--

### 클래스에서 super 사용하기

이 코드 스니펫은 클래스 샘플 (라이브 데모)에서 가져왔습니다. 여기서 `super()`는 `Rectangle`과 `Square` 사이에 공통적인 생성자 부분의 중복을 피하기 위해 호출됩니다.

```js
class Rectangle {
  constructor(height, width) {
    this.name = "Rectangle";
    this.height = height;
    this.width = width;
  }
  sayName() {
    console.log(`Hi, I am a ${this.name}.`);
  }
  get area() {
    return this.height \* this.width;
  }
  set area(value) {
    this._area = value;
  }
}

class Square extends Rectangle {
  constructor(length) {
    this.height; // ReferenceError, super가 먼저 호출되어야 합니다!

    // 여기서 Rectangle의 너비와 높이에 대해 제공된
    // length를 사용하여 부모 클래스의 생성자를 호출합니다.
    super(length, length);

    // 참고: 파생 클래스에서 'this'를 사용하려면
    // 먼저 super()를 호출해야 합니다. 이를 생략하면 참조 오류가 발생합니다.
    this.name = "Square";
  }
}
```

### super를 호출하는 정적 메서드

정적 메서드에서도 super를 호출할 수 있습니다.

```js
class Rectangle {
  static logNbSides() {
    return "I have 4 sides";
  }
}

class Square extends Rectangle {
  static logDescription() {
    return `${super.logNbSides()} which are all equal`;
  }
}
Square.logDescription(); // 'I have 4 sides which are all equal'
```

### 클래스 필드 선언에서 super 접근

`super`는 클래스 필드 초기화 중에도 접근할 수 있습니다. `super`의 참조는 현재 필드가 인스턴스 필드인지 정적 필드인지에 따라 다릅니다.

```js
class Base {
  static baseStaticField = 90;
  baseMethod() {
    return 10;
  }
}

class Extended extends Base {
  extendedField = super.baseMethod(); // 10
  static extendedStaticField = super.baseStaticField; // 90
}
```

인스턴스 필드는 생성자의 `prototype` 대신 인스턴스에 설정되므로 `super`를 사용하여 슈퍼클래스의 인스턴스 필드에 접근할 수 없습니다.

```js
class Base {
  baseField = 10;
}

class Extended extends Base {
  extendedField = super.baseField; // undefined
}
```

여기서 `baseField`는 `Base.prototype`이 아니라 `Base` 인스턴스의 자체 속성으로 정의되기 때문에 10이 아닌 `undefined`입니다. 이 맥락에서 `super`는 `Extended.prototype`의 [[Prototype]]이므로 `Base.prototype`의 속성만 조회할 수 있습니다.

### super 속성을 삭제하면 오류가 발생합니다

`delete` 연산자 (en-US)와 `super.prop` 또는 `super[expr]`를 사용하여 부모 클래스의 속성을 삭제할 수 없습니다. 삭제하면 `ReferenceError`가 발생합니다.

```js
class Base {
  foo() {}
}
class Derived extends Base {
  delete() {
    delete super.foo; // 이렇게 하면 안됩니다.
  }
}

new Derived().delete(); // ReferenceError: invalid delete involving 'super'.
```

### 객체 리터럴에서 super.prop 사용

super는 객체 초기자 표기법에서도 사용할 수 있습니다. 이 예제는 두 객체가 메서드 하나를 정의합니다. 두 번째 객체에서 `super`는 첫 번째 객체의 메서드를 호출합니다. 이는 `obj2`의 프로토타입을 `obj1`로 설정할 수 있는 `Object.setPrototypeOf()` (en-US)의 도움으로 작동하므로 `super`는 `obj1`에서 `method1`을 찾을 수 있습니다.

```js
const obj1 = {
  method1() {
    console.log("method 1");
  },
};

const obj2 = {
  method2() {
    super.method1();
  },
};

Object.setPrototypeOf(obj2, obj1);
obj2.method2(); // "method 1"이 로그됩니다.
```

### super.prop을 읽는 메서드는 다른 객체에 바인딩될 때 다르게 동작하지 않습니다

`super.x`에 접근하는 것은 `Reflect.get(Object.getPrototypeOf(objectLiteral), "x", this)`와 같이 동작합니다. 즉, 속성은 항상 객체 리터럴/클래스 선언의 프로토타입에서 검색되고 메서드를 바인딩 해제하고 다시 바인딩해도 `super`의 참조는 변경되지 않습니다.

```js
class Base {
  baseGetX() {
    return 1;
  }
}
class Extended extends Base {
  getX() {
    return super.baseGetX();
  }
}

const e = new Extended();
console.log(e.getX()); // 1
const { getX } = e;
console.log(getX()); // 1
```

객체 리터럴에서도 동일하게 동작합니다.

```js
const parent1 = { prop: 1 };
const parent2 = { prop: 2 };

const child = {
  myParent() {
    console.log(super.prop);
  },
};

Object.setPrototypeOf(child, parent1);
child.myParent(); // "1"이 로그됩니다.

const myParent = child.myParent;
myParent(); // 여전히 "1"이 로그됩니다.

const anotherChild = { \_\_proto\_\_: parent2, myParent };
anotherChild.myParent(); // 여전히 "1"이 로그됩니다.
```

전체 상속 체인을 재설정해야만 `super`의 참조가 변경됩니다.

```js
class Base {
  baseGetX() {
    return 1;
  }
  static staticBaseGetX() {
    return 3;
  }
}
class AnotherBase {
  baseGetX() {
    return 2;
  }
  static staticBaseGetX() {
    return 4;
  }
}
class Extended extends Base {
  getX() {
    return super.baseGetX();
  }
  static staticGetX() {
    return super.staticBaseGetX();
  }
}

const e = new Extended();
// 인스턴스 상속 재설정
Object.setPrototypeOf(Extended.prototype, AnotherBase.prototype);
console.log(e.getX()); // 프로토타입 체인이 변경되었기 때문에 "1" 대신 "2"가 로그됩니다.
console.log(Extended.staticGetX()); // 정적 부분을 아직 수정하지 않았기 때문에, 여전히 "3"이 로그됩니다.
// 정적 상속 재설정
Object.setPrototypeOf(Extended, AnotherBase);
console.log(Extended.staticGetX()); // 이제 "4"가 로그됩니다.
```

### super에서 메서드 호출

`super.prop`을 함수로 호출할 때 `prop` 함수 내부의 `this` 값은 `super`가 가리키는 객체가 아니라 현재 `this`입니다. 예를 들어, `super.getName()` 호출은 코드가 `Base.getName()`과 동일한 것처럼 보이지만 `"Extended"`를 로그합니다.

```js
class Base {
  static getName() {
    console.log(this.name);
  }
}

class Extended extends Base {
  static getName() {
    super.getName();
  }
}

Extended.getName(); // "Extended" 로그
```

이는 정적 프라이빗 속성과 상호 작용할 때 특히 중요합니다.

### super.prop을 설정하면 this 속성이 대신 설정됩니다

`super.x = 1`과 같은 `super`의 속성을 설정하는 것은 `Reflect.set(Object.getPrototypeOf(objectLiteral), "x", 1, this)`와 같이 동작합니다. 이는 `super`를 단순히 "프로토타입 객체의 참조"로 이해하는 것에 한계가 있는 이유 중 하나입니다. 실제로는 `this`에 대한 속성을 설정하기 때문이죠.

```js
class A {}
class B extends A {
  setX() {
    super.x = 1;
  }
}

const b = new B();
b.setX();
console.log(b); // B { x: 1 }
console.log(Object.hasOwn(b, "x")); // true
```

`super.x = 1`은 `A.prototype`에서 `x`의 속성 설명자를 찾습니다(그리고 거기에 정의된 setter를 호출하죠.). 하지만 `this` 값은 이 맥락에서 `b`로 설정됩니다. `target`과 `receiver`가 다른 경우에 대한 자세한 내용은 `Reflect.set`을 참조하세요.

즉, `super.prop`를 *get*하는 메서드는 일반적으로 이 맥락의 변경에 영향을 받지 않지만 `super.prop`를 *set*하는 메서드는 영향을 받을 수 있습니다.

```js
/\* 위와 동일한 선언 재사용 \*/

const b2 = new B();
b2.setX.call(null); // TypeError: Cannot assign to read only property 'x' of object 'null'
```

그러나 `super.x = 1`은 여전히 프로토타입 객체의 속성 설명자를 참조하므로, 쓸 수 없는 속성을 다시 작성할 수 없으며 setter가 호출됩니다.

```js
class X {
  constructor() {
    // 쓸 수 없는 속성 생성
    Object.defineProperty(this, "prop", {
      configurable: true,
      writable: false,
      value: 1,
    });
  }
}

class Y extends X {
  constructor() {
    super();
  }
  foo() {
    super.prop = 2; // 값을 덮어쓸 수 없습니다.
  }
}

const y = new Y();
y.foo(); // TypeError: "prop" is read-only
console.log(y.prop); // 1
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-super-keyword |

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

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

같이 보기
-----

* 클래스


AND 비트연산(&) - JavaScript

AND 비트연산(&)
===========

AND 비트 연산자(`&`)는 두 개의 피연산자의 각 자리마다 대응하는 비트가 모두 `1`일 경우 `1`을 반환합니다.

시도해보기
-----

구문
--

```js
a & b;
```

설명
--

피연산자는 32비트 정수로 변환되며 일련의 비트(0과 1)로 표현됩니다. 32비트 이상인 숫자는 최상위 비트가 삭제됩니다. 예를 들어 32비트 이상인 다음 정수는 32비트 정수로 변환됩니다.

```js
Before: 11100110111110100000000000000110000000000001;
After: 10100000000000000110000000000001;
```

첫 번째 피연산자의 각 비트는 두 번째 피연산자의 해당 비트(*첫 번째 비트* 와 *첫 번째 비트*, *두 번째 비트* 와 *두 번째 비트* 등등)와 쌍을 이룹니다.

연산자가 각 비트의 쌍에 적용되며, 결과는 완성된 비트 연산된 값입니다.

AND 연산에 대한 진리표는 다음과 같습니다:

| a | b | a AND b |
| --- | --- | --- |
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |

```js
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
    14 (base 10) = 00000000000000000000000000001110 (base 2)
                   --------------------------------
14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
```

어떤 수 `x`에 `0`을 AND 비트 연산한 결과는 `0`가 됩니다.

예제
--

### AND 비트 연산 사용하기

```js
// 5: 00000000000000000000000000000101
// 2: 00000000000000000000000000000010
5 & 2; // 0
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # prod-BitwiseANDExpression |

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

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

같이 보기
-----

* JS의 비트 연산 가이드
* 비트 AND 할당연산자


연산자 우선순위 - JavaScript

연산자 우선순위
========

**연산자 우선순위**는 연산자를 실행하는 순서를 결정합니다. 우선순위가 높은 연산자가 먼저 실행됩니다.

시도해보기
-----

우선순위와 결합성
---------

아래와 같이 표현할 수 있는 표현식을 생각해 봅시다. 연산자1과 연산자2의 자리에는 아무 연산자를 넣을 수 있습니다.
```

a 연산자1 b 연산자2 c
```

두 연산자의 우선순위(아래 표 참조)가 다를 경우, 우선순위가 높은 연산자가 먼저 실행되고 결합성은 영향을 미치지 않습니다. 아래 예제에서는 덧셈이 곱셈보다 먼저 쓰였음에도 곱셈의 우선순위가 높기 때문에 먼저 실행됩니다.

```js
console.log(3 + 10 \* 2); // 23을 출력
console.log(3 + 10 \* 2); // 23을 출력, 괄호는 불필요함
console.log((3 + 10) \* 2); // 26을 출력, 괄호로 인해 실행 순서가 바뀜
```

좌결합성(왼쪽에서 오른쪽으로)은 표현식이 `(a 연산자1 b) 연산자2 c`와 같이, 우결합성(오른쪽에서 왼쪽으로)은 `a 연산자1 (b 연산자2 c)`와 같이 계산된다는 의미입니다. 대입 연산자는 우결합성이므로 다음과 같은 코드를 작성할 수 있습니다.

```js
a = b = 5; // a = (b = 5);와 같음
```

이때 대입 연산자는 대입된 값을 반환하므로 `a`와 `b`의 값이 5가 됨을 예상할 수 있습니다. 우선 `b`의 값이 5로 설정되고, 그 다음에는 `a`의 값이 우변인 `b = 5`의 반환값 5로 설정됩니다.

다른 예시로, 좌결합성인 다른 산술 연산자와 달리 거듭제곱 연산자 (`**`)만은 우결합성입니다. 흥미로운 점으로 표현식의 평가는 결합성과 무관하게 항상 왼쪽에서 오른쪽으로 진행됩니다.

|  |  |
| --- | --- |
| 코드 | 출력 |
|
```js
function echo(name, num) {
    console.log(name + " 항 평가함");
    return num;
}
// 나눗셈 연산자 (/)에 주목
console.log(echo("첫째", 6) / echo("둘째", 2));
```

 |
```
첫째 항 평가함
둘째 항 평가함
3
```

 |
|
```js
function echo(name, num) {
    console.log(name + " 항 평가함");
    return num;
}
// 거듭제곱 연산자 (\*\*)에 주목
console.log(echo("첫째", 2) \*\* echo("둘째", 3));
```
 |
```
첫째 항 평가함
둘째 항 평가함
8
```
 |

여러 연산자의 우선순위가 같을 때는 결합성을 고려합니다. 위에서와 같이 연산자가 하나이거나 연산자끼리 우선순위가 다를 경우에는 결합성이 결과에 영향을 미치지 않습니다. 아래의 예제에서 같은 종류의 연산자를 여러 번 사용했을 때 결합성이 결과에 영향을 미치는 것을 확인할 수 있습니다.

|  |  |
| --- | --- |
| 코드 | 출력 |
|
```js
function echo(name, num) {
    console.log(name + " 항 평가함");
    return num;
}
// 나눗셈 연산자 (/)에 주목
console.log(echo("첫째", 6) / echo("둘째", 2) / echo("셋째", 3));
```

 |
```
첫째 항 평가함
둘째 항 평가함
셋째 항 평가함
1
```

 |
|
```js
function echo(name, num) {
    console.log(name + " 항 평가함");
    return num;
}
// 거듭제곱 연산자 (\*\*)에 주목
console.log(echo("첫째", 2) \*\* echo("둘째", 3) \*\* echo("셋째", 2));
```

 |
```
첫째 항 평가함
둘째 항 평가함
셋째 항 평가함
512
```

 |
|
```js
function echo(name, num) {
    console.log(name + " 항 평가함");
    return num;
}
// 첫 번째 거듭제곱 연산자 주변의 괄호에 주목
console.log((echo("첫째", 2) \*\* echo("둘째", 3)) \*\* echo("셋째", 2));
```
 |
```
첫째 항 평가함
둘째 항 평가함
셋째 항 평가함
64
```
 |

위의 예제에서 나눗셈은 좌결합성이므로 `6 / 3 / 2`는 `(6 / 3) / 2`와 같습니다. 한편 거듭제곱은 우결합성이므로 `2 ** 3 ** 2`는 `2 ** (3 ** 2)`와 같습니다. 그러므로 `(2 ** 3) ** 2`는 괄호로 인해 실행 순서가 바뀌기 때문에 위 표와 같이 64로 평가됩니다.

우선순위는 결합성보다 항상 우선하므로, 거듭제곱과 나눗셈을 같이 사용하면 나눗셈보다 거듭제곱이 먼저 계산됩니다. 예를 들어 `2 ** 3 / 3 ** 2`는 `(2 ** 3) / (3 ** 2)`와 같으므로 0.8888888888888888로 계산됩니다.

예제
--

```js
3 > 2 && 2 > 1;
// true를 반환

3 > 2 > 1;
// 3 > 2는 true인데, 부등호 연산자에서 true는 1로 변환되므로
// true > 1은 1 > 1이 되고, 이는 거짓이다.
// 괄호를 추가하면 (3 > 2) > 1과 같다.
```

그룹화와 단락에 대한 참고사항
----------------

아래 표에서 그룹화는 우선 순위가 가장 높은 것으로 나열됩니다. 그러나 이것이 항상 그룹화 기호`( … )` 내의 표현식이, 특히 단락과 관련하여 먼저 평가된다는 것을 의미하지는 않습니다.

단락은 조건부 평가의 전문 용어입니다. 예를 들어 표현식 `a &&(b + c)`에서 `a`가 falsy이면 하위 표현식`(b + c)`은 괄호 안에 있어도 평가되지 않습니다. 논리 분리 연산자("OR")가 "단락"되었다고 말할 수 있습니다. 논리적 분리와 함께 다른 단락 연산자에는 논리적 연결("AND"), nullish-coalescing, 선택적 연결 및 조건부 연산자가 포함됩니다. 몇 가지 예가 더 있습니다.

```js
a || b \* c; // `a`를 먼저 평가하고, `a`가 "truthy"라면 `a`를 생성합니다.
a && b < c; // `a`를 먼저 평가하고, `a`가 "falsy"라면 `a`를 생성합니다.
a ?? (b || c); // `a`를 먼저 평가하고, `a`가 `null`과 `undefined`가 아니라면 `a`를 생성합니다.
a?.b.c; // `a`를 먼저 평가하고, `a`가 `null`또는 `undefined`라면 `undefined`를 생성합니다.
```

표
-

다음 표는 우선순위 내림차순(19부터 1까지)으로 정렬되어 있습니다.

| 우선순위 | 연산자 유형 | 결합성 | 연산자 |
| --- | --- | --- | --- |
| 19 | 그룹 | 없음 | `( … )` |
| 18 | 멤버 접근 | 좌결합성 | `… . …` |
| 계산된 멤버 접근 | 좌결합성 | `… [ … ]` |
| `new` (인자 리스트 제공) | 없음 | `new … ( … )` |
| 함수 호출 | 좌결합성 | `… ( … )` |
| 옵셔널 체이닝 | 좌결합성 | `?.` |
| 17 | `new` (인자 리스트 생략) | 우결합성 | `new …` |
| 16 | 후위 증가 | 없음 | `… ++` |
| 후위 감소 | `… --` |
| 15 | 논리 NOT | 우결합성 | `! …` |
| 비트 NOT | `~ …` |
| 단항 양부호 | `+ …` |
| 단항 부정 | `- …` |
| 전위 증가 | `++ …` |
| 전위 감소 | `-- …` |
| `typeof` | `typeof …` |
| `void` | `void …` |
| `delete` (en-US) | `delete …` |
| `await` | `await …` |
| 14 | 거듭제곱 | 우결합성 | `… ** …` |
| 13 | 곱하기 | 좌결합성 | `… * …` |
| 나누기 | `… / …` |
| 나머지 | `… % …` |
| 12 | 더하기 | 좌결합성 | `… + …` |
| 빼기 | `… - …` |
| 11 | 비트 왼쪽 시프트 | 좌결합성 | `… << …` |
| 비트 오른쪽 시프트 (en-US) | `… >> …` |
| 비트 부호 없는 오른쪽 시프트 (en-US) | `… >>> …` |
| 10 | 미만 (en-US) | 좌결합성 | `… < …` |
| 이하 (en-US) | `… <= …` |
| 초과 (en-US) | `… > …` |
| 이상 (en-US) | `… >= …` |
| `in` | `… in …` |
| `instanceof` | `… instanceof …` |
| 9 | 동등 | 좌결합성 | `… == …` |
| 부등 | `… != …` |
| 일치 (en-US) | `… === …` |
| 불일치 (en-US) | `… !== …` |
| 7 | 비트 AND | 좌결합성 | `… & …` |
| 7 | 비트 XOR (en-US) | 좌결합성 | `… ^ …` |
| 6 | 비트 OR (en-US) | 좌결합성 | `… | …` |
| 5 | 논리 AND | 좌결합성 | `… && …` |
| 4 | 논리 OR | 좌결합성 | `… || …` |
| 널 병합 연산자 | 좌결합성 | `… ?? …` |
| 3 | 조건 (삼항) | 우결합성 | `… ? … : …` |
| 2 | 할당 (en-US) | 우결합성 | `… = …` |
| `… += …` |
| `… -= …` |
| `… **= …` |
| `… *= …` |
| `… /= …` |
| `… %= …` |
| `… <<= …` |
| `… >>= …` |
| `… >>>= …` |
| `… &= …` |
| `… ^= …` |
| `… |= …` |
| `… &&= …` |
| `… ||= …` |
| `… ??= …` |
| `yield` | 우결합성 | `yield …` |
| `yield*` | `yield* …` |
| 1 | 쉼표 / 시퀀스 | 좌결합성 | `… , …` |


더하기 (+) - JavaScript

더하기 (+)
=======

더하기 연산자(`+`)는 숫자 피연산자의 합을 구하거나, 문자열을 서로 연결합니다.

시도해보기
-----

구문
--

```js
x + y
```

설명
--

`+` 연산자는 숫자 덧셈과 문자열 연결 두 가지 작업을 수행합니다. 계산 시에 먼저 두 개의 피연산자를 원시 타입으로 변환합니다. 그 후에, 두 피연산자의 타입을 확인합니다.

* 만약 한쪽의 피연산자가 문자열인 경우, 나머지 한쪽의 피연산자도 문자열로 변환시킨 뒤 연결합니다.
* 만약 두 피연산자가 모두 BigInt인 경우, BigInt 덧셈을 수행합니다. 만약 한쪽의 피연산자가 BigInt이지만 나머지 한쪽의 피연산자가 BigInt가 아닌 경우, `TypeError`가 발생합니다.
* 그 외의 경우, 두 피연산자를 모두 숫자로 변환시키고, 숫자 덧셈이 수행됩니다.

종종 템플릿 리터럴이나 `String.prototype.concat()`이 문자열 연결과 동일하다고 생각하지만, 그렇지 않습니다. 더하기 연산자는 먼저 `valueOf()`를 호출하여 표현식을 원시 타입으로 변환합니다. 반면에, 템플릿 리터럴과 `concat()`은 먼저 `toString()`을 호출합니다. 만약 표현식에 `@@toPrimitive` 메서드가 있는 경우, 문자열 연결은 `"default"`를 힌트로 사용하고, 템플릿 리터럴은 `"string"`을 사용합니다. 이 차이는 문자열과 원시 표현이 다른 객체에 중요합니다. 예를 들어 `valueOf()` 메서드가 에러를 내는 Temporal 같은 객체가 있습니다.

```js
const t = Temporal.Now.instant();
"" + t; // Throws TypeError
`${t}`; // '2022-07-31T04:48:56.113918308Z'
"".concat(t); // '2022-07-31T04:48:56.113918308Z'
```

문자열 변환을 위해 `"" + x`를 사용하는 것은 좋지 않습니다.

예제
--

### Number 덧셈

```js
// Number + Number -> 덧셈
1 + 2; // 3

// Boolean + Number -> 덧셈
true + 1; // 2

// Boolean + Boolean -> 덧셈
false + false; // 0
```

BigInt 덧셈
---------

```js
// BigInt + BigInt -> 덧셈
1n + 2n; // 3n

// BigInt + Number -> TypeError 발생
1n + 2; // TypeError: Cannot mix BigInt and other types, use explicit conversions

// BigInt와 non-BigInt를 더하기 위해선, 피연산자 중 하나를 변환하십시오.
1n + BigInt(2); // 3n
Number(1n) + 2; // 3
```

### 문자열 연결

```js
// String + String -> 연결
"foo" + "bar"; // "foobar"

// Number + String -> 연결
5 + "foo"; // "5foo"

// String + Boolean -> 연결
"foo" + false; // "foofalse"
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-addition-operator-plus |

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

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

같이 보기
-----

* 빼기 연산자
* 나누기 연산자
* 곱하기 연산자
* 나머지 연산자
* 거듭제곱 연산자
* 증가 연산자
* 감소 연산자
* 단항 부정 연산자
* 단항 플러스 연산자


빼기 (-) - JavaScript

빼기 (-)
======

빼기 연산자(`-`)는 두 연산자의 차이를 구합니다.

시도해보기
-----

구문
--

```js
x - y;
```

예제
--

### 뺄셈

```js
5 - 3; // 2
3 - 5; // -2
```

### 숫자가 아닌 경우

```js
"foo" - 3; // NaN
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-subtraction-operator-minus |

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

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

같이 보기
-----

* 더하기 연산자
* 나누기 연산자
* 곱하기 연산자
* 나머지 연산자
* 거듭제곱 연산자
* 증가 연산자
* 감소 연산자
* 단항 부정 연산자
* 단항 플러스 연산자


Unsigned 오른쪽 시프트 할당 연산자 (>>>=) - JavaScript

Unsigned 오른쪽 시프트 할당 연산자 (>>>=)
==============================

**unsigned 오른쪽 시프트 할당(`>>>=`)** 연산자는 지정된 수 만큼 unsigned 오른쪽 시프트 연산 (en-US)을 수행하고 그 결과를 왼쪽 피연산자에 할당합니다.

시도해보기
-----

구문
--

```js
x >>>= y
```

설명
--

`x >>>= y` 는 `x = x >>> y`와 같은 의미를 가집니다.

예제
--

### unsigned 오른쪽 시프트 할당 연산자 사용

```js
let a = 5; // (00000000000000000000000000000101)
a >>>= 2; // 1 (00000000000000000000000000000001)

let b = -5; // (-00000000000000000000000000000101)
b >>>= 2; // 1073741822 (00111111111111111111111111111110)

let c = 5n;
c >>>= 2n; // 1n
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

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

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

같이 보기
-----

* Assignment operators in the JS guide
* Unsigned 오른쪽 시프트 연산자 (en-US)


객체 초기자 - JavaScript

객체 초기자
======

객체는 `new Object()`, `Object.create()` 또는 *literal* 표기법(*initializer* 표기법)을 사용해 초기화될 수 있습니다. 객체 초기자는 중괄호(`{}`)로 묶인 0개 이상의 객체의 프로퍼티명과 관련 값의 쌍을 콤마로 구분한 목록입니다.

시도해보기
-----

구문
--

```js
let o = {};
let o = { a: "foo", b: 42, c: {} };

let a = "foo",
  b = 42,
  c = {};
let o = { a: a, b: b, c: c };

let o = {
  property: function (parameters) {},
  get property() {},
  set property(value) {},
};
```

### ECMAScript 2015의 새로운 표기법

이러한 표기법의 지원에 대해서는 호환성 테이블을 확인해주세요. 지원하지 않는 환경에서는 이러한 표기법들은 구문 에러를 유발합니다.

```js
// 프로퍼티명 약식 (ES2015)
let a = "foo",
  b = 42,
  c = {};
let o = { a, b, c };

// 메서드명 약식 (ES2015)
let o = {
  property(parameters) {},
};

// 계산된 프로퍼티명 (ES2015)
let prop = "foo";
let o = {
  [prop]: "hey",
  ["b" + "ar"]: "there",
};
```

설명
--

객체 초기자는 `Object`의 초기화를 나타내는 표현입니다. 객체는 객체를 나타내는 데 사용되는 *properties* 로 구성됩니다. 객체 프로퍼티의 값은 원시 값 데이터 타입 또는 다른 객체를 포함할 수 있습니다.

### 객체 리터럴 표기법 vs JSON

객체 리터럴 표기법은 **J**ava**S**cript **O**bject **N**otation(JSON)과 동일하지 않습니다. 비슷하게 보이지만 다음과 같은 차이가 있습니다.

* JSON은 *오직* `"property": value` 구문을 사용해 정의한 프로퍼티만 허용합니다. 프로퍼티명에는 반드시 큰따옴표를 사용해야 하며 약식으로 정의할 수 없습니다.
* JSON에서 값은 문자열, 숫자, 배열, `true`, `false`, `null`, 또는 다른 (JSON) 객체만 사용할 수 있습니다.
* 함수 값(아래 "메서드"를 보세요)은 JSON의 값으로 할당할 수 없습니다.
* `Date`와 같은 객체는 `JSON.parse()` 이후의 문자열이 됩니다.
* `JSON.parse()`는 계산된 프로퍼티명을 거부하며 에러가 발생합니다.
예제
--

### 객체 생성하기

프로퍼티가 없는 빈 객체는 다음과 같이 생성합니다.

```js
let object = {};
```

*literal* 또는 *initializer* 표기법의 장점은 중괄호 안에 프로퍼티를 갖는 객체를 빠르게 생성할 수 있다는 것입니다. 콤마로 구분하여 `key: value` 상의 목록을 작성하면 됩니다.

다음 코드는 세 개의 프로퍼티를 갖는 객체를 생성하며 키는 `"foo"`, `"age"`, `"baz"`입니다. 다음 세 키의 값은 문자열 `"bar"`, 숫자 `42`, 그리고 다른 객체입니다.

```js
let object = {
  foo: "bar",
  age: 42,
  baz: { myProp: 12 },
};
```

### 프로퍼티에 접근하기

객체를 생성한 후에는 이를 읽거나 변경할 수 있습니다. 객체 프로퍼티는 점 표기법 또는 대괄호 표기법을 사용해 접근할 수 있습니다(자세한 정보는 프로퍼티 접근자를 보세요).

```js
object.foo; // "bar"
object["age"]; // 42
object.baz; // {myProp: 12}
object.baz.myProp; //12
```

### 프로퍼티 정의

우리는 초기자 구문을 사용해 프로퍼티를 작성하는 방법을 이미 배웠습니다. 때때로 코드의 변수를 객체로 넣고 싶은 경우가 있습니다. 다음과 같은 코드를 보게 될 수 있습니다.

```js
let a = "foo",
  b = 42,
  c = {};

let o = {
  a: a,
  b: b,
  c: c,
};
```

ECMAScript 2015를 사용하면 더 짧은 표기법을 사용해 동일한 결과를 얻을 수 있습니다.

```js
let a = "foo",
  b = 42,
  c = {};

// 프로퍼티명 약식 (ES2015)
let o = { a, b, c };

// 다르게 작성하면,
console.log(o.a === { a }.a); // true
```

#### 중복된 프로퍼티명

동일한 프로퍼티명을 사용하면 두 번째 프로퍼티가 첫 번째 프로퍼티를 덮어씁니다.

```js
let a = { x: 1, x: 2 };
console.log(a); // {x: 2}
```

ECMAScript 5 엄격 모드 코드에서는 중복된 프로퍼티명을 `SyntaxError`로 간주합니다. 런타임 시 복제를 가능하게 한 계산된 프로퍼티 명의 도입으로 ECMScript 2015는 이 제한을 제거했습니다.

```js
function haveES2015DuplicatePropertySemantics() {
  "use strict";
  try {
    ({ prop: 1, prop: 2 });

    // 에러가 발생하지 않음, 중복된 프로퍼티명이 엄격 모드에서 허용됨
    return true;
  } catch (e) {
    // 에러가 발생함, 엄격 모드에서 중복이 금지됨
    return false;
  }
}
```

### 메서드 정의

객체의 프로퍼티는 function 또는 getter 또는 setter 메서드를 참조할 수도 있습니다.

```js
let o = {
  property: function (parameters) {},
  get property() {},
  set property(value) {},
};
```

ECMAScript 2015에서는 약식 표기법을 사용할 수 있으므로 "`function`" 키워드는 필요하지 않습니다.

```js
// 약식 메서드명(ES2015)
let o = {
  property(parameters) {},
};
```

ECMAScript 2015에서는 값이 generator 함수인 프로퍼티를 간결하게 정의하는 방법이 있습니다.

```js
let o = {
  \*generator() {
    ...........
  }
};
```

다음의 ES5와 유사한 표기법과 동일합니다(하지만 ECMAScript 5에는 generator가 없음을 유의하세요).

```js
let o = {
  generator: function\* () {
    ...........
  }
};
```

메서드에 대한 상세 정보와 예제는 메서드 정의를 보세요.

### 계산된 프로퍼티명

ECMAScript 2015부터 객체 초기자 구문은 계산된 프로퍼티 명도 지원합니다. 대괄호 `[]` 안에서 표현식을 허용하며, 표현식은 프로퍼티명으로 계산되어 사용됩니다. 이는 이미 프로퍼티를 읽고 설정하는 데 사용하는 프로퍼티 접근자 구문의 대괄호 표기법을 연상시킵니다.

이제 객체 리터럴에서도 유사한 구문을 사용할 수 있습니다.

```js
// 계산된 프로퍼티명(ES2015)
let i = 0;
let a = {
  ["foo" + ++i]: i,
  ["foo" + ++i]: i,
  ["foo" + ++i]: i,
};

console.log(a.foo1); // 1
console.log(a.foo2); // 2
console.log(a.foo3); // 3

const items = ["A", "B", "C"];
const obj = {
  [items]: "Hello",
};
console.log(obj); // A,B,C: "Hello"
console.log(obj["A,B,C"]); // "Hello"

let param = "size";
let config = {
  [param]: 12,
  ["mobile" + param.charAt(0).toUpperCase() + param.slice(1)]: 4,
};

console.log(config); // {size: 12, mobileSize: 4}
```

### 전개 프로퍼티

ECMAScript의 나머지/전개 프로퍼티 제안(stage 4)은 객체 리터럴에 전개 프로퍼티를 추가합니다. 이는 제공된 객체로부터 새로운 객체로 자신만의 열거형 프로퍼티를 복사합니다.

이제 `Object.assign()` 보다 더 짧은 구문을 사용해 얕은 복제(`prototype` 제외) 또는 객체 병합이 가능합니다.

```js
let obj1 = { foo: "bar", x: 42 };
let obj2 = { foo: "baz", y: 13 };

let clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }

let mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }
```

**경고:** `Object.assign()`은 setters를 트리거하는 반면 전개 연산자는 그렇지 않음을 유의하세요!

### 프로토타입 변형

`__proto__: value` 또는 `"__proto__": value` 형태의 프로토타입 정의는 `__proto__` 이름을 갖는 프로퍼티를 생성하지 않습니다. 대신에, 제공된 값이 객체 또는 `null`인 경우, 생성된 객체의 `[[Prototype]]`을 해당 값으로 변경합니다(값이 객체 또는 `null`이 아닌 경우, 객체는 변경되지 않습니다).

```js
let obj1 = {};
assert(Object.getPrototypeOf(obj1) === Object.prototype);

let obj2 = { \_\_proto\_\_: null };
assert(Object.getPrototypeOf(obj2) === null);

let protoObj = {};
let obj3 = { \_\_proto\_\_: protoObj };
assert(Object.getPrototypeOf(obj3) === protoObj);

let obj4 = { \_\_proto\_\_: "not an object or null" };
assert(Object.getPrototypeOf(obj4) === Object.prototype);
assert(!obj4.hasOwnProperty("\_\_proto\_\_"));
```

객체 리터럴에서는 단일 프로토타입 변형만 허용됩니다. 다중 프로토타입 변형은 구문 에러입니다.

"콜론" 표기법을 사용하지 않는 프로퍼티 정의는 프로토타입 변형이 아닙니다. 이는 다른 이름을 사용하여 유사한 정의와 동일하게 동작하는 프로퍼티 정의입니다.

```js
let __proto__ = "variable";

let obj1 = { __proto__ };
assert(Object.getPrototypeOf(obj1) === Object.prototype);
assert(obj1.hasOwnProperty("\_\_proto\_\_"));
assert(obj1.__proto__ === "variable");

let obj2 = {
  \_\_proto\_\_() {
    return "hello";
  },
};
assert(obj2.\_\_proto\_\_() === "hello");

let obj3 = { ["\_\_prot" + "o\_\_"]: 17 };
assert(obj3.__proto__ === 17);
```

명세
--

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

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

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

같이 보기
-----

* 프로퍼티 접근자
* `get` / `set`
* 메서드 정의
* Lexical grammar (en-US)


나머지 할당 (%=) - JavaScript

나머지 할당 (%=)
===========

나머지 할당 연산자(`%=`)는 오른쪽 피연산자의 값으로 변수를 나눴을 때의 나머지를 다시 변수에 할당합니다.

시도해보기
-----

구문
--

```js
x %= y; // x = x % y
```

예제
--

### 나머지 할당 사용하기

```js
// bar = 5
// 위와 같은 변수를 가정할 때

bar %= 2; // 1
bar %= "foo"; // NaN
bar %= 0; // NaN
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

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

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

같이 보기
-----

* JavaScript 안내서의 할당 연산자
* 나머지 연산자


곱하기 할당 (*=) - JavaScript

곱하기 할당 (\*=)
============

곱하기 할당 연산자(`*=`)는 오른쪽 피연산자의 값을 변수에 곱한 결과를 다시 변수에 할당합니다.

시도해보기
-----

구문
--

```js
x \*= y; // x = x \* y
```

예제
--

### 곱하기 할당 사용하기

```js
// bar = 5
// 위와 같은 변수를 가정할 때

bar \*= 2; // 10
bar \*= "foo"; // NaN
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

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

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

같이 보기
-----

* JavaScript 안내서의 할당 연산자
* 곱하기 연산자


함수 표현식 - JavaScript

함수 표현식
======

**`function`** 키워드는 어떤 표현식(expression) 내에서 함수를 정의하는 데 사용될 수 있습니다.

또한 Function 생성자와 함수 선언(function declaration)을 이용해 함수를 정의할 수도 있습니다.

시도해보기
-----

구문
--

```js
    var myFunction = function [name]([param1[, param2[, ..., paramN]]]) { statements };
```

ES2015에서 화살표 함수(arrow functions)를 사용할 수도 있습니다.

### 매개변수

`name`

함수 이름. 함수가 이름 없는(anonymous) 함수인 경우, 생략될 수 있음. 이 함수 이름은 함수의 몸통 내에서만 사용할 수 있습니다.

`paramN`

함수로 전달되는 인수(argument) 의 이름.

`statements`

함수 몸통을 구성하는 문(statement).

설명
--

함수 표현식(function expression)은 function 문과 매우 비슷하고 구문(syntax)이 거의 같습니다 (자세한 사항은 function 문 참조). 함수 표현식과 function 문 사이의 주요 차이점은 함수 이름으로, 함수 표현식으로 *익명* 함수를 만들 경우 이 이름을 생략할 수 있습니다. 함수 표현식은 정의하자마자 실행되는 IIFE (즉시 호출되는 함수 표현식)로 사용될 수 있습니다. 더 자세한 정보는 함수 장 참조.

### Function expression 끌어올리기

JavaScript에서 함수 표현식은 `함수 선언`과는 달리 끌어올려지지 않습니다. 함수 표현식을 정의하기 전에는 사용할 수 없습니다.

```js
console.log(notHoisted); // undefined
//even the variable name is hoisted, the definition wasn't. so it's undefined.
notHoisted(); // TypeError: notHoisted is not a function

var notHoisted = function () {
  console.log("bar");
};
```

### 유명(named) 함수 표현식

함수 몸통 안 쪽에서 현재 함수를 참고하고 싶다면, 유명 함수를 생성해야 합니다. ***이 함수 이름은 함수의 몸통(범위) 안에서만 사용할 수 있습니다***. 이로써 비표준 `arguments.callee` 속성을 사용하는 것을 피할 수도 있습니다.

```js
var math = {
  factit: function factorial(n) {
    console.log(n);
    if (n <= 1) return 1;
    return n \* factorial(n - 1);
  },
};

math.factit(3); //3;2;1;
```

함수가 할당된 변수는 `name` 속성을 가지게됩니다. 다른 변수에 할당되더라도 그 name 속성의 값은 변하지 않습니다. 함수의 이름이 생략되었다면, name 속성의 값은 그 변수의 이름(암묵적 이름)이 될 것입니다. 함수의 이름이 있다면 name 속성의 값은 그 함수의 이름(명시적 이름)이 될 것입니다. 이는 화살표 함수(arrow functions)에도 적용됩니다 (화살표 함수는 이름을 가지지 않으므로 해당 변수에 암묵적인 이름만 줄 수 있습니다).

```js
var foo = function () {};
foo.name; // "foo"

var foo2 = foo;
foo2.name; // "foo"

var bar = function baz() {};
bar.name; // "baz"

console.log(foo === foo2); // true
console.log(typeof baz); // undefined
console.log(bar === baz); // false (errors because baz == undefined)
```

Examples
--------

다음 예제는 이름 없는 함수를 정의하고 그 함수를 `x`에 할당합니다. 함수는 인수의 제곱을 반환합니다:

```js
var x = function (y) {
  return y \* y;
};
```

callback으로 더 자주 사용됩니다:

```js
button.addEventListener("click", function (event) {
  console.log("button is clicked!");
});
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-function-definitions |

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

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

참조
--

* `Arrow functions` (en-US)
* `Functions and function scope` (en-US)
* `Function`
* `function statement`
* `function* statement`
* `function* expression`
* `GeneratorFunction`
* `async function`
* `async function expression`


곱하기 (*) - JavaScript

곱하기 (\*)
========

곱하기 연산자(`*`)는 두 연산자의 곱을 구합니다.

시도해보기
-----

구문
--

```js
x \* y;
```

예제
--

### 곱셈

```js
2 \* 2; // 4
-2 \* 2; // -4
```

### Infinity 곱하기

```js
Infinity \* 0; // NaN
Infinity \* Infinity; // Infinity
```

### 숫자가 아닌 경우

```js
"foo" \* 2; // NaN
```

명세
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-multiplicative-operators |

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

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

같이 보기
-----

* 더하기 연산자
* 빼기 연산자
* 나누기 연산자
* 나머지 연산자
* 거듭제곱 연산자
* 증가 연산자
* 감소 연산자
* 단항 부정 연산자
* 단항 플러스 연산자


Nullish coalescing operator - JavaScript

Nullish coalescing operator
===========================

**널 병합 연산자 (`??`)** 는 왼쪽 피연산자가 null 또는 undefined일 때 오른쪽 피연산자를 반환하고, 그렇지 않으면 왼쪽 피연산자를 반환하는 논리 연산자이다.

이는 왼쪽 피연산자가 `null` 또는 `undefined` 뿐만 아니라 *falsy (en-US)* 값에 해당할 경우 오른쪽 피연산자를 반환하는 논리 연산자 OR (`||`) (en-US)와는 대조된다. 다시 말해 만약 어떤 변수 foo에게 *falsy (en-US)* 값( `''` 또는 `0`)을 포함한 값을 제공하기 위해 `||`을 사용하는 것을 고려했다면 예기치 않는 동작이 발생할 수 있다. 하단에 더 많은 예제가 있다.

널 병합 연산자는 연산자 우선 순위가 다섯번째로 낮은데, `||` 의 바로 아래이며 조건부 (삼항) 연산자의 바로 위이다.

시도해보기
-----

문법
--

```js
leftExpr ?? rightExpr;
```

설명
--

널 병합 연산자는 만약 왼쪽 표현식이 `null` 또는 `undefined`인 경우, 오른쪽 표현식의 결과를 반환한다.

### 변수에 기본값 할당

이전에는 변수에 기본값을 할당하고 싶을 때, 논리 연산자 OR (`||` (en-US))을 사용하는 것이 일반적인 패턴이다:

```js
let foo;
...
// foo is never assigned any value so it is still undefined
let someDummyText = foo || 'Hello!';
```

그러나 `||` boolean 논리 연산자 때문에, 왼쪽 피연산자는 boolean으로 강제로 변환되었고 *falsy* 한 값(`0`, `''`, `NaN`, `null`, `undefined`)은 반환되지 않았다. 이 동작은 만약 `0`, `''` or `NaN`을 유효한 값으로 생각한 경우 예기치 않는 결과를 초래할 수 있다.

```js
let count;
let text;
...
count = 0;
text = "";
...
let qty = count || 42;
let message = text || "hi!";
console.log(qty);     // 42 and not 0
console.log(message); // "hi!" and not ""
```

널 병합 연산자는 첫 번째 연산자가 `null` 또는 `undefined`로 평가될 때만, 두 번째 피연산자를 반환함으로써 이러한 위험을 피한다:

```js
let myText = ""; // An empty string (which is also a falsy value)

let notFalsyText = myText || "Hello world";
console.log(notFalsyText); // Hello world

let preservingFalsy = myText ?? "Hi neighborhood";
console.log(preservingFalsy); // '' (as myText is neither undefined nor null)
```

### 단락

OR과 AND 같은 논리 연산자들과 마찬가지로, 만약 왼쪽이 `null` 또는 `undefined`가 아님이 판명되면 오른쪽 표현식은 평가되지 않는다.

```js
function A() {
  console.log("A was called");
  return undefined;
}
function B() {
  console.log("B was called");
  return false;
}
function C() {
  console.log("C was called");
  return "foo";
}

console.log(A() ?? C());
// logs "A was called" then "C was called" and then "foo"
// as A() returned undefined so both expressions are evaluated

console.log(B() ?? C());
// logs "B was called" then "false"
// as B() returned false (and not null or undefined), the right
// hand side expression was not evaluated
```

### No chaining with AND or OR operators

AND (`&&`) 와 OR 연산자 (`||`)를 `??`와 직접적으로 결합하여 사용하는 것은 불가능하다. 이 경우 `SyntaxError`가 발생된다.

```js
null || undefined ?? "foo"; // raises a SyntaxError
true || undefined ?? "foo"; // raises a SyntaxError
```

그러나 우선 순위를 명시적으로 나타내기 위해 괄호를 사용하면 가능하다:

```js
(null || undefined) ?? "foo"; // returns "foo"
```

### Optional chaining 연산자(`?.`)와의 관계

널 병합 연산자는 명확한 값으로 `undefined`과 `null`을 처리하고, optional chaining 연산자 (`?.`)는 `null` or `undefined`일 수 있는 객체의 속성에 접근할 때 유용하다.

```js
let foo = { someFooProp: "hi" };

console.log(foo.someFooProp?.toUpperCase()); // "HI"
console.log(foo.someBarProp?.toUpperCase()); // undefined
```

예제
--

이 예제는 기본 값을 제공하지만 `null` or `undefined` 이외의 값을 를 유지한다.

```js
function getMiscObj() {
  return {
    aNullProperty: null,
    emptyText: "", // this is not falsy
    someNumber: 42,
  };
}

const miscObj = getMiscObj();

const newObj = {};
newObj.propA = miscObj.aNullProperty ?? "default for A";
newObj.propB = miscObj.emptyText ?? "default for B";
newObj.propC = miscObj.someNumber ?? 0;

console.log(newObj.propA); // "default for A"
console.log(newObj.propB); // "" (as the empty string is not null or undefined)
console.log(newObj.propC); // 42
```

명세서
---

| Specification |
| --- |
| ECMAScript Language Specification # prod-CoalesceExpression |

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

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

참고
--

* The optional chaining operator
* The logical OR (`||`) operator (en-US)
* Default paramaters in functions