Kiedy operator przecinka jest przydatny?

Przeczytałem to pytanie o "operator przecinka" w wyrażeniach (,) i MDN docs na ten temat, ale nie mogę wymyślić scenariusza, w którym byłby przydatny.

Kiedy więc operator przecinka jest przydatny?

Author: Community, 2012-03-06

10 answers

Poniższy tekst prawdopodobnie nie jest zbyt przydatny, ponieważ nie piszesz go samodzielnie, ale minifier może zmniejszyć kod za pomocą operatora przecinka. Na przykład:

if(x){foo();return bar()}else{return 1}

Stałoby się:

return x?(foo(),bar()):1

The ? : operator może być użyty teraz, ponieważ operator przecinka (do pewnego stopnia) pozwala na zapisanie dwóch instrukcji jako jednej instrukcji.

Ten jest użyteczny, ponieważ pozwala na porządną kompresję (39 - > 24 bajty tutaj).


Chciałbym podkreślić fakt, że przecinek w var a, b jest Nie operator przecinka, ponieważ nie istnieje w wyrażeniu . Przecinek ma szczególne znaczenie w var statements . a, b w wyrażeniu odnosiłoby się do dwóch zmiennych i oceniało na b, co nie ma miejsca w przypadku var a, b.

 92
Author: pimvdb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-02 10:37:22

Operator przecinka pozwala umieścić wiele wyrażeń w miejscu, w którym oczekuje się jednego wyrażenia. wartość wynikowa wielu wyrażeń oddzielonych przecinkiem będzie wartością ostatniego wyrażenia oddzielonego przecinkami.

Osobiście nie używam go zbyt często, ponieważ nie ma zbyt wielu sytuacji, w których oczekuje się więcej niż jednego wyrażenia i nie ma mniej mylącego sposobu pisania kodu niż użycie operatora przecinka. Jedną z ciekawych możliwości jest koniec pętli for, gdy chcesz zwiększyć więcej niż jedną zmienną:

// j is initialized to some other value
// as the for loop executes both i and j are incremented
// because the comma operator allows two statements to be put in place of one
for (var i = 0; i < items.len; i++, j++) {
    // loop code here that operates on items[i] 
    // and sometimes uses j to access a different array
}

Tutaj widzisz, że i++, j++ można umieścić w miejscu, w którym dozwolone jest jedno wyrażenie. W tym konkretnym przypadku wyrażenia wielokrotne są używane dla afektów bocznych, więc nie ma znaczenia, że wyrażenia złożone przyjmują wartość ostatniego, ale są inne przypadki, w których może to mieć znaczenie.

 29
Author: jfriend00,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-23 12:13:40

Operator Przecinka jest często przydatny przy pisaniu kodu funkcjonalnego w Javascript.

Rozważ ten kod, który napisałem dla SPA jakiś czas temu, który miał coś podobnego do następującego

const actions = _.chain(options)
                 .pairs() // 1
                 .filter(selectActions) // 2
                 .map(createActionPromise) // 3
                 .reduce((state, pair) => (state[pair[0]] = pair[1], state), {}) // 4
                 .value();
To był dość skomplikowany, ale realny scenariusz. Bądź ze mną, a ja wyjaśnię, co się dzieje, i w procesie zrobić przypadek dla operatora Przecinka.
To używa podkreślenia do
  1. Rozebrać wszystkie opcje przekazane do tego function using pairs który zamieni { a: 1, b: 2} w [['a', 1], ['b', 2]]

  2. Ta tablica par właściwości jest filtrowana, przez co te są uważane za "akcje" w systemie.

  3. Następnie drugi indeks w tablicy jest zastępowany funkcją, która zwraca obietnicę reprezentującą tę akcję (używając map)

  4. W końcu wywołanie reduce Scali każdą "tablicę właściwości" (['a', 1]) z powrotem do ostatecznego obiektu.

Efektem końcowym jest transformacja wersja argumentu options, który zawiera tylko odpowiednie klucze i którego wartości są używane przez funkcję wywołującą.


Patrząc na just

.reduce((state, pair) => (state[pair[0]] = pair[1], state), {})

Możesz zobaczyć, że funkcja reduce zaczyna się od pustego obiektu stanu, state i dla każdej pary reprezentującej klucz i wartość, funkcja zwraca ten sam obiekt state po dodaniu właściwości do obiektu odpowiadającego parze klucz/wartość. Ze względu na składnię funkcji arrow w ECMAScript 2015, ciało funkcji jest wyrażenie, a w rezultacie Operator Przecinka pozwala na zwięzłą i użyteczną funkcję "iteratee".

Osobiście natknąłem się na wiele przypadków podczas pisania Javascript w bardziej funkcjonalnym stylu Z FUNKCJAMI ECMAScript 2015 + Arrow. Powiedziawszy to, przed spotkaniem z funkcjami strzałek (takimi jak w momencie pisania pytania), nigdy nie użyłem operatora przecinka w żaden celowy sposób.

 24
