/ Gists / JavaScript

Gists - JavaScript

On gists

Javascript Safe Assignment Operator (?=)

JavaScript

examples.js #

// https://devsmitra.medium.com/javascript-error-handling-just-got-a-whole-lot-easier-meet-the-safe-assignment-operator-c372d892d4ed

// without
async function getData() {
  try {
    const response = await fetch("https://api.example.com/data");
    const json = await response.json();
    return validationSchema.parse(json);
  } catch (error) {
    handleError(error);
  }
}


// with
async function getData() {
  const [fetchError, response]?= await fetch("https://api.example.com/data");
  if (fetchError) return handleFetchError(fetchError);

  const [jsonError, json]?= await response.json();
  if (jsonError) return handleJsonError(jsonError);

  const [validationError, data]?= validationSchema.parse(json);
  if (validationError) return handleValidationError(validationError);

  return data;
}

On gists

toString()

JavaScript

index.js #

// https://medium.com/@asierr/javascripts-function-prototype-tostring-just-got-useful-here-s-how-bc617fd7222c

function greet(name) {
  return `Hello, ${name}`;
}

console.log(greet.toString());

// result
"function greet(name) {\n  return `Hello, ${name}`;\n}"



// any usage
const fn = x => x * 2;
const body = fn.toString();

if (body.includes('x * 2')) {
  console.log('Safe to optimize!');
}


/*
Limitations
Doesn’t work on native functions (e.g., Math.max.toString() returns "function max() { [native code] }")
Some minifiers may still mangle formatting
Not recommended for secure comparisons (function source can be identical but semantically different)
*/

On gists

JS Proxy - real usecases

JavaScript

proxy.js #

// https://javascript.plainenglish.io/the-battle-of-isolation-proxy-vs-web-workers-vs-iframe-in-frontend-development-%EF%B8%8F-3eaeef99a11d

// 1 
const sandbox = new Proxy(window, {
  get(target, key) {
    if (key === 'document') {
      throw new Error('No access to DOM!');
    }
    return Reflect.get(target, key);
  },
  set(target, key, value) {
    if (key === 'location') return false;
    return Reflect.set(target, key, value);
  }
});

// Running plugin code in sandbox
(function(window) {
  try {
    window.document.title = 'Hacked!'; // Triggers exception
  } catch (err) {
    console.error('Illegal operation intercepted:', err);
  }
})(sandbox);



// 2
const audit = new Proxy(console, {
  get(target, key) {
    if (key === 'log') return (...args) => {
      recordLog(args); // Log recording
      target[key](...args);
    };
    return target[key];
  }
});

sandbox.console = audit;

On gists

Promises

JavaScript

promises.js #

// https://medium.com/@hxu0407/master-these-8-promise-concurrency-control-techniques-to-significantly-improve-performance-5a1c199b6b3c


// 1. Promise.all: Execute in Parallel and Return Results Together
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3])
  .then(results => {
    console.log(results); // Output: [1, 2, 3]
  });
  
  
  
  
// 2. Promise.allSettled: Execute in Parallel and Return All States
const promise1 = Promise.resolve(1);
const promise2 = Promise.reject("Error");
const promise3 = Promise.resolve(3);
Promise.allSettled([promise1, promise2, promise3])
  .then(results => {
    console.log(results);
    /* Output:
    [
      { status: 'fulfilled', value: 1 },
      { status: 'rejected', reason: 'Error' },
      { status: 'fulfilled', value: 3 }
    ]
    */
  })
  
  
  
  
// 3. Promise.race: Execute in Parallel and Return the Fastest
const promise1 = new Promise(resolve => setTimeout(() => resolve("Fast"), 100));
const promise2 = new Promise(resolve => setTimeout(() => resolve("Slow"), 500));
Promise.race([promise1, promise2])
  .then(result => console.log(result)); // Output: "Fast" (whichever resolves first)
  
  
  
  
// 4. Promise.any (ES2021): Execute in Parallel and Return the First Fulfilled
const promise1 = Promise.reject("Error 1");
const promise2 = new Promise(resolve => setTimeout(() => resolve("Success"), 200));
const promise3 = Promise.reject("Error 2");
Promise.any([promise1, promise2, promise3])
  .then(result => console.log(result)) // Output: "Success"
  .catch(error => console.log(error.errors)); // If all reject
  
  
  
  
