Základní operátory, matematika

Mnoho operátorů známe ze školy. Jsou to věci jako sčítání + , násobení * , odčítání - , a tak dále.

V této kapitole začneme jednoduchými operátory a poté se zaměříme na aspekty specifické pro JavaScript, které nejsou pokryty školní aritmetikou.

Termíny:„unární“, „binární“, „operand“

Než budeme pokračovat, uchopme běžnou terminologii.

  • Operand – na co se operátoři vztahují. Například při násobení 5 * 2 existují dva operandy:levý operand je 5 a pravý operand je 2 . Někdy jim lidé říkají „argumenty“ místo „operandy“.

  • Operátor je unární pokud má jeden operand. Například unární negace - obrátí znaménko čísla:

    let x = 1;
    
    x = -x;
    alert( x ); // -1, unary negation was applied
  • Operátor je binární pokud má dva operandy. Stejné mínus existuje také v binární podobě:

    let x = 1, y = 3;
    alert( y - x ); // 2, binary minus subtracts values

    Formálně ve výše uvedených příkladech máme dva různé operátory, které sdílejí stejný symbol:operátor negace, unární operátor, který převrací znaménko, a operátor odčítání, binární operátor, který odečítá jedno číslo od druhého.

Matematika

Jsou podporovány následující matematické operace:

  • Dodatek + ,
  • Odčítání - ,
  • Násobení * ,
  • Divize / ,
  • Zbytek % ,
  • Umocnění ** .

První čtyři jsou jednoduché, zatímco % a ** potřebujeme o nich pár slov.

Zbytek %

Operátor zbytku % , navzdory svému vzhledu, nesouvisí s procenty.

Výsledek a % b je zbytek celočíselného dělení a podle b .

Například:

alert( 5 % 2 ); // 1, a remainder of 5 divided by 2
alert( 8 % 3 ); // 2, a remainder of 8 divided by 3

Umocnění **

Operátor umocnění a ** b zvyšuje a na sílu b .

Ve školní matematice to píšeme jako a b .

Například:

alert( 2 ** 2 ); // 2² = 4
alert( 2 ** 3 ); // 2³ = 8
alert( 2 ** 4 ); // 2⁴ = 16

Stejně jako v matematice je operátor umocňování definován i pro neceločíselná čísla.

Například druhá odmocnina je umocnění o ½:

alert( 4 ** (1/2) ); // 2 (power of 1/2 is the same as a square root)
alert( 8 ** (1/3) ); // 2 (power of 1/3 is the same as a cubic root)

Zřetězení řetězců pomocí binárních +

Pojďme se seznámit s funkcemi operátorů JavaScriptu, které přesahují školní aritmetiku.

Obvykle se používá operátor plus + součtová čísla.

Ale pokud je binární + se aplikuje na řetězce, sloučí je (zřetězí):

let s = "my" + "string";
alert(s); // mystring

Všimněte si, že pokud je některý z operandů řetězec, pak se i ten druhý převede na řetězec.

Například:

alert( '1' + 2 ); // "12"
alert( 2 + '1' ); // "21"

Vidíte, nezáleží na tom, zda je první operand řetězec nebo druhý.

Zde je složitější příklad:

alert(2 + 2 + '1' ); // "41" and not "221"

Zde operátoři pracují jeden po druhém. První + sečte dvě čísla, takže vrátí 4 , pak další + přidá řetězec 1 na to, takže je to jako 4 + '1' = '41' .

alert('1' + 2 + 2); // "122" and not "14"

Zde je prvním operandem řetězec, kompilátor zachází s dalšími dvěma operandy také jako s řetězci. 2 se zřetězí do '1' , takže je to jako '1' + 2 = "12" a "12" + 2 = "122" .

Binární + je jediným operátorem, který podporuje řetězce tímto způsobem. Ostatní aritmetické operátory pracují pouze s čísly a vždy převádějí své operandy na čísla.

Zde je ukázka odčítání a dělení:

