javascript - Kako mogu koristiti opcionalno lančanje s nizovima i funkcijama?


Pokušavam koristiti opcionalno lančanje s nizom umjesto s objektom, ali nisam siguran kako to učiniti:

Evo što pokušavam napraviti myArray.filter(x => x.testKey === myTestKey)?[0]. Također pokušavam sličnu stvar koristeći funkciju:

let x = {a: () => {}, b: null}
console.log(x?b());

Ali daje sličnu pogrešku - kako mogu koristiti opcionalno povezivanje s nizom ili funkcijom?

Odgovor #1

Trebaš staviti . nakon ? da bi koristio opcionalno lančanje:

myArray.filter(x => x.testKey === myTestKey)?.[0]

Veza za igralište

Korištenje samo ? samo čini da kompajler misli da pokušavate koristiti uvjetni operator (i tada baca pogrešku jer kasnije ne vidi :)

Opcionalno povezivanje nije samo stvar TypeScripta - to je gotov prijedlog i u običnom JavaScriptu.

Može se koristiti s notacijom zagrada kao gore, ali se može koristiti i s pristupom svojstvima pomoću točke:

const obj = {
  prop2: {
    nested2: 'val2'
  }
};

console.log(
  obj.prop1?.nested1,
  obj.prop2?.nested2
);

I s pozivima funkcija:

const obj = {
  fn2: () => console.log('fn2 running')
};

obj.fn1?.();
obj.fn2?.();

Odgovor #2

Upravo sam to našao nakon malo traženja na stranici 'što je novo' u službenoj dokumentaciji

Ispravan način za to s nizom je dodati . nakon ?

tako da će biti kao

myArray.filter(x => x.testKey === myTestKey)?.[0] // in case of object
x?.() // in case of function

Volio bih baciti više svjetla na to što se točno događa s mojim gore navedenim pitanjem.

myArray.filter(x => x.testKey === myTestKey)?[0]

Prevodi u

const result = myArray.filter(x => x.testKey === myTestKey) ? [0] : ;

Zbog čega se javlja pogreška jer nakon : nešto nedostaje, a vjerojatno ne želite da se vaš kod transpilira u ovo.

Zahvaljujući odgovoru Certain Performancea naučio sam nove stvari o TypeScriptu, posebno o alatu https://www.typescriptlang.org/play/index.html.

Odgovor #3

ECMA 262 (2020) koji testiram na Edge Chromium 84 može izvršavati operator opcionalnog lančanja bez TypeScript transpilera:

// All result are undefined
const a = {};

console.log(a?.b);
console.log(a?.["b-foo-1"]);
console.log(a?.b?.());

// Note that the following statements throw exceptions:
a?.(); // TypeError: a is not a function
a?.b(); // TypeError: a?.b is not a function

CanIUse: Chrome 80+, Firefox 74+

Odgovor #4

Nije nužno da je funkcija unutar objekta, funkciju možete pokrenuti koristeći opcionalno lančanje i ovako:

someFunction?.();

Ako someFunction postoji, izvršit će se, inače će se preskočiti izvršavanje i neće doći do pogreške.

Ova tehnika zapravo je vrlo korisna, posebno ako radite s komponentama koje se mogu ponovno koristiti i neke komponente možda nemaju ovu funkciju.

Povezani članci