2015-10-11 5 views
36

W coffeescript to jest prosta:destructuring dostać ostatni element tablicy w ES6

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

robi ES6 pozwolić na coś podobnego?

> 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)           

Oczywiście można zrobić to tak ES5 -

const a = b[b.length - 1] 

Ale może to nieco podatne na off by one. Czy kłótnia może być ostatnią rzeczą w destrukturyzacji?

+3

Dlaczego wszyscy myślą, że ES6 zmienia wszystko i jest jakaś nowa składnia do robienia xyz? –

+7

@FelixBadanie tego pytania dotyczy w szczególności zachowania '...' w es6, w szczególności, że może być użyte jako ostatnia rzecz podczas destrukturyzacji lub na liście parametrów. Jest to potencjalnie sprzeczne z intuicją osoby wchodzącej w es6 z coffeescript, a zatem to pytanie jest potencjalnie przydatne. –

+0

Oznacza to, że oprócz '[1,2,3] .slice (-1)' nie można nawet zniszczyć równoważnej '[1,2,3] .slice (0, -1)'. Są to typowe operacje. Wyniszczenie ES6 jest jakoś żartem! – rand

Odpowiedz

20

Nie jest to możliwe w ES6/2015. Standard po prostu tego nie zapewnia.

Jak widać w the spec The FormalParameterList mogą być:

  • FunctionRestParameter
  • FormalsList (wykaz parametes)
  • FormalsList, następnie FunctionRestParameter

Posiadanie FunctionRestParameter z następującymi parametrami nie jest przewidziane.

Jest to jeden z wielu przykładów na to, jak ES6/2015 jest gorszy niż CoffeeScript.

18

wierzę ES6 może przynajmniej w tym pomóc:

[...arr].pop() 

Biorąc swoją tablicę (arr) nie jest niezdefiniowany i iterable elementu (tak, nawet ciągi pracy !!), powinien on powrócić ostatni element ... dla pustej tablicy i to też nie zmienia. Tworzy to jednak pośrednią tablicę ... ale nie powinno to kosztować wiele.

Wasz przykład będzie wtedy wyglądać tak:

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

uhh, to jest dość złe, nawet '.slice (-1) [0]' jest nieznacznie mniej zły, lub 'var [last] = arr.slice(). reverse()' jest kolejnym brzydkim jeśli potrzebujesz – caub

+3

Myślałem, że ten post był o ES6/ES2015, nie? Ale szczególnie lubię twój ostatni kawałek. Jak o połączeniu dwóch: '' 'var [last] = arr.slice (-1)' '') – shoesel

+8

moim ulubionym sposobem jest 'Object.defineProperty (Array.prototype, -1, {get() {return this [this.length - 1]}}); [1,2,3] [- 1] ' – caub

11

Można destructure odwróconą tablicę zbliżyć się do tego, co chcesz.

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

+2

Smart. Lepsze niż 'const last = ['bbb', 'uuu', 'iii']. Slice (-1);'? Pod względem wydajności? – Vadorequest

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

[Zwycięzca!] (Https://jsperf.com/destructure-last/1) – Shanimal

+0

Ładne proste, niezmutowane rozwiązanie. –

1

Niekoniecznie najbardziej wydajnych sposobów robi. Ale w zależności od kontekstu dość elegancki sposób będzie:

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

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

Nie widzę żadnej elegancji w tym rozwiązaniu, ale w każdym razie @shoesel już to opublikował – Bergi