Permalink
Branch: master
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