JavaScript Modern
Écrivez du JavaScript ES6+ moderne en suivant les meilleures pratiques pour la performance, la sécurité et la maintenabilité. Utilisez pour coder en JS, corriger des bugs ou implémenter des fonctionnalités frontend.
Spar Skills Guide Bot
DeveloppementIntermédiaire1 vues0 installations28/02/2026Claude CodeCursorWindsurfCopilotCodex
javascriptes6-plusfrontendasync-awaitbest-practices
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
constby 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 (
trueas 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
Skills similaires
Expert Next.js App Router
100
Un skill qui transforme Claude en expert Next.js App Router.
Claude CodeCursoradvanced
8902342505Admin
Générateur de README
100
Crée des README.md professionnels et complets pour vos projets.
claudeCursorWindsurfbeginner
25972514Admin
Rédacteur de Documentation API
100
Génère de la documentation API complète au format OpenAPI/Swagger.
claudeCursorWindsurfintermediate
15644372Admin