Máy Tính Bỏ Túi JavaScript Nâng Cao

KẾT QUẢ TÍNH TOÁN

Hướng Dẫn Toàn Diện: Tạo Máy Tính Bỏ Túi Bằng JavaScript (2024)

Máy tính bỏ túi là một trong những ứng dụng cơ bản nhưng vô cùng hữu ích mà mọi lập trình viên JavaScript nên biết cách xây dựng. Bài viết này sẽ hướng dẫn bạn từng bước tạo một máy tính bỏ túi hoàn chỉnh với JavaScript thuần, từ các chức năng cơ bản đến nâng cao, cùng với các kỹ thuật tối ưu hóa và tích hợp visualization.

1. Các Loại Máy Tính Bỏ Túi Phổ Biến

Trước khi bắt đầu coding, chúng ta cần hiểu các loại máy tính khác nhau:

  • Máy tính cơ bản: Thực hiện 4 phép tính cộng, trừ, nhân, chia
  • Máy tính khoa học: Bao gồm các hàm lượng giác, logarit, lũy thừa
  • Máy tính thống kê: Tính toán các thông số thống kê như trung bình, phương sai
  • Máy tính tài chính: Tính lãi suất, giá trị tương lai của tiền, thanh toán vay
  • Máy tính lập trình: Hỗ trợ các phép toán nhị phân, hexa, bitwise
// Ví dụ cấu trúc HTML cơ bản cho máy tính
<div class=”calculator”>
  <div class=”display”><input type=”text” class=”calculator-screen” value=”” disabled></div>
  <div class=”calculator-keys”>
    <button type=”button” class=”operator” value=”+”>+</button>
    <button type=”button” class=”operator” value=”-“>-</button>
    <button type=”button” class=”operator” value=”*”>×</button>
    <button type=”button” class=”operator” value=”/”>÷</button>
    <button type=”button” value=”7″>7</button>
    <button type=”button” value=”8″>8</button>
    <button type=”button” value=”9″>9</button>
    <button type=”button” value=”4″>4</button>
    <button type=”button” value=”5″>5</button>
    <button type=”button” value=”6″>6</button>
    <button type=”button” value=”1″>1</button>
    <button type=”button” value=”2″>2</button>
    <button type=”button” value=”3″>3</button>
    <button type=”button” value=”0″>0</button>
    <button type=”button” class=”decimal” value=”.”>.</button>
    <button type=”button” class=”all-clear” value=”all-clear”>AC</button>
    <button type=”button” class=”equal-sign” value=”=”>=</button>
  </div>
</div>

2. Xây Dựng Máy Tính Cơ Bản Với JavaScript

Đây là phần core của máy tính. Chúng ta sẽ implement các chức năng:

  1. Nhập số từ bàn phím ảo
  2. Xử lý phép toán
  3. Hiển thị kết quả
  4. Xóa và reset
// JavaScript cho máy tính cơ bản
const calculator = {
  displayValue: ‘0’,
  firstOperand: null,
  waitingForSecondOperand: false,
  operator: null,
};

function updateDisplay() {
  const display = document.querySelector(‘.calculator-screen’);
  display.value = calculator.displayValue;
}

function inputDigit(digit) {
  const { displayValue, waitingForSecondOperand } = calculator;

  if (waitingForSecondOperand === true) {
    calculator.displayValue = digit;
    calculator.waitingForSecondOperand = false;
  } else {
    calculator.displayValue = displayValue === ‘0’ ? digit : displayValue + digit;
  }
}

function inputDecimal(dot) {
  if (calculator.waitingForSecondOperand === true) {
    calculator.displayValue = ‘0.’;
    calculator.waitingForSecondOperand = false;
    return;
  }

  if (!calculator.displayValue.includes(dot)) {
    calculator.displayValue += dot;
  }
}

function handleOperator(nextOperator) {
  const { firstOperand, displayValue, operator } = calculator;
nbsp; const inputValue = parseFloat(displayValue);

  if (operator && calculator.waitingForSecondOperand) {
    calculator.operator = nextOperator;
    return;
  }

  if (firstOperand === null) {
    calculator.firstOperand = inputValue;
  } else if (operator) {
    const result = performCalculation[operator](firstOperand, inputValue);

    calculator.displayValue = String(result);
    calculator.firstOperand = result;
  }

  calculator.waitingForSecondOperand = true;
  calculator.operator = nextOperator;
}

