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
<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:
- Nhập số từ bàn phím ảo
- Xử lý phép toán
- Hiển thị kết quả
- Xóa và reset
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:
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:
<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:
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
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:
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:
- Unit testing cho từng hàm toán học
- Integration testing cho luồng xử lý
- UI testing cho giao diện
- Performance testing
- Cross-browser testing
Ví dụ sử dụng Jest cho unit testing:
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=”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:
- Wolfram MathWorld – Bách khoa toàn thư toán học trực tuyến
- MDN JavaScript Documentation – Tài liệu JavaScript chính thức
- Khan Academy Math – Khóa học toán miễn phí từ cơ bản đến nâng cao
- MIT OpenCourseWare Mathematics – Khóa học toán từ MIT