Destructuring to get the last element of an array

2019-01-06 17:02发布

问题:

In coffeescript this is straightforward:

coffee> a = ['a', 'b', 'program']
[ 'a', 'b', 'program' ]
coffee> [_..., b] = a
[ 'a', 'b', 'program' ]
coffee> b
'program'

Does es6 allow for something similar?

> const [, b] = [1, 2, 3]                              
'use strict'                                           
> b  // it got the second element, not the last one!                      
2                                                      
> const [...butLast, last] = [1, 2, 3]          
SyntaxError: repl: Unexpected token (1:17)                                                                                                                                                        
> 1 | const [...butLast, last] = [1, 2, 3]                                                                                                                                                        
    |                  ^                                                                                                                                                                          
    at Parser.pp.raise (C:\Users\user\AppData\Roaming\npm\node_modules\babel\node_modules\babel-core\node_modules\babylon\lib\parser\location.js:24:13)                                           

Of course I can do it the es5 way -

const a = b[b.length - 1]

But maybe this is a bit prone to off by one errors. Can the splat only be the last thing in the destructuring?

回答1:

It is not possible in ES6/2015. The standard just doesn't provide for it.

As you can see in the spec, the FormalParameterList can either be:

  • a FunctionRestParameter
  • a FormalsList (a list of parametes)
  • a FormalsList, followed by a FunctionRestParameter

Having FunctionRestParameter followed by parameters is not provided.



回答2:

const [last] = [1, 3, 4, 5].slice(-1)
const [second_to_last] = [1, 3, 4, 5].slice(-2)


回答3:

I believe ES6 could at least help with that:

[...arr].pop()

Given your array (arr) is not undefined and an iterable element (yes, even strings work!!), it should return the last element..even for the empty array and it doesn't alter it either. It creates an intermediate array though..but that should not cost much.

Your example would then look like this:

[...['a', 'b', 'program']].pop() -> 'program'


回答4:

You can destructure the reversed array to get close to what you want.

const [a, ...rest] = ['a', 'b', 'program'].reverse();
  
document.body.innerHTML = 
    "<pre>"
    + "a: " + JSON.stringify(a) + "\n\n"
    + "rest: " + JSON.stringify(rest.reverse())
    + "</pre>";



回答5:

Not necessarily the most performant way of doing. But depending on the context a quite elegant way would be:

const myArray = ['one','two','three'];
const theOneIWant = [...myArray].pop();

console.log(theOneIWant); // 'three'
console.log(myArray.length); //3