Author: Syynth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-22 06:25:51

Innym zastosowaniem operatora przecinka jest ukrywanie wyników, które cię nie interesują w repl lub konsoli, wyłącznie dla wygody.

Na przykład, jeśli ocenisz myVariable = aWholeLotOfText w repl lub konsoli, wyświetli wszystkie dane, które właśnie przypisałeś. Może to być pages i pages, a jeśli wolisz tego nie widzieć, możesz zamiast tego ocenić myVariable = aWholeLotOfText, 'done', A repl / console po prostu wyświetli "gotowe".

Oriel poprawnie wskazuje że dostosowane toString() lub get() funkcje mogą nawet uczynić to użytecznym.

 15
Author: Julian de Bhal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:33

Operator Przecinka nie jest specyficzny dla JavaScript, jest dostępny w innych językach, takich jak C i C++. Jako operator binarny jest to przydatne, gdy pierwszy operand, który jest ogólnie wyrażeniem, ma pożądany efekt uboczny wymagany przez drugi operand. Przykład z Wikipedii:

i = a += 2, a + b;

Oczywiście można napisać dwie różne linie kodów, ale używanie przecinków jest inną opcją i czasami bardziej czytelną.

 11
Author: taskinoor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-06 07:38:11

Nie zgodzę się z Flanaganem i powiem, że przecinek jest naprawdę przydatny i pozwala pisać bardziej czytelny i elegancki kod, zwłaszcza gdy wiesz co robisz:

Oto bardzo szczegółowy artykuł na temat użycia przecinków:

Kilka przykładów stamtąd dla dowodu demonstracji:

function renderCurve() {
  for(var a = 1, b = 10; a*b; a++, b--) {
    console.log(new Array(a*b).join('*'));
  }
}

Generator Fibonacciego:

for (
    var i=2, r=[0,1];
    i<15;
    r.push(r[i-1] + r[i-2]), i++
); 
// 0,1,1,2,3,5,8,13,21,34,55,89,144,233,377

Znajdź pierwszy element nadrzędny, analogiczny do funkcji jQuery .parent():

function firstAncestor(el, tagName) {
    while(el = el.parentNode, el && (el.tagName != tagName.toUpperCase()));
    return el;
}

//element in http://ecma262-5.com/ELS5_HTML.htm
var a = $('Section_15.1.1.2'); 

firstAncestor(a, 'div'); //<div class="page">
 4
Author: shaman.sir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-30 16:15:06

Nie znalazłem innego praktycznego zastosowania, ale oto jeden scenariusz, w którym James Padolsey ładnie używa tej techniki wykrywania IE W pętli while:

var ie = (function(){

    var undef,
        v = 3,
        div = document.createElement('div'),
        all = div.getElementsByTagName('i');

    while ( // <-- notice no while body here
        div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
        all[0]
    );

    return v > 4 ? v : undef;

}());

Te dwie linie muszą wykonać:

div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
all[0]

I wewnątrz operatora przecinka, oba są oceniane, choć można by je jakoś wyodrębnić.

 3
Author: Sarfraz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-06 10:16:27

Jest coś "dziwnego", co można zrobić w JavaScript wywołując funkcję pośrednio za pomocą operatora przecinka.

Jest tu długi opis: pośrednie wywołanie funkcji w JavaScript

Używając tej składni:

(function() {
    "use strict";
  
    var global = (function () { return this || (1,eval)("this"); })();
    console.log('Global === window should be true: ', global === window);
  
    var not_global = (function () { return this })();
    console.log('not_global === window should be false: ', not_global === window);
  
  }());

Możesz uzyskać dostęp do zmiennej globalnej, ponieważ eval działa inaczej, gdy wywołana jest bezpośrednio vs wywołana pośrednio.

 3
Author: Jeremy J Starcher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:19

Typowy przypadek, w którym go używam, to parsowanie argumentów opcjonalnych. Myślę, że czyni to zarówno bardziej czytelnym, jak i bardziej zwięzłym, tak aby parsowanie argumentów nie zdominowało ciała funkcji.

/**
 * @param {string} [str]
 * @param {object} [obj]
 * @param {Date} [date]
 */
function f(str, obj, date) {
  // handle optional arguments
  if (typeof str !== "string") date = obj, obj = str, str = "default";
  if (obj instanceof Date) date = obj, obj = {};
  if (!(date instanceof Date)) date = new Date();

  // ...
}
 1
Author: Rich Remer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-18 22:20:57

Innym obszarem, w którym można użyć operatora przecinka, jest maskowanie kodu .

Powiedzmy, że programista pisze jakiś kod w ten sposób:

var foo = 'bar';
Postanawia zaciemnić kod. Użyte narzędzie może zmienić kod w następujący sposób:
var Z0b=(45,87)>(195,3)?'bar':(54,65)>(1,0)?'':'baz';// Z0b == 'bar'

Demo: http://jsfiddle.net/uvDuE/

 -3
Author: Stephan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-12 03:31:05