This proposal has progressed to the Draft ECMAScript 6 Specification, which is available for review here: specification_drafts. Any new issues relating to them should be filed as bugs at http://bugs.ecmascript.org. The content on this page is for historic record only and may no longer reflect the current state of the feature described within.

Background

Requirements/Goals

  • Replace an array or array-like actual parameter value with its elements as positional parameters
  • Let new compose with a this-free form of apply
  • Remove (some day, and in similar future methods) automagic (and half-the-time wrong) array flattening, e.g. in Array.prototype.concat

Sketch

  • Let ... be special prefix syntax called spread.
  • The ... syntax is legal only as a prefix to these list elements:
    • an actual parameter AssignmentExpression within an ArgumentList
    • an element initialiser AssignmentExpression within an ElementList in an ArrayLiteral
  • Evaluate ... arg in such a list by evaluating arg and then replacing it with arg[0] through arg[arg.length - 1].
// Expand an array as element-wise positional parameters
function q(x, a, b, c) {
    return a * x * x + b * x + c;
}
var a = read_triple();
var x = read_value();
print(q(x, ...a));

// Compose new with this-free apply:
var date_fields = read_date_fields(database);
var d = new Date(...date_fields);

Syntax

ArgumentList :
  AssignmentOrSpreadExpression
  ArgumentList , AssignmentOrSpreadExpression

AssignmentOrSpreadExpression :
  ... AssignmentExpression
  AssignmentExpression  

ElementList :
  Elisionopt AssignmentOrSpreadExpression
  ElementList , Elisionopt AssignmentOrSpreadExpression

Semantics

11.2.4 Argument Lists

The evaluation of an argument list produces a List of values (see 8.8).

The production ArgumentList : AssignmentOrSpreadExpression is evaluated as follows:

  1. Return the result of evaluating AssignmentOrSpreadExpression

The production AssignmentOrSpreadExpression : AssignmentExpression

  1. Let ref be the result of evaluating AssignmentExpression.
  2. Let arg be GetValue(ref).
  3. Return a List whose sole item is arg.

The production AssignmentOrSpreadExpression : ... AssignmentExpression

  1. Let ref be the result of evaluating AssignmentExpression.
  2. Let argArray be GetValue(ref).
  3. If argArray is null or undefined, then
    1. Return an empty list
  4. If Type(argArray) is not Object, then throw a TypeError exception.
  5. Let len be the result of calling the [[Get]] internal method of argArray with argument “length”.
  6. Let n be ToUint32(len).
  7. Let argList be an empty List.
  8. Let index be 0.
  9. Repeat while index < n
    1. Let indexName be ToString(index).
    2. Let nextArg be the result of calling the [[Get]] internal method of argArray with indexName as the argument.
    3. Append nextArg as the last element of argList.
    4. Set index to index + 1.
  10. Return argList

The production ArgumentList : ArgumentList , AssignmentOrSpreadExpression is evaluated as follows:

  1. Let precedingArgs be the result of evaluating ArgumentList.
  2. Let ref be the result of evaluating AssignmentOrSpreadExpression.
  3. Let arg be GetValue(ref).
  4. Return a List whose length is the length of precedingArgs plus the length of arg and whose items are the items of precedingArgs, in order, followed by the items of arg, in order.

11.1.4 Array Initialiser

...

The production ElementList : Elisionopt AssignmentOrSpreadExpression is evaluated as follows:

  1. Let array be the result of creating a new object as if by the expression new Array() where Array is the standard built-in constructor with that name.
  2. Let pad be the result of evaluating Elision; if not present, use the numeric value zero.
  3. Let initList be the result of evaluating AssignmentOrSpreadExpression.
  4. Let index be pad.
  5. Iterate over the values in initList.
    1. Let indexName be ToString(index).
    2. Let value be the current value of initList.
    3. Call the [[DefineOwnProperty]] internal method of array with arguments indexName, the Property Descriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    4. Set index to index + 1.
  6. Return array.

The production ElementList : ElementList , Elisionopt AssignmentOrSpreadExpression is evaluated as follows:

  1. Let array be the result of evaluating ElementList.
  2. Let pad be the result of evaluating Elision; if not present, use the numeric value zero.
  3. Let initList be the result of evaluating AssignmentOrSpreadExpression.
  4. Let len be the result of calling the [[Get]] internal method of array with argument “length”.
  5. Let index be pad + len.
  6. Iterate over the values in initList.
    1. Let indexName be ToString(index).
    2. Let value be the current value of initList.
    3. Call the [[DefineOwnProperty]] internal method of array with arguments indexName, the Property Descriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    4. Set index to index + 1.
  7. Return array.

...

Discussion

We should also support spread in destructuring.

let a = [0, 1, 2];
let [x, ...xs] = a;
// x = 0
// xs = [1, 2]

Erik Arvidsson 2010/11/04 00:30

 
harmony/spread.txt · Last modified: 2013/07/11 23:59 by rwaldron
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki