Web Geliştirmede Modern JavaScript Teknikleri

JavaScript, web geliştirme dünyasının kalbi olmaya devam ediyor. ES6+ ile gelen yeni özellikler, modern framework'ler ve gelişmiş araçlar sayesinde JavaScript ekosistemi sürekli evrim geçiriyor. Bu kapsamlı rehberde, 2024 yılında her web geliştiricisinin bilmesi gereken modern JavaScript tekniklerini detaylı bir şekilde inceleyeceğiz.

Modern JavaScript'in Temelleri

Modern JavaScript denildiğinde, ES6 (ES2015) ve sonrası sürümlerle gelen yenilikler akla gelir. Bu özellikler, kodun daha okunabilir, sürdürülebilir ve performanslı olmasını sağlar.

ES6+ Temel Özellikleri

1. Let ve Const Değişken Tanımlamaları

Geleneksel var yerine let ve const kullanımı:

JavaScript - Değişken Tanımlamaları
// Eski yöntem (kullanmayın)
var name = 'John';
var age = 25;

// Modern yöntem
const name = 'John';  // Değişmeyecek değerler için
let age = 25;         // Değişebilecek değerler için

// Block scope örneği
if (true) {
    let blockScoped = 'Bu sadece bu blokta geçerli';
    const PI = 3.14159;
}
// console.log(blockScoped); // ReferenceError

2. Arrow Functions (Ok Fonksiyonları)

Daha kısa ve okunabilir fonksiyon yazımı:

JavaScript - Arrow Functions
// Geleneksel fonksiyon
function add(a, b) {
    return a + b;
}

// Arrow function
const add = (a, b) => a + b;

// Tek parametre için parantez opsiyonel
const square = x => x * x;

// Çok satırlı arrow function
const processData = (data) => {
    const processed = data.map(item => item * 2);
    return processed.filter(item => item > 10);
};

// Array methods ile kullanım
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);

3. Destructuring (Yapı Bozma)

Array ve object'lerden değer çıkarmanın modern yolu:

JavaScript - Destructuring
// Array destructuring
const colors = ['red', 'green', 'blue'];
const [primary, secondary, tertiary] = colors;

// Object destructuring
const user = {
    name: 'Alice',
    age: 30,
    email: 'alice@example.com'
};
const { name, age, email } = user;

// Varsayılan değerler ile
const { name: userName = 'Anonymous', country = 'Unknown' } = user;

// Nested destructuring
const response = {
    data: {
        users: [
            { id: 1, name: 'John' },
            { id: 2, name: 'Jane' }
        ]
    }
};
const { data: { users: [firstUser] } } = response;

4. Template Literals

String interpolation ve çok satırlı string'ler:

JavaScript - Template Literals
const name = 'World';
const greeting = `Hello, ${name}!`;

// Çok satırlı string
const html = `
    

${title}

${description}

`; // Tagged template literals function highlight(strings, ...values) { return strings.reduce((result, string, i) => { const value = values[i] ? `${values[i]}` : ''; return result + string + value; }, ''); } const message = highlight`Merhaba ${name}, bugün ${new Date().toLocaleDateString()}`;

Async Programming (Asenkron Programlama)

Promises ve Async/Await

Modern JavaScript'te asenkron işlemler için en önemli araçlar:

JavaScript - Promises
// Promise oluşturma
const fetchData = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const success = Math.random() > 0.5;
            if (success) {
                resolve({ data: 'Başarılı veri' });
            } else {
                reject(new Error('Veri alınamadı'));
            }
        }, 1000);
    });
};

// Promise kullanımı
fetchData()
    .then(result => console.log(result))
    .catch(error => console.error(error));

// Async/Await ile
async function getData() {
    try {
        const result = await fetchData();
        console.log(result);
        return result;
    } catch (error) {
        console.error('Hata:', error.message);
        throw error;
    }
}

// Paralel işlemler
async function fetchMultipleData() {
    try {
        const [users, posts, comments] = await Promise.all([
            fetch('/api/users').then(r => r.json()),
            fetch('/api/posts').then(r => r.json()),
            fetch('/api/comments').then(r => r.json())
        ]);
        
        return { users, posts, comments };
    } catch (error) {
        console.error('Bir veya daha fazla istek başarısız:', error);
    }
}

Pro İpucu

