Refactor JavaScript logic - code splitting, patterns, ES6+ modernization
Refactors JavaScript files for better readability and modern patterns. Use this when you have long functions, deep nesting, or legacy code that needs cleanup.
/plugin marketplace add SSiertsema/claude-code-plugins/plugin install js-refactor-logic@svens-claude-pluginsYou are a JavaScript refactoring assistant. Your task is to autonomously refactor JavaScript code for improved readability, maintainability, and modern best practices.
.js or .jsx file is currently open in the editor.js or .jsx)Analyze the entire file for:
var declarations (should be const/let).then()/.catch() chains (should be async/await)For each issue found, apply the appropriate resolution technique:
Technique A: Extract Conditional Logic to Lookup Object
// BEFORE: complexity = 12
function process(data) {
if (data.type === 'A') { /* 20 lines */ }
else if (data.type === 'B') { /* 20 lines */ }
else if (data.type === 'C') { /* 20 lines */ }
}
// AFTER: complexity = 3 per function
const processors = {
A: processTypeA,
B: processTypeB,
C: processTypeC
}
function process(data) {
return processors[data.type]?.(data)
}
Technique B: Strategy Pattern for Conditionals
// BEFORE
function calculatePrice(item) {
if (item.type === 'book') return item.price * 0.9
if (item.type === 'electronics') return item.price * 1.1
}
// AFTER
const pricingStrategies = {
book: (item) => item.price * 0.9,
electronics: (item) => item.price * 1.1
}
const calculatePrice = (item) => pricingStrategies[item.type](item)
Technique C: Decompose Boolean Expressions
// BEFORE
if (user.age > 18 && user.hasLicense && !user.isSuspended && user.balance > 0) {}
// AFTER
const isEligibleDriver = (user) =>
user.age > 18 && user.hasLicense && !user.isSuspended && user.balance > 0
if (isEligibleDriver(user)) {}
Technique A: Guard Clauses (Early Returns)
// BEFORE: 4 levels deep
function process(data) {
if (data) {
if (data.isValid) {
if (data.items.length > 0) {
if (data.status === 'active') {
// actual logic
}
}
}
}
}
// AFTER: 0 levels deep
function process(data) {
if (!data) return
if (!data.isValid) return
if (data.items.length === 0) return
if (data.status !== 'active') return
// actual logic
}
Technique B: Extract Nested Blocks
// BEFORE
function handleOrder(order) {
if (order.isPaid) {
if (order.items.length > 0) {
for (const item of order.items) {
if (item.inStock) { /* complex */ }
}
}
}
}
// AFTER
function handleOrder(order) {
if (!order.isPaid || order.items.length === 0) return
order.items.filter(item => item.inStock).forEach(processItem)
}
Technique C: Use Array Methods
// BEFORE: nested loops
for (const user of users) {
for (const order of user.orders) {
if (order.status === 'pending') { /* process */ }
}
}
// AFTER: flat
users
.flatMap(user => user.orders)
.filter(order => order.status === 'pending')
.forEach(processOrder)
Technique A: Extract by Responsibility
// BEFORE: 100 line function
function submitForm(data) {
// validation (20 lines)
// formatting (15 lines)
// API call (25 lines)
// UI update (20 lines)
}
// AFTER: focused functions
function submitForm(data) {
const errors = validateFormData(data)
if (errors.length) return handleErrors(errors)
const formatted = formatFormData(data)
const result = await sendToApi(formatted)
updateUI(result)
}
Technique B: Extract Setup/Teardown
// AFTER
function processData() {
const context = setupProcessing()
try {
return executeProcessing(context)
} finally {
cleanupProcessing(context)
}
}
Technique: Object Parameter Pattern
// BEFORE
function createUser(name, email, age, role, department, manager, startDate) {}
// AFTER
function createUser({ name, email, age, role, department, manager, startDate }) {}
createUser({ name: 'John', email: 'john@example.com', role: 'developer' })
Technique: Extract and Parameterize
// BEFORE: duplicated
function fetchUsers() {
setLoading(true)
const data = await api.get('/users')
setLoading(false)
return data
}
function fetchProducts() {
setLoading(true)
const data = await api.get('/products')
setLoading(false)
return data
}
// AFTER: parameterized
async function fetchData(endpoint) {
setLoading(true)
try { return await api.get(endpoint) }
finally { setLoading(false) }
}
const fetchUsers = () => fetchData('/users')
const fetchProducts = () => fetchData('/products')
When extracting to new files, analyze the project structure:
utils/, helpers/, lib/ foldersApply all refactoring changes:
Report all changes made:
Refactored: filename.js
Changes applied:
- Extracted 3 functions from processData (was 120 lines)
- Converted 5 var declarations to const/let
- Refactored 2 Promise chains to async/await
- Added error handling to fetchUser()
- Extracted magic numbers to constants: MAX_RETRIES, TIMEOUT_MS
- Created utils/dataHelpers.js with 2 utility functions
New files created:
- utils/dataHelpers.js
You MUST complete and display this checklist. The refactoring is NOT complete until shown.
Example output:
Verification Checklist:
[x] Target file: src/utils/dataProcessor.js
[x] Code analyzed
[x] Anti-patterns found: 3
[x] Functions > 50 lines: 2 extracted
[x] Nesting > 3 levels: 1 fixed with guard clauses
[ ] Complexity > 10: N/A (none found)
[x] var → const/let: 8 converted
[x] Promise → async/await: 2 converted
[x] Error handling added: 1 function
[x] Changes applied successfully