JavaScript tipy a triky. rubrika: Programování: JavaScript

Anonym
položil/-a 2.12.2017
 
upravil/-a 2.12.2017

Prispejte prosím do zbierky v komentároch, alebo odpovediach :)

VALUE SWAPPING

let a = 'world', b = 'hello'
[a, b] = [b, a]
console.log(a, b) // hello world

ARRAY CONCATENATION

let a = ['aa', 'bb'], b = ['cc', 'dd']
var result = a.concat(b) // old way
var result = [...a, ...b]

ASYNC/AWAIT

const [user, account] = await Promise.all([
  fetch('/user'),
  fetch('/account')
])

MORE READABLE FUNCTIONS

const myFunc = (id, force, verbose) => {
  ...do stuff
}
// Somewhere else in the codebase... 
myFunc(150, true, true) // WTF is true, true?
 
const improved = ({ id, force, verbose }) => {
  ...do stuff
}
// Somewhere else in the codebase...
improved({ id: 150, force: true, verbose: true }) // more readable

FIND MAX ONELINER

const max = arr => Math.max(...arr)
max([123, 456, 78]) // 456

CONVERT TO NUMBER

const toNumber = number => +number
console.log(toNumber('1234')) // 1234
console.log(toNumber('ABC')) // NaN

SHUFFLE

var sorted = [1, 2, 3]
const shuffle = arr => arr.sort(_=> Math.random()-0.5)
console.log(shuffle(sorted)) // 2,1,3

SHORT CIRCUIT

if (connected) {
  login()
}
// Or shorter version
connected && login()

CONVERT TRUTHY/FALSY TO BOOLEAN

var arr = [0]
console.log(!!arr, !!arr[0]) // true, false

Komentáře

  • harrison314 : to nie su typy a triky, to je kusok zo specifikacie :D 2.12.2017
  • Anonym : tos uhod bobeši :) 2.12.2017
  • kate.mihalikova : Ohledně toNumber není potřeba vymýšlet kolo, existuje built-in funkce Number, která dělá to samé. 9.12.2017
odkaz
12 rmaslo
odpověděl/-a 3.12.2017
 
upravil/-a 3.12.2017

Trik: replaceAll

JS má metodu .replace, ta ovšem (při zadání stringu jako parametru) nahrazuje jen první výskyt stringu v řetězci:

Kód

var str = 'test test test test';
str = str.replace('test', 'abc');
alert(str);

vrátí tedy "abc test test test"


Pokud bychom chtěli nahradit všechny výskyty musíme v této metodě použít RegExp s modifikátorem "g" (jako Global)

var str = 'test test test test';
str = str.replace(/test/g, 'abc');
alert(str);

Ovšem pokud máme hledaný string v proměnné (nikoliv zapsaný v kódu) tak se nám situace již komplikuje:

var str = 'test test test test';
var find = 'test';
var re = new RegExp(find, 'g');
str = str.replace(re, 'abc');
alert(str);

A hlavně toto je chybně, protože je potřeba ošetřit to, že RegExp reaguje na řídící znaky a tyto znaky escapovat. Ovšem JS nemá žádnou funkci na escapování znaků v RegExp a proto si jí musíme napsat sami.


Správně tedy je:

var str = 'test test test test';
var find = 'test';
var re = new RegExp(find.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$&"), 'g');
str = str.replace(re, 'abc');
alert(str);

A pokud to chceme to nahrazení napsat rychle na jeden řádek tak dostaneme něco takového:

var str = 'test test test test';
var find = 'test';
str = str.replace(new RegExp(find.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$&"), 'g'), 'abc');
alert(str);

No, né každý to rychle z hlavy dá...


A teď přijde trik :-) jak to napsat mnohem rychleji.
Pokud zadáme do .split string tak se samozřejmě aplikuje na všechny výskyty. A toho lze využít - rozložíme to do pole a hned zase složíme:

var str = 'test test test test';
var find = 'test';
str = str.split(find).join('abc');
alert(str);

Samozřejmě může následovat diskuze o výkonu v různých prohlížečích, ale je to celkem OK.

Komentáře

  • Anonym : Bez ohľadu na výkon @rmaslo je toto VÝBORNÝ NÁPAD :) 3.12.2017
  • Kit : Místo 'test' ve stringu můžeš injektovat new RegExp('test', 'g'); a nemusíš pak řešit escapování. 3.12.2017
  • rmaslo : @Kit: No pokud bych chtěl nahradit třeba string '$test' tak to někde oescapovat musím. A pokud nevím co mi v té proměnné find přijde tak musím oescapovat všechny řídící znaky... 3.12.2017
  • rmaslo : @vladislav.ladicky: jj. tak nějak jsem tušil, že toto se bude líbit :-) 3.12.2017
  • Anonym : @rmaslo o to viac sa mi to páči, že som presne toto riešil minulý týždeň a vyriešil to práve escapovaním :) pozri si demo.3w.sk kde je to este neopravené a skús hľadať telefónne číslo vrátane + na začiatku a pozri do konzoly ako sa to zrúti :) Ako som povedal, už to mám opravené, ale práve tým escapovaním a vôbec sa mi to nepáči, takže este dnes si do kódu zaimplementujem práve tento trik :) 3.12.2017
  • Kit : Pokud je ten 'test' konstantou v programu, tak ho escapuji ručně, např: var re = new RegExp('\\$test', 'g'); nebo rovnou var re = /\$test/g; Pokud převádím regexp z cizího stringu, tak je escapování samozřejmě nutné. 3.12.2017
  • Kit : @vladislav.ladicky: Inlajnování se mi v poslední době zhnusilo. Místo ...,new RegExp("\\b"+"delete,typeof,void".split(",").join("\\s*\\([^\\)]*\\)|\\b")+"\\s*\\([^\\)]*\\)"),... bych to raději rozdělil na 2 řádky: var funkceRe = /\bdelete\s*\([^\)]*\)|\btypeof\s*\([^\)]*\)|\bvoid\s*\([^\)]*\)/; ...,funkceRe,... 3.12.2017
  • rmaslo : @Kit: jj. myslel jsem nahrazení třeba uživatelem zadaného stringu. Složitější patterny v RegExp taky nerad inlinuju, protože si k nim radši dělám poznámky. Pokud bych to měl dělat přes RegExp asi by to vedlo na nějakou zvláštní funkci replaceAll. Ale s tím split a join to klidně napíšu přímo - podle mě je na první pohled vidět co to dělá a není k tomu potřeba nic psát. 3.12.2017

Pro zobrazení všech 20 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.