Promise.all() tüm promise'ların başarılı olmasını bekler. Eğer bazılarının başarısız olmasına rağmen devam etmek istiyorsanız Promise.allSettled() kullanın.

Modern Array ve Object Methods

Functional Programming Yaklaşımı

JavaScript - Array Methods
const products = [
    { id: 1, name: 'Laptop', price: 1000, category: 'Electronics' },
    { id: 2, name: 'Phone', price: 500, category: 'Electronics' },
    { id: 3, name: 'Book', price: 20, category: 'Education' },
    { id: 4, name: 'Headphones', price: 100, category: 'Electronics' }
];

// Map - Dönüştürme
const productNames = products.map(product => product.name);
const discountedPrices = products.map(product => ({
    ...product,
    discountedPrice: product.price * 0.9
}));

// Filter - Filtreleme
const expensiveProducts = products.filter(product => product.price > 100);
const electronics = products.filter(product => product.category === 'Electronics');

// Reduce - Toplama/Birleştirme
const totalPrice = products.reduce((sum, product) => sum + product.price, 0);
const productsByCategory = products.reduce((acc, product) => {
    if (!acc[product.category]) {
        acc[product.category] = [];
    }
    acc[product.category].push(product);
    return acc;
}, {});

// Find - Bulma
const laptop = products.find(product => product.name === 'Laptop');
const cheapProduct = products.find(product => product.price < 50);

// Some ve Every - Koşul kontrolü
const hasExpensiveItem = products.some(product => product.price > 500);
const allElectronics = products.every(product => product.category === 'Electronics');

// Method chaining
const result = products
    .filter(product => product.category === 'Electronics')
    .map(product => ({ ...product, discounted: product.price * 0.8 }))
    .sort((a, b) => b.discounted - a.discounted)
    .slice(0, 2);

Object Methods

JavaScript - Object Methods
const user = {
    name: 'John',
    age: 30,
    email: 'john@example.com',
    address: {
        city: 'Istanbul',
        country: 'Turkey'
    }
};

// Object.keys, values, entries
const keys = Object.keys(user);           // ['name', 'age', 'email', 'address']
const values = Object.values(user);       // ['John', 30, 'john@example.com', {...}]
const entries = Object.entries(user);     // [['name', 'John'], ['age', 30], ...]

// Object.assign - Shallow copy
const userCopy = Object.assign({}, user, { age: 31 });

// Spread operator - Modern way
const updatedUser = { ...user, age: 31, city: 'Ankara' };

// Object.fromEntries
const filteredEntries = Object.entries(user)
    .filter(([key, value]) => typeof value === 'string');
const stringFields = Object.fromEntries(filteredEntries);

// Nested object update
const userWithNewAddress = {
    ...user,
    address: {
        ...user.address,
        city: 'Izmir'
    }
};

Modules (Modüller)

Modern JavaScript'te kod organizasyonu için ES6 modülleri:

utils.js - Export
// Named exports
export const PI = 3.14159;
export const E = 2.71828;

export function add(a, b) {
    return a + b;
}

export function multiply(a, b) {
    return a * b;
}

// Class export
export class Calculator {
    constructor() {
        this.result = 0;
    }
    
    add(value) {
        this.result += value;
        return this;
    }
    
    multiply(value) {
        this.result *= value;
        return this;
    }
    
    getResult() {
        return this.result;
    }
}

// Default export
const utils = {
    formatCurrency: (amount) => `$${amount.toFixed(2)}`,
    formatDate: (date) => date.toLocaleDateString('tr-TR')
};

export default utils;
main.js - Import
// Named imports
import { add, multiply, PI, Calculator } from './utils.js';

// Default import
import utils from './utils.js';

// Mixed import
import utils, { add, PI } from './utils.js';

// Rename imports
import { add as sum, multiply as product } from './utils.js';

// Import all
import * as MathUtils from './utils.js';

// Dynamic imports
async function loadModule() {
    const { add, multiply } = await import('./utils.js');
    console.log(add(5, 3));
}

// Conditional loading
if (condition) {
    import('./heavy-module.js')
        .then(module => {
            module.doSomething();
        });
}

Modern Framework Patterns

React Hooks Pattern

React - Custom Hook
// Custom hook for API calls
import { useState, useEffect } from 'react';