// 5. Custom Concurrency Control Function: Limit Max Concurrent Requests
async function limitConcurrency(tasks, limit) {
  const results = [];
  const running = new Set();
  
  for (const task of tasks) {
    const promise = task().then(result => {
        running.delete(promise);
        return result;
    });
    running.add(promise);
        results.push(promise);
        if (running.size >= limit) {
          await Promise.race(running);
        }
      }
  return Promise.all(results);

On gists

9 Smart Ways to Replace if-else in JavaScript

Popular ⭐ JavaScript

ways.js #

// https://medium.com/@hxu0407/9-smart-ways-to-replace-if-else-in-javascript-28f82ad6dcb9

// 1. Object Mapping Instead of if-else
function getPrice(user) {
  if (user.type === 'vip') {
    return 'VIP Price';
  } else if (user.type === 'svip') {
    return 'SVIP Price';
  } else if (user.type === 'vvip') {
    return 'VVIP Price';
  } else {
    return 'Regular Price';
  }
}

// better
const priceStrategy = {
  vip: () => 'VIP Price',
  svip: () => 'SVIP Price',
  vvip: () => 'VVIP Price',
  default: () => 'Regular Price'
};

function getPrice(user) {
  return (priceStrategy[user.type] || priceStrategy.default)();
}



// 2. Replace Multiple Conditions with Array.includes
if (status === 'failed' || status === 'error' || status === 'rejected') {
  handleError();
}

// better
const errorStatus = ['failed', 'error', 'rejected'];
if (errorStatus.includes(status)) {
  handleError();
}



// 3. Chained Ternary Operators
let message;
if (score >= 90) {
  message = 'Excellent';
} else if (score >= 80) {
  message = 'Good';
} else if (score >= 60) {
  message = 'Pass';
} else {
  message = 'Fail';
}

// better 
const message =
  score >= 90 ? 'Excellent' :
  score >= 80 ? 'Good' :
  score >= 60 ? 'Pass' :
  'Fail';
  
  
  
// 4. Logical Operators && and ||
// Replacing a simple `if`
user.isAdmin && showAdminPanel();
// Setting default values
const name = user.name || 'unnamed';
// Nullish coalescing
const count = data?.users ?? [];



// 5. Switch-Case with Pattern Matching
const actions = new Map([
  [/^vip/, handleVip],
  [/^admin/, handleAdmin],
  [/^user/, handleUser]
]);

/*or

const actions = [
  [/^vip/, handleVip],
  [/^admin/, handleAdmin],
  [/^user/, handleUser]
];
*/

const handleRequest = (type) => {
  const action = [...actions].find(([key]) => key.test(type));
  return action ? action[1]() : handleDefault();
};



// 6. Using Proxy for Conditional Interception
const handler = {
  get: (target, property) => {
    return property in target ? target[property] : target.default;
  }
};

const services = new Proxy({
  admin: () => 'Admin Service',
  user: () => 'User Service',
  default: () => 'Default Service'
}, handler);



// 7. Functional Approach
// Composing conditions
const isAdult = age => age >= 18;
const hasPermission = role => ['admin', 'superuser'].includes(role);
const canAccess = user => isAdult(user.age) && hasPermission(user.role);

// Usage
users.filter(canAccess).forEach(grantAccess);



// 8. State Machine Pattern
const stateMachine = {
  draft: {
    publish: 'published',
    delete: 'deleted'
  },
  published: {
    unpublish: 'draft',
    archive: 'archived'
  },
  archived: {
    restore: 'draft'
  }
};

const changeState = (currentState, action) =>
  stateMachine[currentState]?.[action] || currentState;
  
  
  
// 9. Use Decorators to Handle Conditional Logic
function checkPermission(target, name, descriptor) {
  const original = descriptor.value;
  descriptor.value = function (...args) {
    if (this.user?.hasPermission) {
      return original.apply(this, args);
    }
    throw new Error('No permission');
  };
  return descriptor;
}

class Document {
  @checkPermission
  edit() {
    // Edit the document
  }
}


On gists

Inefficient DOM Manipulations

JavaScript

demo.js #

/*
Why It’s a Problem:
Direct DOM manipulation triggers reflows and repaints, slowing down rendering.
Inserting elements one by one instead of batching updates increases the number of re-renders.
Modifying styles directly forces layout recalculations.
*/

// BAD: Multiple reflows
for (let i = 0; i < 1000; i++) {
    const div = document.createElement('div');
    div.textContent = `Item ${i}`;
    document.body.appendChild(div);
}

// GOOD: Batch updates using DocumentFragment
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
    const div = document.createElement('div');
    div.textContent = `Item ${i}`;
    fragment.appendChild(div);
}
document.body.appendChild(fragment);

