javascript

javascript

Write modern JavaScript/ES6+ code following best practices for performance, security, and maintainability. Use when writing JS code, fixing bugs, or implementing frontend functionality.

3étoiles
0forks
Mis à jour 1/19/2026
SKILL.md
readonlyread-only
name
javascript
description

Write modern JavaScript/ES6+ code following best practices for performance, security, and maintainability. Use when writing JS code, fixing bugs, or implementing frontend functionality.

JavaScript Skill

Instructions

When writing JavaScript:

1. Modern Syntax

// Use const by default, let when needed
const API_URL = 'https://api.example.com';
let count = 0;

// Arrow functions
const add = (a, b) => a + b;
const greet = name => `Hello, ${name}!`;

// Destructuring
const { name, email } = user;
const [first, second, ...rest] = items;

// Spread operator
const newArray = [...oldArray, newItem];
const newObject = { ...oldObject, newProp: value };

// Template literals
const message = `User ${name} has ${count} items`;

// Optional chaining
const city = user?.address?.city;

// Nullish coalescing
const value = input ?? defaultValue;

2. Async/Await

// Async function
async function fetchData(url) {
  try {
    const response = await fetch(url);

    if (!response.ok) {
      throw new Error(`HTTP error: ${response.status}`);
    }

    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Fetch failed:', error);
    throw error;
  }
}

// Parallel requests
async function fetchAll(urls) {
  const promises = urls.map(url => fetch(url));
  const responses = await Promise.all(promises);
  return Promise.all(responses.map(r => r.json()));
}

// With timeout
async function fetchWithTimeout(url, timeout = 5000) {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  try {
    const response = await fetch(url, { signal: controller.signal });
    return await response.json();
  } finally {
    clearTimeout(timeoutId);
  }
}

3. Array Methods

const users = [
  { id: 1, name: 'Alice', age: 25, active: true },
  { id: 2, name: 'Bob', age: 30, active: false },
  { id: 3, name: 'Charlie', age: 35, active: true },
];

// map - transform items
const names = users.map(user => user.name);

// filter - select items
const activeUsers = users.filter(user => user.active);

// find - get first match
const bob = users.find(user => user.name === 'Bob');

// some/every - check conditions
const hasActive = users.some(user => user.active);
const allActive = users.every(user => user.active);

// reduce - aggregate
const totalAge = users.reduce((sum, user) => sum + user.age, 0);

// Chaining
const activeNames = users
  .filter(user => user.active)
  .map(user => user.name)
  .sort();

4. DOM Manipulation

// Selecting elements
const element = document.querySelector('.class');
const elements = document.querySelectorAll('.class');

// Creating elements
const div = document.createElement('div');
div.className = 'card';
div.innerHTML = `
  <h2>${title}</h2>
  <p>${description}</p>
`;

// Event handling
element.addEventListener('click', (event) => {
  event.preventDefault();
  // Handle click
});

// Event delegation
document.querySelector('.list').addEventListener('click', (event) => {
  if (event.target.matches('.item')) {
    handleItemClick(event.target);
  }
});

// IntersectionObserver (lazy loading, animations)
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add('visible');
      observer.unobserve(entry.target);
    }
  });
}, { threshold: 0.1 });

document.querySelectorAll('.animate').forEach(el => observer.observe(el));

5. Classes

class User {
  #privateField; // Private field

  constructor(name, email) {
    this.name = name;
    this.email = email;
    this.#privateField = 'secret';
  }

  // Getter
  get displayName() {
    return this.name.toUpperCase();
  }

  // Setter
  set displayName(value) {
    this.name = value.trim();
  }

  // Method
  greet() {
    return `Hello, I'm ${this.name}`;
  }

  // Static method
  static create(data) {
    return new User(data.name, data.email);
  }
}

// Inheritance
class Admin extends User {
  constructor(name, email, role) {
    super(name, email);
    this.role = role;
  }

  greet() {
    return `${super.greet()} and I'm an ${this.role}`;
  }
}

6. Modules

// Named exports
export const API_URL = 'https://api.example.com';
export function fetchData() { /* ... */ }
export class User { /* ... */ }