const performCalculation = {
  ‘+’: (firstOperand, secondOperand) => firstOperand + secondOperand,
  ‘-‘: (firstOperand, secondOperand) => firstOperand – secondOperand,
  ‘*’: (firstOperand, secondOperand) => firstOperand * secondOperand,
  ‘/’: (firstOperand, secondOperand) => firstOperand / secondOperand,
  ‘=’: (firstOperand, secondOperand) => secondOperand
};

function resetCalculator() {
  calculator.displayValue = ‘0’;
  calculator.firstOperand = null;
  calculator.waitingForSecondOperand = false;
  calculator.operator = null;
}

const keys = document.querySelector(‘.calculator-keys’);
keys.addEventListener(‘click’, (event) => {
  const { target } = event;

  if (!target.matches(‘button’)) {
    return;
  }

  if (target.classList.contains(‘operator’)) {
    handleOperator(target.value);
    updateDisplay();
    return;
  }

  if (target.classList.contains(‘decimal’)) {
    inputDecimal(target.value);
    updateDisplay();
    return;
  }

  if (target.classList.contains(‘all-clear’)) {
    resetCalculator();
    updateDisplay();
    return;
  }

  inputDigit(target.value);
  updateDisplay();
});

3. Mở Rộng Thành Máy Tính Khoa Học

Để nâng cấp máy tính cơ bản thành máy tính khoa học, chúng ta cần thêm:

  • Các hàm toán học: sin, cos, tan, log
  • Phép toán nâng cao: lũy thừa, căn bậc n
  • Hằng số: π, e
  • Chức năng nhớ (memory)

Dưới đây là implementation cho hàm sin:

function scientificSin() {
  const currentValue = parseFloat(calculator.displayValue);
  if (isNaN(currentValue)) return;

  // Chuyển từ độ sang radian nếu cần
  const useRadians = document.getElementById(‘degree-mode’).checked;
  const valueInRadians = useRadians ? currentValue : currentValue * Math.PI / 180;

  calculator.displayValue = String(Math.sin(valueInRadians));
  updateDisplay();
}

// Thêm vào event listener
if (target.classList.contains(‘scientific’)) {
  switch(target.value) {
    case ‘sin’: scientificSin(); break;
    case ‘cos’: scientificCos(); break;
    // Các hàm khác tương tự
  }
  return;
}

4. Tích Hợp Thư Viện Chart.js Cho Visualization

Để làm cho máy tính trở nên trực quan hơn, chúng ta có thể sử dụng Chart.js để hiển thị đồ thị của các hàm toán học hoặc dữ liệu thống kê. Dưới đây là ví dụ về cách tích hợp Chart.js để vẽ đồ thị hàm sin:

// HTML: Thêm canvas vào trang
<canvas id=”functionChart” width=”400″ height=”200″></canvas>

// JavaScript: Tạo đồ thị hàm sin
function plotSineWave() {
  const ctx = document.getElementById(‘functionChart’).getContext(‘2d’);

  // Dữ liệu cho đồ thị
  const labels = [];
  const dataPoints = [];

  for (let x = -10; x <= 10; x += 0.5) {
    labels.push(x.toFixed(1));
    dataPoints.push(Math.sin(x));
  }

  const data = {
    labels: labels,
    datasets: [{
      label: ‘sin(x)’,
      data: dataPoints,
      borderColor: ‘#2563eb’,
      backgroundColor: ‘rgba(37, 99, 235, 0.1)’,
      tension: 0.3,
      fill: true
    }]
  };

  const config = {
    type: ‘line’,
    data: data,
    options: {
      responsive: true,
      plugins: {
        title: {
          display: true,
          text: ‘Đồ thị hàm sin(x)’
        }
      }
    }
  };

  new Chart(ctx, config);
}

5. Tối Ưu Hóa Hiệu Suất

