博客 / 詳情

返回

12個JS核心,搞懂這些直接起飛!

🧑‍💻 寫在開頭

點贊 + 收藏 === 學會🤣🤣🤣

你是不是也遇到過這樣的場景?面試官拋出一個閉包問題,你支支吾吾答不上來;團隊代碼review時,看到同事用的Promise鏈一臉懵逼;明明功能實現了,性能卻總是差那麼一點...

別慌!今天我整理了12個JavaScript核心概念,這些都是2024年各大廠面試的高頻考點,也是日常開發中真正實用的硬核知識。搞懂它們,不僅能輕鬆應對面試,更能讓你的代碼質量提升一個檔次!

變量與作用域

先來看個最常見的面試題:

// 經典面試題:猜猜輸出什麼?
for (var i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i); // 輸出:3 3 3
  }, 100);
}

為什麼會這樣?因為var聲明的變量存在變量提升,而且沒有塊級作用域。換成let就正常了:

// 使用let的正確寫法
for (let i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i); // 輸出:0 1 2
  }, 100);
}

這裏涉及到兩個關鍵概念:變量提升和塊級作用域。let和const是ES6引入的,它們有塊級作用域,不會出現var的那些奇怪問題。

閉包與內存管理

閉包可能是最讓人頭疼的概念了,但其實理解起來並不難:

// 閉包的實際應用:計數器
function createCounter() {
  let count = 0; // 這個變量被"封閉"在函數內部
  
  return {
    increment: () => ++count,
    decrement: () => --count,
    getValue: () => count
  };
}

const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2

閉包就是函數能夠記住並訪問其詞法作用域中的變量,即使函數在其作用域外執行。但要注意內存泄漏問題:

// 潛在的內存泄漏
function createHeavyObject() {
  const largeObject = new Array(1000000); // 大對象
  
  return () => {
    // 即使外部不再需要,largeObject仍然被引用
    console.log('對象還在內存中');
  };
}

原型與繼承

JavaScript的繼承是基於原型的,這和傳統的類繼承很不一樣:

// 原型鏈示例
function Animal(name) {
  this.name = name;
}

Animal.prototype.speak = function() {
  console.log(`${this.name} makes a noise.`);
};

function Dog(name) {
  Animal.call(this, name); // 調用父類構造函數
}

// 設置原型鏈
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.speak = function() {
  console.log(`${this.name} barks.`);
};

const dog = new Dog('Rex');
dog.speak(); // Rex barks.

ES6的class語法讓這變得更簡單:

class Animal {
  constructor(name) {
    this.name = name;
  }
  
  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name} barks.`);
  }
}

異步編程演進

從回調地獄到async/await,異步編程經歷了很大變化:

// 1. 回調地獄
function oldWay(callback) {
  readFile('file1.txt', (err, data1) => {
    if (err) return callback(err);
    processData(data1, (err, result1) => {
      if (err) return callback(err);
      // 更多嵌套...
    });
  });
}

// 2. Promise鏈
function promiseWay() {
  return readFilePromise('file1.txt')
    .then(processDataPromise)
    .then(data => {
      // 更清晰的流程
    })
    .catch(error => {
      // 統一錯誤處理
    });
}

// 3. async/await(推薦)
async function modernWay() {
  try {
    const data = await readFilePromise('file1.txt');
    const result = await processDataPromise(data);
    return result;
  } catch (error) {
    console.error('處理失敗:', error);
  }
}

Promise深度解析

Promise是現代JavaScript異步編程的基石:

// 手寫一個簡易Promise
class MyPromise {
  constructor(executor) {
    this.state = 'pending';
    this.value = undefined;
    this.onFulfilledCallbacks = [];
    
    const resolve = (value) => {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.forEach(cb => cb(value));
      }
    };
    
    executor(resolve);
  }
  
  then(onFulfilled) {
    return new MyPromise((resolve) => {
      if (this.state === 'fulfilled') {
        const result = onFulfilled(this.value);
        resolve(result);
      } else {
        this.onFulfilledCallbacks.push((value) => {
          const result = onFulfilled(value);
          resolve(result);
        });
      }
    });
  }
}

事件循環機制

這是JavaScript併發模型的核心:

// 理解事件循環的執行順序
console.log('1. 同步任務開始');

setTimeout(() => {
  console.log('6. 宏任務執行');
}, 0);

Promise.resolve().then(() => {
  console.log('4. 微任務執行');
});

console.log('2. 同步任務繼續');

Promise.resolve().then(() => {
  console.log('5. 另一個微任務');
});

console.log('3. 同步任務結束');

// 輸出順序:1 2 3 4 5 6

ES6+新特性實戰

現代JavaScript提供了很多好用特性:

// 解構賦值
const user = { name: '小明', age: 25, city: '北京' };
const { name, age } = user;

// 擴展運算符
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]

// 可選鏈操作符
const street = user?.address?.street; // 不會報錯

// 空值合併
const displayName = user.nickname ?? '匿名用户'; // 只有null/undefined時使用默認值

函數式編程概念

JavaScript很適合函數式編程風格:

// 高階函數
const users = [
  { name: '小明', age: 25 },
  { name: '小紅', age: 30 },
  { name: '小剛', age: 28 }
];

// 函數組合
const getAdultNames = users
  .filter(user => user.age >= 18)
  .map(user => user.name)
  .sort();

// 柯里化
const multiply = a => b => a * b;
const double = multiply(2);
console.log(double(5)); // 10

模塊化系統

從IIFE到ES Modules的演進:

// 現代ES Modules
// math.js
export const add = (a, b) => a + b;
export const PI = 3.14159;

// app.js
import { add, PI } from './math.js';
console.log(add(PI, 2)); // 5.14159

// 動態導入
const loadModule = async () => {
  const module = await import('./math.js');
  console.log(module.add(1, 2));
};

類型系統與TypeScript

雖然JavaScript是動態類型,但類型檢查很重要:

// 類型檢查工具函數
const typeCheck = {
  isString: value => typeof value === 'string',
  isFunction: value => typeof value === 'function',
  isObject: value => value !== null && typeof value === 'object'
};

// TypeScript帶來的類型安全
interface User {
  name: string;
  age: number;
  email?: string;
}

function createUser(user: User): User {
  // TypeScript會在編譯時檢查類型
  return { ...user };
}

性能優化技巧

寫出高性能的JavaScript代碼:

// 防抖函數:避免頻繁調用
function debounce(func, wait) {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

// 使用Web Worker處理密集型任務
const worker = new Worker('heavy-task.js');
worker.postMessage({ data: largeData });
worker.onmessage = (event) => {
  console.log('計算結果:', event.data);
};

現代開發工具鏈

2024年的前端開發離不開這些工具:

// Vite配置示例
// vite.config.js
export default {
  plugins: [vue(), eslint()],
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['vue', 'vue-router']
        }
      }
    }
  }
};

// 現代測試工具
import { describe, it, expect } from 'vitest';

describe('工具函數測試', () => {
  it('應該正確計算加法', () => {
    expect(add(1, 2)).toBe(3);
  });
});

這12個核心概念就像JavaScript的基石,理解它們不僅能讓你在面試中游刃有餘,更能寫出更健壯、更易維護的代碼。

如果對您有所幫助,歡迎您點個關注,我會定時更新技術文檔,大家一起討論學習,一起進步。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.