javascript - Použitie premennej _ (podčiarkovník) s arrow funkciami v ES6/Typescripte


Narazil som na túto konštrukciu v príklade Angular a zaujímalo by ma, prečo bola zvolená:

_ => console.log('Not using any parameters');

Chápem, že premenná _ znamená, že na nej nezáleží/nemá sa používať, ale keďže je to jediná premenná, existuje nejaký dôvod uprednostniť použitie _ pred:

() => console.log('Not using any parameters');

Určite to nemôže byť o jednej postave menej na písanie. Podľa mňa syntax () lepšie vyjadruje zámer a je tiež viac typovo špecifická, pretože inak by prvý príklad mohol vyzerať takto:

(_: any) => console.log('Not using any parameters');

Ak to má nejaký význam, toto bol kontext, v ktorom sa to používalo:

submit(query: string): void {
    this.router.navigate(['search'], { queryParams: { query: query } })
      .then(_ => this.search());
}

Odpoveď č. 1

Dôvod, prečo je možné použiť tento štýl (a pravdepodobne prečo bol použitý tu), je ten, že _ je o jeden znak kratší ako ().

Voliteľné zátvorky spadajú do rovnakého štýlového problému ako voliteľné slučkové zátvorky. Ide väčšinou o záležitosť vkusu a štýlu kódu, ale tu sa uprednostňuje rozvláčnosť kvôli konzistentnosti.

Zatiaľ čo šípové funkcie umožňujú jeden parameter bez zátvoriek, je to nekonzistentné pri nulových, jednom deštrukturovanom, jednom zostávajúcom a viacerých parametroch:

let zeroParamFn = () => { ... };
let oneParamFn = param1 => { ... };
let oneParamDestructuredArrFn = ([param1]) => { ... };
let oneParamDestructuredObjFn = ({ param1 }) => { ... };
let twoParamsFn = (param1, param2) => { ... };
let restParamsFn = (...params) => { ... };

Aj keď chyba is declared but never used bola opravená v TypeScript 2.0 pre parametre s podčiarkovníkom, _ môže tiež vyvolať varovanie unused variable/parameter od lintera alebo IDE. Toto je značný argument proti tomu, aby sa to robilo.

_ sa môže konvenčne používať pre ignorované parametre (ako už vysvetlil druhý odpoveď). Hoci to môže byť považované za prijateľné, tento zvyk môže spôsobiť konflikt s _ menným priestorom Underscore/Lodash, a tiež vyzerá mätúco, keď je viac ignorovaných parametrov. Z tohto dôvodu je výhodné mať správne pomenované parametre s podčiarkovníkom (podporované v TS 2.0), čo tiež šetrí čas pri zisťovaní podpisu funkcie a prečo sú parametre označené ako ignorované (to odporuje účelu _ parametra ako skratky):

let fn = (param1, _unusedParam2, param3) => { ... };

Z vyššie uvedených dôvodov by som osobne považoval štýl kódu _ => { ... } za zlý tón, ktorému by sa malo vyhýbať.

Odpoveď č. 2

Syntax () podľa môjho názoru lepšie vyjadruje úmysel a je tiež špecifickejšia pre typ

Nie presne. () hovorí, že funkcia neočakáva žiadne argumenty, nevykazuje žiadne parametre. .length funkcie je 0.

Ak použijete _, výslovne to uvádza, že funkcii bude odovzdaný jeden argument, ale že vám na ňom nezáleží. .length funkcie bude 1, čo môže byť dôležité v niektorých rámcoch.

Takže z pohľadu typov by to mohlo byť presnejšie riešenie (najmä keď to neinicializuješ ako any, ale napríklad _: Event). A ako si povedal, je to o jeden znak menej na napísanie, čo je tiež ľahšie dosiahnuteľné na niektorých klávesniciach.

Odpoveď č. 3

Myslím, že _ => sa používa namiesto () => jednoducho preto, že _ je bežné v iných jazykoch, kde nie je povolené len tak vynechať parametre ako v JS.

_ je populárny v Go a používa sa aj v Dart na označenie, že parameter sa ignoruje, a pravdepodobne aj v iných jazykoch, o ktorých neviem.

Odpoveď č. 4

Je možné rozlíšiť medzi týmito dvoma spôsobmi použitia a niektoré rámce to využívajú na reprezentáciu rôznych typov spätných volaní. Napríklad si myslím, že framework nodes express toto využíva na rozlíšenie typov middleware, napríklad spracovatelia chýb používajú tri argumenty, zatiaľ čo routovanie používa dva.

Takáto diferenciácia môže vyzerať ako príklad nižšie:

const f1 = () => { } // A function taking no arguments
const f2 = _ => { }  // A function with one argument that doesn't use it

function h(ff) { 
  if (ff.length === 0) {
    console.log("No argument function - calling directly");
    ff();
  } else if (ff.length === 1) {
    console.log("Single argument function - calling with 1");
    ff(1);
  }
}

h(f1);
h(f2);

Toto je založené na Bergiho odpovedi, ale myslel som si, že pridanie príkladu je trochu viac úprav, než s čím som bol ochotný zasahovať do príspevku niekoho iného.

Súvisiace články