// Default export
export default function main() { /* ... */ }

// Importing
import main, { API_URL, fetchData, User } from './module.js';

// Dynamic import
const module = await import('./heavy-module.js');

7. Error Handling

// Custom error
class ValidationError extends Error {
  constructor(message, field) {
    super(message);
    this.name = 'ValidationError';
    this.field = field;
  }
}

// Try-catch with specific handling
try {
  await submitForm(data);
} catch (error) {
  if (error instanceof ValidationError) {
    showFieldError(error.field, error.message);
  } else if (error instanceof NetworkError) {
    showToast('Network error. Please try again.');
  } else {
    console.error('Unexpected error:', error);
    showToast('Something went wrong.');
  }
}

8. Local Storage

// Store data
const saveData = (key, data) => {
  localStorage.setItem(key, JSON.stringify(data));
};

// Retrieve data
const getData = (key, defaultValue = null) => {
  const stored = localStorage.getItem(key);
  return stored ? JSON.parse(stored) : defaultValue;
};

// Remove data
const removeData = (key) => {
  localStorage.removeItem(key);
};

9. Debounce & Throttle

// Debounce - wait until stopped
function debounce(func, delay) {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func(...args), delay);
  };
}

const debouncedSearch = debounce((query) => {
  fetchResults(query);
}, 300);

// Throttle - limit frequency
function throttle(func, limit) {
  let inThrottle;
  return (...args) => {
    if (!inThrottle) {
      func(...args);
      inThrottle = true;
      setTimeout(() => inThrottle = false, limit);
    }
  };
}

const throttledScroll = throttle(() => {
  updatePosition();
}, 100);

10. Best Practices

  • Use const by default
  • Prefer arrow functions
  • Use async/await over callbacks
  • Handle all errors
  • Avoid global variables
  • Use meaningful variable names
  • Keep functions small and focused
  • Comment complex logic
  • Use strict equality (===)
  • Validate user input

WordPress-Specific JavaScript

11. Enqueueing Scripts Properly

function theme_enqueue_scripts() {
    // Frontend script
    wp_enqueue_script(
        'theme-main',
        get_template_directory_uri() . '/assets/js/main.js',
        array(), // dependencies
        '1.0.0',
        true // in footer
    );

    // With jQuery dependency
    wp_enqueue_script(
        'theme-jquery-script',
        get_template_directory_uri() . '/assets/js/custom.js',
        array('jquery'),
        '1.0.0',
        true
    );

    // Pass PHP data to JavaScript
    wp_localize_script('theme-main', 'themeData', array(
        'ajaxUrl' => admin_url('admin-ajax.php'),
        'restUrl' => rest_url('theme/v1/'),
        'nonce'   => wp_create_nonce('theme_nonce'),
        'i18n'    => array(
            'loading' => __('Loading...', 'theme'),
            'error'   => __('An error occurred', 'theme'),
        ),
    ));
}
add_action('wp_enqueue_scripts', 'theme_enqueue_scripts');

12. AJAX with admin-ajax.php

// Frontend JavaScript
async function submitForm(formData) {
    const data = new FormData();
    data.append('action', 'theme_submit_form');
    data.append('nonce', themeData.nonce);
    data.append('name', formData.name);
    data.append('email', formData.email);

    try {
        const response = await fetch(themeData.ajaxUrl, {
            method: 'POST',
            body: data,
            credentials: 'same-origin',
        });

        const result = await response.json();

        if (result.success) {
            return result.data;
        } else {
            throw new Error(result.data.message || 'Request failed');
        }
    } catch (error) {
        console.error('AJAX Error:', error);
        throw error;
    }
}
// PHP handler
add_action('wp_ajax_theme_submit_form', 'theme_handle_form');
add_action('wp_ajax_nopriv_theme_submit_form', 'theme_handle_form');

function theme_handle_form() {
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'], 'theme_nonce')) {
        wp_send_json_error(array('message' => 'Invalid nonce'));
    }

    // Sanitize input
    $name = sanitize_text_field($_POST['name']);
    $email = sanitize_email($_POST['email']);

    // Process...

    wp_send_json_success(array('message' => 'Form submitted'));
}