alert( 6 - '2' ); // 4, converts '2' to a number
alert( '6' / '2' ); // 3, converts both operands to numbers

Číselný převod, unární +

Plus + existuje ve dvou formách:binární forma, kterou jsme použili výše, a unární forma.

Jednočlenné plus nebo jinými slovy plusový operátor + použito na jednu hodnotu, nedělá nic s čísly. Ale pokud operand není číslo, unární plus jej převede na číslo.

Například:

// No effect on numbers
let x = 1;
alert( +x ); // 1

let y = -2;
alert( +y ); // -2

// Converts non-numbers
alert( +true ); // 1
alert( +"" ); // 0

Ve skutečnosti dělá to samé jako Number(...) , ale je kratší.

Potřeba převádět řetězce na čísla vzniká velmi často. Pokud například získáváme hodnoty z polí formuláře HTML, jsou to obvykle řetězce. Co když je chceme sečíst?

Binární plus by je přidal jako řetězce:

let apples = "2";
let oranges = "3";

alert( apples + oranges ); // "23", the binary plus concatenates strings

Pokud s nimi chceme zacházet jako s čísly, musíme je převést a pak je sečíst:

let apples = "2";
let oranges = "3";

// both values converted to numbers before the binary plus
alert( +apples + +oranges ); // 5

// the longer variant
// alert( Number(apples) + Number(oranges) ); // 5

Z hlediska matematika se množství plusů může zdát zvláštní. Ale z pohledu programátora na tom není nic zvláštního:nejprve se aplikují unární plusy, převedou řetězce na čísla a pak je binární plus sečte.

Proč jsou unární plusy aplikovány na hodnoty před binárními? Jak uvidíme, je to kvůli jejich vyšší prioritě .

Priorita operátora

Pokud má výraz více než jeden operátor, je pořadí provedení definováno jejich preferencí , nebo jinými slovy výchozí pořadí priorit operátorů.

Ze školy všichni víme, že násobení ve výrazu 1 + 2 * 2 by měla být vypočtena před přidáním. To je přesně ta priorita. Říká se, že násobení má vyšší prioritu než sčítání.

Závorky mají přednost před jakoukoli prioritou, takže pokud nejsme spokojeni s výchozím pořadím, můžeme je použít ke změně. Napište například (1 + 2) * 2 .

V JavaScriptu existuje mnoho operátorů. Každý operátor má odpovídající číslo priority. Ten s větším číslem se provede jako první. Pokud je priorita stejná, příkaz k provedení je zleva doprava.

Zde je výňatek z tabulky priorit (nemusíte si to pamatovat, ale mějte na paměti, že unární operátory jsou vyšší než odpovídající binární):

Prednost Jméno Podepsat
14 unární plus +
14 unární negace -
13 umocnění **
12 násobení *
12 divize /
11 dodatek +
11 odčítání -
2 úkol =

Jak vidíme, „unární plus“ má prioritu 14 která je vyšší než 11 „sčítání“ (binární plus). Proto ve výrazu "+apples + +oranges" , jednočlenné plusy fungují před přidáním.

Přiřazení

Všimněme si, že přiřazení = je také provozovatelem. Je uveden v tabulce priorit s velmi nízkou prioritou 2 .

To je důvod, proč, když přiřadíme proměnnou, například x = 2 * 2 + 1 , nejprve se provedou výpočty a poté = se vyhodnotí a výsledek se uloží do x .

let x = 2 * 2 + 1;

alert( x ); // 5

Přiřazení =vrátí hodnotu

Skutečnost = být operátorem, nikoli „magickým“ jazykovým konstruktem, má zajímavý význam.

Všechny operátory v JavaScriptu vracejí hodnotu. To je zřejmé pro + a - , ale také platí pro = .

Volání x = value zapíše value do x a poté jej vrátí .

Zde je ukázka, která používá přiřazení jako součást složitějšího výrazu:

let a = 1;
let b = 2;

let c = 3 - (a = b + 1);