On gists

Dynamic imports

JavaScript ES 6

examples.md #

Výhody dynamických importů v JavaScriptu

Výhody dynamických importů

  1. Code splitting (rozdělení kódu)

Místo načtení celé aplikace najednou můžeš načítat moduly až když jsou potřeba:

// Běžný statický import
import { heavyFunction } from './heavyModule.js';

// Dynamický import - načte se jen když je potřeba
button.addEventListener('click', async () => {
  const { heavyFunction } = await import('./heavyModule.js');
  heavyFunction();
});
  1. Podmíněné načítání

Můžeš načítat moduly jen za určitých podmínek:

async function loadFeature(featureName) {
  if (featureName === 'chart') {
    const { createChart } = await import('./chartModule.js');
    createChart();
  } else if (featureName === 'table') {
    const { createTable } = await import('./tableModule.js');
    createTable();
  }
}
  1. Lazy loading (líné načítání) komponent v Nuxt/Vue
// Místo tohoto statického importu
import HeavyComponent from '@/components/HeavyComponent.vue';

// Můžeš použít dynamický import
const HeavyComponent = defineAsyncComponent(() => 
  import('@/components/HeavyComponent.vue')
);
  1. Lepší výkon první načtení stránky

Zmenšíš hlavní bundle a zrychlíš tak první vykreslení:

// V Nuxt 3 můžeš dynamicky importovat i stránky
const routes = [
  {
    path: '/',
    component: () => import('./Home.vue')
  },
  {
    path: '/dashboard',
    component: () => import('./Dashboard.vue') // Načte se až při navigaci
  }
]
  1. Práce s různými formáty souborů
async function loadConfigBasedOnEnvironment() {
  if (process.env.NODE_ENV === 'development') {
    return import('./config.dev.json');
  } else {
    return import('./config.prod.json');
  }
}
  1. Lepší cachování v prohlížeči

Když změníš jeden modul, prohlížeč může znovu stáhnout jen tento modul, ne celý bundle.

  1. Vyhnutí se problémům s cyklickými závislostmi

Dynamické importy mohou někdy pomoct vyřešit cyklické závislosti:

// moduleA.js
export function funcA() {
  console.log('Function A');
}

export async function funcThatUsesB() {
  const moduleB = await import('./moduleB.js');
  moduleB.funcB();
}

// moduleB.js
import { funcA } from './moduleA.js';

export function funcB() {
  console.log('Function B calls:');
  funcA();
}

On gists

Delay in JS

JavaScript

sleep.js #

// 1
await new Promise(resolve => setTimeout(resolve, 1000)); // wait for 1 sec


// 2
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
   
   
   

On gists

Better Vue components with TS

JavaScript Typescript Vue.js

better-vue-with-components.vue #

<!-- 1. PROPS  -->

<!-- JS -->
<script setup>
import { defineProps } from 'vue';

const props = defineProps({
  foo: { type: String, required: true },
  bar: Number,
});

// props.foo is a string
// props.bar is a number or undefined
</script>


<!-- TS -->
<script setup lang="ts">
const props = defineProps<{
  foo: string;
  bar?: number;
}>()
</script>


<script setup lang="ts">
interface Props {
  foo: string;
  bar?: number;
}

const props = defineProps<Props>()
</script>



<!-- 2. EMITS  -->
<!-- JS -->
<script setup>
const emit = defineEmits(['change', 'update'])
</script>

 <!-- TS -->
 <script setup lang="ts">
const emit = defineEmits<{
  change: [id: number]
  update: [value: string]
}>()
</script>



<!-- 3. Typing Ref and Reactive Data => Inference -->
<script setup>
import { ref } from 'vue';