13. REST API Requests

// GET request
async function getPosts() {
    const response = await fetch(`${themeData.restUrl}posts`, {
        headers: {
            'X-WP-Nonce': themeData.nonce,
        },
    });
    return response.json();
}

// POST request
async function createPost(data) {
    const response = await fetch(`${themeData.restUrl}posts`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-WP-Nonce': themeData.nonce,
        },
        body: JSON.stringify(data),
    });
    return response.json();
}

// Using wp.apiFetch (Gutenberg)
wp.apiFetch({ path: '/wp/v2/posts' }).then(posts => {
    console.log(posts);
});

14. jQuery Compatibility

// WordPress jQuery no-conflict wrapper
(function($) {
    $(document).ready(function() {
        // Your jQuery code here
        $('.element').on('click', function() {
            $(this).toggleClass('active');
        });
    });
})(jQuery);

// Or with modern syntax
jQuery(($) => {
    $('.element').on('click', function() {
        $(this).toggleClass('active');
    });
});

15. Gutenberg/Block Editor JavaScript

// Using wp.data for state
const { select, dispatch } = wp.data;

// Get current post
const post = select('core/editor').getCurrentPost();

// Get blocks
const blocks = select('core/block-editor').getBlocks();

// Using wp.hooks for filters
wp.hooks.addFilter(
    'blocks.registerBlockType',
    'theme/modify-block',
    (settings, name) => {
        if (name === 'core/paragraph') {
            settings.attributes.customAttr = {
                type: 'string',
                default: '',
            };
        }
        return settings;
    }
);

// Using wp.i18n for translations
const { __, _n, sprintf } = wp.i18n;
const message = __('Hello World', 'theme');
const items = sprintf(_n('%d item', '%d items', count, 'theme'), count);

16. WordPress JavaScript Best Practices

  • Always use nonces for security in AJAX/REST requests
  • Use wp_localize_script() to pass data from PHP to JS
  • Wrap jQuery code in no-conflict wrapper
  • Prefer REST API over admin-ajax for new projects
  • Use wp.apiFetch in Gutenberg context
  • Namespace your code to avoid conflicts
  • Load scripts in footer when possible (true as last param)
  • Use dependencies array correctly (e.g., array('jquery', 'wp-element'))
  • Handle errors gracefully with user-friendly messages
  • Test in both frontend and admin contexts

You Might Also Like

Related Skills

coding-agent

coding-agent

179Kdev-codegen

Run Codex CLI, Claude Code, OpenCode, or Pi Coding Agent via background process for programmatic control.

openclaw avataropenclaw
Obtenir
add-uint-support

add-uint-support

97Kdev-codegen

Add unsigned integer (uint) type support to PyTorch operators by updating AT_DISPATCH macros. Use when adding support for uint16, uint32, uint64 types to operators, kernels, or when user mentions enabling unsigned types, barebones unsigned types, or uint support.

pytorch avatarpytorch
Obtenir
at-dispatch-v2

at-dispatch-v2

97Kdev-codegen

Convert PyTorch AT_DISPATCH macros to AT_DISPATCH_V2 format in ATen C++ code. Use when porting AT_DISPATCH_ALL_TYPES_AND*, AT_DISPATCH_FLOATING_TYPES*, or other dispatch macros to the new v2 API. For ATen kernel files, CUDA kernels, and native operator implementations.

pytorch avatarpytorch
Obtenir
skill-writer

skill-writer

97Kdev-codegen

Guide users through creating Agent Skills for Claude Code. Use when the user wants to create, write, author, or design a new Skill, or needs help with SKILL.md files, frontmatter, or skill structure.

pytorch avatarpytorch
Obtenir

Implements JavaScript classes in C++ using JavaScriptCore. Use when creating new JS classes with C++ bindings, prototypes, or constructors.

oven-sh avataroven-sh
Obtenir

Creates JavaScript classes using Bun's Zig bindings generator (.classes.ts). Use when implementing new JS APIs in Zig with JSC integration.

oven-sh avataroven-sh
Obtenir