alert( a ); // 3
alert( c ); // 0

Ve výše uvedeném příkladu výsledek výrazu (a = b + 1) je hodnota, která byla přiřazena a (to je 3 ). Poté se použije pro další hodnocení.

Legrační kód, že? Měli bychom rozumět tomu, jak to funguje, protože to někdy vidíme v knihovnách JavaScriptu.

I když, prosím, nepište kód takto. Takové triky rozhodně neudělají kód jasnějším ani čitelnějším.

Řetězení úkolů

Další zajímavou funkcí je možnost řetězit úkoly:

let a, b, c;

a = b = c = 2 + 2;

alert( a ); // 4
alert( b ); // 4
alert( c ); // 4

Zřetězené úkoly se vyhodnocují zprava doleva. Nejprve výraz zcela vpravo 2 + 2 je vyhodnocena a poté přiřazena k proměnným vlevo:c , b a a . Nakonec všechny proměnné sdílejí jednu hodnotu.

Ještě jednou, pro účely čitelnosti je lepší rozdělit takový kód na několik řádků:

c = 2 + 2;
b = c;
a = c;

To je snazší číst, zvláště když rychle skenujete kód.

Úpravy na místě

Často potřebujeme použít operátor na proměnnou a uložit nový výsledek do stejné proměnné.

Například:

let n = 2;
n = n + 5;
n = n * 2;

Tento zápis lze zkrátit pomocí operátorů += a *= :

let n = 2;
n += 5; // now n = 7 (same as n = n + 5)
n *= 2; // now n = 14 (same as n = n * 2)

alert( n ); // 14

Krátké operátory „modify-and-assign“ existují pro všechny aritmetické a bitové operátory:/= , -= , atd.

Takové operátory mají stejnou prioritu jako normální přiřazení, takže běží po většině ostatních výpočtů:

let n = 2;

n *= 3 + 5; // right part evaluated first, same as n *= 8

alert( n ); // 16

Zvýšení/snížení

Zvětšení nebo zmenšení čísla o jedna patří mezi nejběžnější numerické operace.

Takže pro to existují speciální operátory:

  • Přírůstek ++ zvýší proměnnou o 1:

    let counter = 2;
    counter++; // works the same as counter = counter + 1, but is shorter
    alert( counter ); // 3
  • Snížit -- sníží proměnnou o 1:

    let counter = 2;
    counter--; // works the same as counter = counter - 1, but is shorter
    alert( counter ); // 1
Důležité:

Přírůstek/snížení lze použít pouze na proměnné. Zkouším to použít na hodnotu jako 5++ zobrazí chybu.

Operátory ++ a -- lze umístit před nebo za proměnnou.

  • Když operátor jde za proměnnou, je ve „postfixovém tvaru“:counter++ .
  • Formát předpony je, když operátor předchází proměnnou:++counter .

Oba tyto příkazy dělají totéž:zvýšení counter od 1 .

Je v tom nějaký rozdíl? Ano, ale můžeme to vidět, pouze pokud použijeme vrácenou hodnotu ++/-- .

Pojďme si to ujasnit. Jak víme, všechny operátory vracejí hodnotu. Přírůstek/snížení není výjimkou. Předpona vrací novou hodnotu, zatímco postfixová vrací starou hodnotu (před zvýšením/snížením).

Chcete-li vidět rozdíl, zde je příklad:

let counter = 1;
let a = ++counter; // (*)

alert(a); // 2

V řádku (*) , předpona formulář ++counter zvýšení counter a vrátí novou hodnotu 2 . Takže alert ukazuje 2 .

Nyní použijeme postfixový formulář:

let counter = 1;
let a = counter++; // (*) changed ++counter to counter++

alert(a); // 1

Na řádku (*) , postfix formulář counter++ také zvýší counter ale vrátí staré hodnotu (před zvýšením). Takže alert ukazuje 1 .