const count = ref(0); 
count.value = 'string';  // error, inference, we expect number
</script>


<!-- 4. Typing Server Responses -->
<script setup lang="ts">
import { ref, onMounted } from 'vue';

interface User {
  id: number;
  name: string;
  email: string;
}

const userData = ref<User | null>(null);

onMounted(async () => {
  const response = await fetch('https://api.example.com/user');
  const data: User = await response.json();
  userData.value = data; // TypeScript ensures data usages match the User interface
});
</script>


<!-- 5. Typing Computed Data -->
import { ref, computed } from 'vue'

const count = ref(0)
// inferred type: ComputedRef<number>
const double = computed(() => count.value * 2)
// => TS Error: Property 'split' does not exist on type 'number'
const result = double.value.split('')

// or explicitely define return type
const double = computed<number>(() => {
  // type error if this doesn't return a number
})



<!-- 6. Typing Scoped Slots-->
<template>
  <slot :msg="message"></slot>
</template>

<script setup lang="ts">
const message = 'Hello, Vue!';

const slots = defineSlots<{
  default: (props: { msg: string }) => any;
}>()
</script>


<!-- 7. Typing Template Refs -->
<script setup lang="ts">
import { useTemplateRef, onMounted } from 'vue';

const myInput = useTemplateRef('my-input');

onMounted(() => {
  myInput.value?.focus(); 
});
</script>

<template>
  <input ref="my-input" />
</template>



<!-- 8. Typing Provide/Inject -->
<!-- ParentComponent.vue -->
<script setup lang="ts">
import { provide } from 'vue';

const theme = 'dark';
provide('theme', theme);
</script>

<!-- ChildComponent.vue -->
<script setup lang="ts">
import { inject } from 'vue';

const theme = inject<string>('theme'); // Inject with expected type
// TypeScript ensures that 'theme' is of type string
</script>


<!-- 9. Generics -->
<script setup lang="ts" generic="T">
defineProps<{
  items: T[];      // Array of items of type T
  selected: T;     // Single selected item of type T
}>()
</script>


<!-- 10. Typed Composables -->
// useUser.ts
import { ref } from 'vue';

interface User {
  id: number;
  name: string;
  age: number;
}

export function useUser() {
  const user = ref<User | null>(null);

  function fetchUser(id: number) {
    // Fetching user logic
    user.value = { id, name: 'John Doe', age: 30 };
  }

  return { user, fetchUser };
}

On gists

Async/Await Tricks

JavaScript

index.js #

/*
@url https://levelup.gitconnected.com/7-simple-async-await-tricks-for-developers-who-hate-asynchronous-javascript-fe370ac7fe72
*/

// 1. Use Promise.allSettled() for Safer Batch Processing
const results = await Promise.allSettled([
  fetchData1(),
  fetchData2(),
  fetchData3(),
]);
results.forEach(result => {
  if (result.status === 'fulfilled') {
    console.log('Success:', result.value);
  } else {
    console.error('Failed:', result.reason);
  }
});


// 2. Use Timeouts to Prevent Hanging Promises
const withTimeout = (promise, ms) =>
  Promise.race([
    promise,
    new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), ms)),
  ]);

try {
  const data = await withTimeout(fetchData(), 5000);
} catch (err) {
  console.error(err.message); // "Timeout" if it takes too long
}


// 3. Sequential Loops with Async/Await
const urls = ['url1', 'url2', 'url3'];
for (const url of urls) {
  const data = await fetch(url);
  console.log(data);
}


// 4. Dynamic Delays with await
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
console.log('Start');
await delay(2000); // Waits 2 seconds
console.log('End');


// 5. Always Use try...catch Inside Async Functions
async function fetchData(url) {
  try {
    const response = await fetch(url);
    if (!response.ok) throw new Error('Fetch failed');
    return await response.json();
  } catch (err) {
    console.error('Error:', err.message);
    return null;
  }
}


// 6. await Outside Loops to Batch Workloads
const urls = ['url1', 'url2', 'url3'];
const responses = await Promise.all(urls.map(url => fetch(url)));
const data = await Promise.all(responses.map(res => res.json()));
console.log(data);


// 7 ... fking yield => dont care