Khi xây dựng máy tính bằng JavaScript, có một số kỹ thuật tối ưu hóa quan trọng:

Kỹ Thuật Mô Tả Cải Thiện Hiệu Suất
Debouncing Giới hạn tần suất xử lý sự kiện Giảm 40-60% tải CPU khi nhập liệu liên tục
Memoization Cache kết quả các phép tính phức tạp Tăng tốc độ 3-5 lần cho các hàm đệ quy
Web Workers Chạy tính toán nặng trên thread riêng Giảm đơ UI với các phép tính phức tạp
Lazy Loading Chỉ tải các module cần thiết Giảm 30% thời gian tải trang ban đầu
Request Animation Frame Tối ưu hóa animation Mượt mà hơn 60fps cho các hiệu ứng

Ví dụ về implement debounce:

function debounce(func, wait) {
  let timeout;

  return function executedFunction(…args) {
    const later = () => {
      clearTimeout(timeout);
      func(…args);
    };

    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

// Sử dụng
const inputElement = document.getElementById(‘calculator-input’);
inputElement.addEventListener(‘input’, debounce(function(e) {
  // Xử lý input sau 300ms không hoạt động
  processInput(e.target.value);
}, 300));

6. Xử Lý Lỗi Và Validation

Một máy tính tốt cần xử lý được các trường hợp lỗi:

  • Chia cho 0
  • Nhập liệu không hợp lệ
  • Tràn số (overflow)
  • Căn bậc hai của số âm
  • Logarit của số không dương
function safeCalculate(operation, a, b) {
  try {
    if (operation === ‘divide’ && b === 0) {
      throw new Error(‘Không thể chia cho 0’);
    }

    if (operation === ‘sqrt’ && a < 0) {
      throw new Error(‘Không thể tính căn bậc hai của số âm’);
    }

    if (operation === ‘log’ && a <= 0) {
      throw new Error(‘Logarit chỉ định nghĩa cho số dương’);
    }

    // Thực hiện phép tính
    switch(operation) {
      case ‘add’: return a + b;
      case ‘subtract’: return a – b;
      case ‘multiply’: return a * b;
      case ‘divide’: return a / b;
      case ‘sqrt’: return Math.sqrt(a);
      case ‘log’: return Math.log(a);
      default: throw new Error(‘Phép toán không hỗ trợ’);
    }
  } catch (error) {
      showError(error.message);
      return null;
  }
}

function showError(message) {
  const errorElement = document.getElementById(‘calculator-error’);
  errorElement.textContent = message;
  errorElement.style.display = ‘block’;

  setTimeout(() => {
    errorElement.style.display = ‘none’;
  }, 3000);
}

7. Tích Hợp Với Các API Ngoại Vi

Để làm cho máy tính của bạn mạnh mẽ hơn, bạn có thể tích hợp với các API:

API Chức Năng Ví Dụ Sử Dụng
Wolfram Alpha Giải phương trình phức tạp Giải phương trình bậc 4
Currency API Chuyển đổi tiền tệ 1 USD = ? VND
Weather API Tính toán liên quan thời tiết Chỉ số UV dựa trên góc mặt trời
Google Maps Tính toán khoảng cách Khoảng cách giữa 2 địa điểm
Crypto API Theo dõi giá tiền điện tử Tính lợi nhuận đầu tư

Ví dụ tích hợp với Currency API:

async function convertCurrency(amount, from, to) {
  try {
    const response = await fetch(
      `https://api.exchangerate-api.com/v4/latest/${from}`
    );

    if (!response.ok) {
      throw new Error(‘Không thể lấy dữ liệu tỷ giá’);
    }

    const data = await response.json();
    const rate = data.rates[to];

    if (!rate) {
      throw new Error(`Không tìm thấy tỷ giá cho ${to}`);
    }

    return amount * rate;
  } catch (error) {
      console.error(‘Lỗi chuyển đổi tiền tệ:’, error);
      showError(error.message);
      return null;
  }
}

// Sử dụng
const vndAmount = await convertCurrency(100, ‘USD’, ‘VND’);
if (vndAmount !== null) {
  console.log(`100 USD = ${vndAmount.toLocaleString()} VND`);
}

8. Testing Và Debugging

Để đảm bảo máy tính hoạt động chính xác, chúng ta cần:

  1. Unit testing cho từng hàm toán học
  2. Integration testing cho luồng xử lý
  3. UI testing cho giao diện
  4. Performance testing
  5. Cross-browser testing

Ví dụ sử dụng Jest cho unit testing:

// calculator.test.js
const { add, subtract, multiply, divide } = require(‘./calculator’);

describe(‘Calculator operations’, () => {
  test(‘adds 1 + 2 to equal 3’, () => {
    expect(add(1, 2)).toBe(3);
  });

  test(‘subtracts 5 – 3 to equal 2’, () => {
    expect(subtract(5, 3)).toBe(2);
  });

  test(‘multiplies 3 * 4 to equal 12’, () => {
    expect(multiply(3, 4)).toBe(12);
  });

  test(‘divides 10 / 2 to equal 5’, () => {
    expect(divide(10, 2)).toBe(5);
  });

  test(‘throws error when dividing by zero’, () => {
    expect(() => divide(10, 0)).toThrow(‘Không thể chia cho 0’);
  });
});

9. Triển Khai Và Tối Ưu SEO

Sau khi hoàn thành máy tính, chúng ta cần:

  • Tối ưu hóa tốc độ tải trang
  • Thêm meta tags phù hợp
  • Tạo sitemap
  • Đăng ký với Google Search Console
  • Tối ưu hóa cho mobile

Ví dụ về meta tags quan trọng:

<meta name=”description” content=”Máy tính bỏ túi đa năng bằng JavaScript với chức năng khoa học, thống kê và tài chính. Tính toán nhanh chóng và chính xác.”>
<meta name=”keywords” content=”máy tính bỏ túi, calculator javascript, máy tính khoa học, tính toán online, công cụ toán học”>
<meta property=”og:title” content=”Máy Tính Bỏ Túi JavaScript Nâng Cao | Công Cụ Toán Học Đa Năng”>
<meta property=”og:description” content=”Máy tính bỏ túi hoàn chỉnh với JavaScript thuần. Hỗ trợ tính toán cơ bản, khoa học, thống kê và tài chính với visualization trực quan.”>
<meta property=”og:type” content=”website”>
<meta property=”og:url” content=”https://yourdomain.com/may-tinh-bo-tui”>
<meta property=”og:image” content=”https://yourdomain.com/images/calculator-preview.jpg”>

10. Các Thư Viện Và Framework Hữu Ích

Mặc dù chúng ta đang sử dụng JavaScript thuần, nhưng có một số thư viện có thể giúp ích:

Thư Viện Mục Đích Ví Dụ Sử Dụng
Math.js Thư viện toán học nâng cao Phép toán ma trận, số phức
Chart.js Visualization dữ liệu Vẽ đồ thị hàm số
Numeral.js Định dạng số 1000 → “1,000”
Algebrite Giải phương trình đại số Giải x² + 2x + 1 = 0
Decimal.js Tính toán chính xác 0.1 + 0.2 = 0.3

Kết Luận Và Hướng Phát Triển

Chúng ta đã xây dựng một máy tính bỏ túi hoàn chỉnh bằng JavaScript với các chức năng từ cơ bản đến nâng cao. Để tiếp tục phát triển dự án này, bạn có thể:

  • Thêm chức năng lưu lịch sử tính toán
  • Phát triển ứng dụng mobile với React Native
  • Tích hợp voice input cho tính toán bằng giọng nói
  • Thêm chế độ dark/light theme
  • Phát triển extension cho Chrome/Firefox
  • Tạo API backend để lưu trữ dữ liệu người dùng

Với nền tảng này, bạn có thể mở rộng thành các công cụ chuyên biệt như máy tính kỹ thuật, máy tính y tế, hoặc thậm chí là hệ thống tính toán cho trí tuệ nhân tạo.

Tài Nguyên Hữu Ích

Để tìm hiểu sâu hơn về các khái niệm toán học và lập trình liên quan:

Leave a Reply

Your email address will not be published. Required fields are marked *