Abych to shrnul:

  • Pokud se nepoužije výsledek zvýšení/snížení, není žádný rozdíl v tom, kterou formu použít:

    let counter = 0;
    counter++;
    ++counter;
    alert( counter ); // 2, the lines above did the same
  • Pokud bychom chtěli zvýšit hodnotu a okamžitě použijeme výsledek operátoru, potřebujeme tvar předpony:

    let counter = 0;
    alert( ++counter ); // 1
  • Pokud bychom chtěli zvýšit hodnotu, ale použít její předchozí hodnotu, potřebujeme postfixový formulář:

    let counter = 0;
    alert( counter++ ); // 0
Zvýšení/snížení mezi ostatními operátory

Operátory ++/-- lze použít i uvnitř výrazů. Jejich priorita je vyšší než u většiny ostatních aritmetických operací.

Například:

let counter = 1;
alert( 2 * ++counter ); // 4

Porovnejte s:

let counter = 1;
alert( 2 * counter++ ); // 2, because counter++ returns the "old" value

I když je to technicky v pořádku, takový zápis obvykle činí kód méně čitelným. Jeden řádek dělá více věcí – není dobrý.

Při čtení kódu může rychlý „vertikální“ sken oka snadno přehlédnout něco jako counter++ a nebude zřejmé, že se proměnná zvýšila.

Doporučujeme styl „jeden řádek – jedna akce“:

let counter = 1;
alert( 2 * counter );
counter++;

Bitové operátory

Bitové operátory považují argumenty za 32bitová celá čísla a pracují na úrovni jejich binární reprezentace.

Tyto operátory nejsou specifické pro JavaScript. Jsou podporovány ve většině programovacích jazyků.

Seznam operátorů:

  • A ( & )
  • NEBO ( | )
  • XOR ( ^ )
  • NE ( ~ )
  • LEVÝ Shift ( << )
  • PRAVÝ Shift ( >> )
  • NULA-VYPLNIT PRAVÝ POSUN ( >>> )

Tyto operátory se používají velmi zřídka, když si potřebujeme pohrát s čísly na úplně nejnižší (bitové) úrovni. Tyto operátory brzy nebudeme potřebovat, protože vývoj webu je málo využívá, ale v některých speciálních oblastech, jako je kryptografie, jsou užitečné. V případě potřeby si můžete přečíst kapitolu Bitwise Operators o MDN.

Čárka

Operátor čárky , je jedním z nejvzácnějších a nejneobvyklejších operátorů. Někdy se používá k psaní kratšího kódu, takže jej potřebujeme znát, abychom pochopili, co se děje.

Operátor čárky nám umožňuje vyhodnotit několik výrazů a vydělit je čárkou , . Každý z nich je vyhodnocen, ale vrátí se pouze výsledek posledního.

Například:

let a = (1 + 2, 3 + 4);

alert( a ); // 7 (the result of 3 + 4)

Zde je první výraz 1 + 2 se vyhodnotí a jeho výsledek se zahodí. Poté 3 + 4 se vyhodnotí a vrátí jako výsledek.

Čárka má velmi nízkou prioritu

Upozorňujeme, že operátor čárky má velmi nízkou prioritu, nižší než = , takže závorky jsou ve výše uvedeném příkladu důležité.

Bez nich:a = 1 + 2, 3 + 4 vyhodnotí + nejprve sečtením čísel do a = 3, 7 , pak operátor přiřazení = přiřadí a = 3 a zbytek je ignorován. Je to jako (a = 1 + 2), 3 + 4 .

Proč potřebujeme operátor, který zahodí všechno kromě posledního výrazu?

Někdy to lidé používají ve složitějších konstrukcích, aby umístili několik akcí na jeden řádek.

Například:

// three operations in one line
for (a = 1, b = 3, c = a * b; a < 10; a++) {
 ...
}

Takové triky se používají v mnoha frameworkech JavaScriptu. Proto je zmiňujeme. Obvykle ale nezlepšují čitelnost kódu, takže bychom si je měli dobře rozmyslet, než je použijeme.