function useApi(url) {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);
    
    useEffect(() => {
        const fetchData = async () => {
            try {
                setLoading(true);
                const response = await fetch(url);
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                const result = await response.json();
                setData(result);
            } catch (err) {
                setError(err.message);
            } finally {
                setLoading(false);
            }
        };
        
        fetchData();
    }, [url]);
    
    return { data, loading, error };
}

// Component'te kullanım
function UserProfile({ userId }) {
    const { data: user, loading, error } = useApi(`/api/users/${userId}`);
    
    if (loading) return 
Yükleniyor...
; if (error) return
Hata: {error}
; if (!user) return
Kullanıcı bulunamadı
; return (

{user.name}

{user.email}

); }

Vue 3 Composition API

Vue 3 - Composition API
import { ref, computed, onMounted, watch } from 'vue';

export default {
    setup() {
        // Reactive state
        const count = ref(0);
        const name = ref('');
        
        // Computed property
        const displayName = computed(() => {
            return name.value || 'Anonim';
        });
        
        // Methods
        const increment = () => {
            count.value++;
        };
        
        const decrement = () => {
            count.value--;
        };
        
        // Lifecycle
        onMounted(() => {
            console.log('Component mounted');
        });
        
        // Watchers
        watch(count, (newValue, oldValue) => {
            console.log(`Count changed from ${oldValue} to ${newValue}`);
        });
        
        // Return what should be available in template
        return {
            count,
            name,
            displayName,
            increment,
            decrement
        };
    }
};

Modern Development Tools

Package.json Scripts

package.json
{
  "name": "modern-js-project",
  "version": "1.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "test": "vitest",
    "test:coverage": "vitest --coverage",
    "lint": "eslint src --ext .js,.jsx,.ts,.tsx",
    "lint:fix": "eslint src --ext .js,.jsx,.ts,.tsx --fix",
    "format": "prettier --write src/**/*.{js,jsx,ts,tsx,json,css,md}"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@vitejs/plugin-react": "^4.0.0",
    "eslint": "^8.45.0",
    "prettier": "^3.0.0",
    "vite": "^4.4.0",
    "vitest": "^0.34.0"
  }
}

Dikkat

Modern JavaScript projelerinde mutlaka linting (ESLint) ve formatting (Prettier) araçlarını kullanın. Bu araçlar kod kalitesini artırır ve takım çalışmasını kolaylaştırır.

Performance Optimization

Lazy Loading ve Code Splitting

JavaScript - Lazy Loading
// React lazy loading
import { lazy, Suspense } from 'react';

const LazyComponent = lazy(() => import('./HeavyComponent'));

function App() {
    return (
        
Yükleniyor...
}>
); } // Dynamic imports for code splitting async function loadFeature() { const { feature } = await import('./feature-module.js'); feature.init(); } // Intersection Observer for lazy loading const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; img.classList.remove('lazy'); observer.unobserve(img); } }); }); document.querySelectorAll('img[data-src]').forEach(img => { observer.observe(img); });

Debouncing ve Throttling

JavaScript - Performance Utilities
// Debounce function
function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

// Throttle function
function throttle(func, limit) {
    let inThrottle;
    return function() {
        const args = arguments;
        const context = this;
        if (!inThrottle) {
            func.apply(context, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    };
}

// Kullanım örnekleri
const searchInput = document.getElementById('search');
const debouncedSearch = debounce((query) => {
    console.log('Searching for:', query);
    // API call here
}, 300);

searchInput.addEventListener('input', (e) => {
    debouncedSearch(e.target.value);
});

const throttledScroll = throttle(() => {
    console.log('Scroll event');
    // Expensive scroll operations
}, 100);

window.addEventListener('scroll', throttledScroll);

Best Practices

Modern JavaScript Best Practices

Sonuç

Modern JavaScript, web geliştirme dünyasında devrim yaratmaya devam ediyor. ES6+ özellikleri, async programming, modern array methods ve framework patterns ile daha temiz, okunabilir ve performanslı kod yazabiliyoruz.

Bu teknikleri projelerinizde uygulamaya başlayın ve JavaScript'in gücünü tam anlamıyla keşfedin. Unutmayın, teknoloji sürekli gelişiyor - güncel kalmak için sürekli öğrenmeye devam edin!

Son Söz

"Modern JavaScript sadece bir programlama dili değil, web'in geleceğini şekillendiren bir platform. Bu gücü doğru kullanmak, harika kullanıcı deneyimleri yaratmanın anahtarı." - KodNuke Dev Team