Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
December 1, 2020 11:45 am GMT

A few handy JavaScript tricks

I'd like to document a few neat JavaScript tricks and patterns I've recently learnt from Twitter and other online resources (which I sadly haven't kept track of). All the credits go to the online JavaScript community.

Invoking an IIFE (Immediately Invoked Function Expression) without extra brackets

We can use the void operator for that, where void clearly indicates we want to discard the result of an expression (which an IIFE itself is):

void function debug() {  if (confirm('stop?')) debugger;}(); 
Enter fullscreen mode Exit fullscreen mode

I believe it's more readable and mnemonic than wrapping the function with brackets:

(function debug() {  if (confirm('stop?')) debugger;})();
Enter fullscreen mode Exit fullscreen mode

If we do need the result:

const rgb = function getColor(color) {  return {     red: '#FF0000',    green: '#00FF00',    blue: '#0000FF'  }[color];}(car.color); 
Enter fullscreen mode Exit fullscreen mode

Invoking an async IIFE (Immediately Invoked Function Expression)

Similarly to the above, we don't need the wrapping brackets:

await async function delay() {  const start = performance.now();  await new Promise(r => setTimeout(r, 1000));  console.log(`elapsed: ${performance.now() - start}`);}();
Enter fullscreen mode Exit fullscreen mode

Destructuring of a function argument inline:

function output ({firstName, lastName}) {  console.log(firstName, lastName);}const person = {  firstName: 'Jane',  lastName: 'Doe'};output(person);
Enter fullscreen mode Exit fullscreen mode

Partial destructuring of a function argument inline:

function output ({firstName, ...rest}) {  console.log(firstName, rest.lastName, rest.age);}const person = {  firstName: 'John',  lastName: 'Doe',  age: 33};output(person);
Enter fullscreen mode Exit fullscreen mode

Using expressions in switch

const category = function getCategory(temp) {  // the first `case` which expression is `true` wins  switch(true) {    case temp < 0: return 'freezing';    case temp < 10: return 'cold';    case temp < 24: return 'cool';    default: 'unknown';  }}(10);
Enter fullscreen mode Exit fullscreen mode

Passing a non-function object as event handler to addEventListener

The trick is to implement EventListener.handleEvent:

const listener = Object.freeze({  state: { message: 'Hello' },  handleEvent: event => {    alert(`${event.type} : ${listener.state.message}`);  }});button.addEventListener('click', listener); 
Enter fullscreen mode Exit fullscreen mode

Checking if an object is String (Number, Boolean, Object)

Could you predict which console output is common for s1 and s2 snippets below? I myself couldn't, so I've made it a runnable RunKit:

const s1 = 's'; log('s1 instanceof String');log('typeof s1');log('s1.constructor === String');const s2 = new String('s'); log('s2 instanceof String');log('typeof s2');log('s2.constructor === String');function log(code) { console.log(`${code}: ${eval(code)}`); }

Interestingly, it's s1.constructor === String and s2.constructor === String, both are true. It's even more fun with TypeScript, and it may feel odd for a person coming to JavaScript with C# or Java background.

So, to check if variable s represents a string, the following works consistently for primitive values and their wrapping class types:

const isString = s.constructor === String;
Enter fullscreen mode Exit fullscreen mode

We can also make it work across realms (an iframe or a popup):

const isString = s.constructor.name === 'String';
Enter fullscreen mode Exit fullscreen mode

A mnemonic way of ignoring promise errors (where applicable):

await promise.catch(e => void e); 
Enter fullscreen mode Exit fullscreen mode

This literally says: "void that error" and it's ESLint-friedly. I see it becoming increasingly useful, to avoid potential troubles with unhandled promise rejections in Node v15+. For example:

// f1 has to start before f2const promise1 = f1();const promise2 = f2();// we need promise2 results first and// we don't care about promise1 results if promise2 fails,// so let's prevent unwanted unhandledrejection for promise1promise1.catch(e => void e); // observe promise2 resultsawait promise2; // now observe promise1 results, after promise2await promise1;
Enter fullscreen mode Exit fullscreen mode

Thenables can be useful side-by-side with promises

I've previously blogged about thenables. In a nutshell:

function createDeferred() {  let resolve, reject;  const promise = new Promise((...args) =>     [resolve, reject] = args);  return Object.freeze({    resolve,     reject,    then: promise.then.bind(promise)  });}const deferred = createDeferred();// resolve the deferred in 2s setTimeout(deferred.resolve, 2000);await deferred;
Enter fullscreen mode Exit fullscreen mode

Tell which promise settles first in Promise.race

Sometimes we need to know which promise became resolved or rejected first and thus won the race with Promise.race, similarly to Task.WhenAny in .NET. Linking my SO answer:

/** * When any promise is resolved or rejected,  * returns that promise as the result. * @param  {Iterable.<Promise>} iterablePromises An iterable of promises. * @return {{winner: Promise}} The winner promise. */async function whenAny(iterablePromises) {  let winner;  await Promise.race(function* getRacers() {    for (const p of iterablePromises) {      if (!p?.then) throw new TypeError();      const settle = () => winner = winner ?? p;      yield p.then(settle, settle);    }  }());  // return the winner promise as an object property,   // to prevent automatic promise "unwrapping"  return { winner }; }
Enter fullscreen mode Exit fullscreen mode

Hope this is useful

I'll be updating this post as I learn more. Follow me on Twitter if interested in these updates.


Original Link: https://dev.to/noseratio/a-few-handy-javascript-tricks-an9

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To