You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

前端初学者CRUD应用JavaScript代码优化建议咨询及每日合理编码时长疑问

Hey there! Great job building your first CRUD app 🎉

As a frontend beginner, putting together a working CRUD tool is a fantastic milestone. Let's walk through actionable optimizations to align this code with JavaScript best practices, then talk about daily coding routines that work for new developers.


Code Optimization Suggestions

1. Follow Naming Conventions & Avoid Redundant Calls

JavaScript uses camelCase for variable/function names (instead of snake_case like title_input). Also, you’re calling getSaveData() twice—let’s fix that to save unnecessary work:

Before:

let fetchURL = "https://jsonplaceholder.typicode.com/posts/";
const title_input = document.getElementById("title-input");
// ... other snake_case variables

getSaveData();
if (getSaveData() == false) {
    console.log("No saved data found, Fetching new data");
    fetchData();
}

After:

const fetchURL = "https://jsonplaceholder.typicode.com/posts/"; // Constant, so use const
const titleInput = document.getElementById("title-input");
const bodyInput = document.getElementById("body-input");
const postsContainer = document.getElementById("posts-container");
// ... rest of the variables in camelCase

const hasSavedData = getSaveData();
if (!hasSavedData) {
    console.log("No saved data found, Fetching new data");
    fetchData();
}

2. Prevent XSS Attacks with HTML Escaping

Directly inserting user-provided content into innerHTML risks cross-site scripting (XSS) attacks. Add a helper function to escape special HTML characters:

function escapeHtml(str) {
    return str.replace(/[&<>"']/g, match => {
        const escapeMap = {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&quot;',
            "'": '&#039;'
        };
        return escapeMap[match];
    });
}

Then use it in your renderData function:

<div class="post-title">${escapeHtml(element.title)}</div>
<div class="post-body">${escapeHtml(element.body)}</div>

3. Replace Inline Onclicks with Event Delegation

Inline onclick attributes mix HTML and JavaScript, making code harder to maintain. Use event delegation instead—attach one listener to the parent container:

First, remove inline onclicks from your template:

<!-- Inside renderData -->
<button class="edit-btn">Edit</button>
<button class="delete-btn">Delete</button>

Add a data-index attribute to track the item position:

<div class="post-card" data-index="${idx}">

Then attach the listener to postsContainer:

postsContainer.addEventListener('click', (e) => {
    const card = e.target.closest('.post-card');
    if (!card) return; // Exit if click isn't on a card or its children
    
    const index = parseInt(card.dataset.index);
    if (e.target.classList.contains('edit-btn')) {
        editItem(index);
    } else if (e.target.classList.contains('delete-btn')) {
        deleteItem(index);
    }
});

4. Optimize Render Performance

Using innerHTML += in a loop triggers repeated DOM reflows, which slows down your app with large datasets. Use a DocumentFragment or array join to update the DOM once:

Option 1: DocumentFragment (best for performance)

function renderData(data) {
    postsContainer.innerHTML = '';
    const fragment = document.createDocumentFragment();
    
    data.forEach((element, idx) => {
        const card = document.createElement('div');
        card.className = 'post-card';
        card.dataset.index = idx;
        card.innerHTML = `
            <div class="post-title">${escapeHtml(element.title)}</div>
            <div class="post-body">${escapeHtml(element.body)}</div>
            <div class="post-actions">
                <button class="edit-btn">Edit</button>
                <button class="delete-btn">Delete</button>
            </div>
        `;
        fragment.appendChild(card);
    });
    
    postsContainer.appendChild(fragment);
}

Option 2: Array Join (simpler syntax)

function renderData(data) {
    const cardsHtml = data.map((element, idx) => `
        <div class="post-card" data-index="${idx}">
            <div class="post-title">${escapeHtml(element.title)}</div>
            <div class="post-body">${escapeHtml(element.body)}</div>
            <div class="post-actions">
                <button class="edit-btn">Edit</button>
                <button class="delete-btn">Delete</button>
            </div>
        </div>
    `).join('');
    
    postsContainer.innerHTML = cardsHtml;
}

5. Add Error Handling for LocalStorage

LocalStorage can fail (e.g., storage quota exceeded, browser restrictions). Wrap storage operations in try/catch blocks:

saveBtn.addEventListener("click", () => {
    try {
        localStorage.setItem("saveData", JSON.stringify(globalData));
        console.log("Data is successfully saved.");
    } catch (error) {
        console.error("Failed to save data:", error);
        // Optionally show a user-friendly alert:
        // alert("Couldn't save your data—check your browser storage settings.");
    }
});

function getSaveData() {
    try {
        const savedData = JSON.parse(localStorage.getItem("saveData"));
        if (savedData) {
            globalData = savedData;
            renderData(globalData);
            return true;
        }
        return false;
    } catch (error) {
        console.error("Corrupted saved data, clearing it:", error);
        localStorage.removeItem("saveData");
        return false;
    }
}

6. Encapsulate Repeated Logic

You’re resetting the form and edit state in two places—wrap that in a helper function to keep code DRY (Don’t Repeat Yourself):

function resetFormState() {
    form.reset();
    editId = null;
    globalIdx = null;
}

Then use it in your form submit handler:

form.addEventListener("submit", async (e) => {
    e.preventDefault();
    const title = titleInput.value.trim();
    const body = bodyInput.value.trim();
    
    if (editId) {
        // Update existing item
        globalData[globalIdx] = { ...globalData[globalIdx], title, body };
        renderData(globalData);
    } else {
        // Add new item
        globalData.push({ title, body, userId: 1 });
        renderData(globalData);
    }
    
    resetFormState(); // Reuse the helper function
});

Daily Coding Duration for Beginners

As someone new to coding, focus and consistency beat long hours. Here’s my advice:

  • Aim for 1–3 hours of focused coding per day. Use the Pomodoro Technique (25 minutes of work, 5 minutes of rest) to stay sharp.
  • Avoid marathon sessions (4+ hours)—your brain needs time to process new concepts, and fatigue leads to sloppy code and frustration.
  • Pair coding time with learning: spend 15–30 minutes after coding reviewing your work, reading documentation, or watching a short tutorial on a concept you struggled with.
  • Prioritize consistency over intensity: coding 1 hour every day is better than 6 hours once a week.
  • Listen to your body—if you’re feeling burnt out, take a break. It’s okay to skip a day to recharge.

内容的提问来源于stack exchange,提问作者Abhinav Jha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 06:42:41