The spread operator (`...`) is used to spread elements from an iterable (like an array) into individual elements. It can also be used to clone arrays or objects. For example:
```js
const arr = [1, 2, 3];
const newArr = [...arr, 4, 5]; // [1, 2, 3, 4, 5]
```
A `Promise` in JavaScript represents a value that may be available now, in the future, or never. It allows handling of asynchronous operations by providing methods like `.then()`, `.catch()`, and `.finally()`. Promises have three states: `pending`, `fulfilled`, and `rejected`. They allow chaining and error handling in asynchronous code.
Destructuring allows you to unpack values from arrays or properties from objects into distinct variables. For example:
```js
const [a, b] = [1, 2]; // Array destructuring
const {name, age} = {name: 'John', age: 30}; // Object destructuring
```
Template literals allow for multi-line strings and embedded expressions. They are created using backticks (`` ` ``) instead of quotes. For example:
```js
const name = 'John';
const greeting = `Hello, ${name}!`;
```
ES6 introduced several new features such as `let` and `const` for block-scoped variable declarations, arrow functions, template literals, destructuring assignment, default parameters, `Promise` for asynchronous code, classes, modules, and the spread/rest operators (`...`).