Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
138 lines (112 sloc) 2.7 KB

Object Rest Destructuring

Specification

Examples

Shallow Clone (excluding prototype)

let { ...aClone } = a;

Rest Properties

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x; // 1
y; // 2
z; // { a: 3, b: 4 }

Nested Objects

let complex = {
  x: { a: 1, b: 2, c: 3 },
  y: [4, 5, 6]
};

let {
  x: { a: xa, ...xbc },
  y: [y0, ...y12]
} = complex;

xa; // 1
xbc; // { b: 2, c: 3 }
y0; // 4
y12; // [5, 6]

Extending a Function with Additional Options

function baseFunction({ a, b }) {
  // ...
}
function wrapperFunction({ x, y, ...restConfig }) {
  // do something with x and y
  // pass the rest to the base function
  return baseFunction(restConfig);
}

Extra properties may be safely added to baseFunction.

function baseFunction({ a, b, x }) {
  // ...
}
function wrapperFunction({ x, y, ...restConfig }) {
  // x won't be accidentally passed to baseFunction after this refactor
  return baseFunction(restConfig);
}

If the wrapper function wants to consume the x property but also pass it along, it can remerge it in using the spread operator.

function baseFunction({ a, b, x }) {
  // ...
}
function wrapperFunction({ x, y, ...restConfig }) {
  // explicitly pass x along
  return baseFunction({ ...restConfig, x });
}

Caveat: Only Own Properties

function ownX({ ...properties }) {
  return properties.x;
}
ownX(Object.create({ x: 1 })); // undefined
let { x, y, ...z } = a;
// is not equivalent to
let { x, ...n } = a;
let { y, ...z } = n;
// because x and y use the prototype chain

Restructure using Object Spread Operator

let assembled = { x: 1, y: 2, a: 3, b: 4 };
let { x, y, ...z } = assembled;
let reassembled = { x, y, ...z };

Runtime Error

let { x, y, ...z } = null; // runtime error

Static Error

let { ...x, y, z } = obj; // syntax error
let { x, ...y, ...z } = obj; // syntax error

Destructuring Only Own Properties

var o = Object.create({ x: 1, y: 2 });
o.z = 3;

var x, y, z;

// Destructuring assignment allows nested objects
({ x, ...{ y, z } } = o);
x; // 1
y; // undefined
z; // 3

Prior Art

Successor-ML

val { x = x, y = y, ... = z } = obj

http://successor-ml.org/index.php?title=Functional_record_extension_and_row_capture

Mentioned on the destructuring assignment wiki in previous discussions:

http://wiki.ecmascript.org/doku.php?id=discussion:destructuring_assignment#successor-ml_and_row_capture

http://wiki.ecmascript.org/doku.php?id=harmony:destructuring#issues