JavaScript Cơ Bản: Syntax, Data Types, và Thao Tác DOM/BOM

1. Nhập môn nhanh chóng

Khai báo script
- Khi nhúng bên ngoài: dùng thẻ <script src="tập_tin.js"></script>.
- Khi viết nội bộ: <script>[mã nguồn]</script>. Attention: phải có cặp mở–đóng.
- Thuộc tính type="text/javascript" không bắt buộc (bỏ qua mặc định vẫn là JS).

1.1 Cú pháp cơ bản

  • Tất cả biến khai báo bằng keyword var.
  • Hiển thị giá trị biến: dùng console.log(value) trên Browser DevTools.

1.2 Kiểu dữ liệu

JS là ngôn ngữ động: kiểu của biến xác định khi chạy, dựa vào giá trị gán.

  • Số (number):
    • Nguyên: 123, thập phân: 123.1
    • Kiết khoa học: 1.123e3
    • Các giá trị đặc biệt: NaN, Infinity, -Infinity
  • Chuỗi (string):
    • Dùng dấu nháy đơn `'...'` hoặc nháy kép `"..."`, có thể lồng nhau.
    • Nối chuỗi: dùng phép + (nếu một toán hạng là chuỗi,concatenate).
    • Ký tự thoát: \n, \t, \\.
    • Độ dài: str.length.
  • Boolean (true / false):
    • Tham gia运算: true → 1, false → 0.
    • Phép logic: &&, ||, !.

Phase-out (logic ngắt ngắn)
- A && B: nếu A falsy → trả về A (không evaluating B).
- A || B: nếu A truthy → trả về A.
- Các giá trị falsy: 0, NaN, "", null, undefined.

So sánh
- == (giá trị, không kiểm tra type): không đảm bảo an toàn.
- === (giá trị + type): nên dùng mọi lúc.
- NaN không bằng bất kỳ giá trị nào, kể cả chính nó; kiểm tra bằng isNaN(value).

1.3 Chuyển đổi kiểu dữ liệu

Vào Chuỗi:
1. num.toString()
2. String(variable)
3. concatenate rỗng: num + ''

Vào Số:
1. parseInt(str) ( lấy nguyên, cắt đơn vị nếu có, ví dụ "120px" → 120 ).
2. parseFloat(str) (lấy thập phân).
3. Number(str)
4. Phép tính trừ𝛾ăncăsgjkhá: "12" - 2 → 10.

Vào Boolean:
- false nếu rỗng/negative/NaN/null/undefined.
- true cho mọi trường hợp còn lại.

1.4 Cấu trúc rẽ nhánh

if–else if–else Dùng cho tình huống phân chia nhiều khoảng giá trị (ví dụ: điểm số → xếp loại ABCDE).

Ternary operator
điều_kiện ? kết_quả_true : kết_quả_false

switch
- So sánh strict === giữa biểu thức và từng case.
- Dùng break để thoát khỏi block; default chạy khi không khớp.
- Phù hợp khi giá trị cụ thể cần xử lý riêng.

1.5 Vòng lặp lồng nhau

for (let i = 1; i ≤ 5; i++) {
  let row = '';
  for (let j = 1; j ≤ 5; j++) row += '*';
  console.log(row);
}

// In bảng cửu chương 1–9
for (let i = 1; i ≤ 9; i++) {
  let line = '';
  for (let j = 1; j ≤ i; j++) {
    line += `${j}×${i}=${i*j}\t`;
  }
  console.log(line);
}

1.6 Mảng và đối tượng

  • Mảng: dùng dấu [ ].
    let arr = [1, 'a', null, true];
    arr[999]; // "undefined" nếu truy cập ngoài giới hạn.
  • Đối tượng: dùng { }.
    let person = { name: 'Tenglong', age: 3, tags: ['JS','Java'] };
    person.name // 'Tenglong'

2. Chế độ nghiêm ngặt (Strict Mode)

'use strict';

Giúp tránh lỗi tiềm ẩn (ví dụ: không cho phép dùng biến chưa khai báo, this ở global mang giá trị undefined...).

3. Kiểu dữ liệu nâng cao

3.1 Chuỗi

  • Trích xuất chuỗi con: str.substring(start, end) (không>
  • Tìm vị trí: indexOf(subStr, start) (trả về -1 nếu không tìm thấy).
  • Lặp tìm tất cả vị trí:
    while ((idx = str.indexOf('o', idx)) !== -1) { ...; idx++; }
  • Lấy ký tự tại vị trí: charAt(idx), str[idx], hoặc charCodeAt(idx) (ASCII).

Đếm ký tự xuất hiện nhiều nhất:

let counts = {};
for (let char of str) counts[char] = (counts[char] || 0) + 1;

let maxChar = '', maxCount = 0;
for (const k in counts) {
  if (counts[k] > maxCount) {
    maxCount = counts[k];
    maxChar = k;
  }
}

Thay thế – Tách chuỗi
- Thay thế: str.replace(old, new) (chỉ thay thế lần xuất hiện đầu tiên).
- Dùng vòng lặp để thay thế toàn bộ.
- Tách thành mảng: str.split(delimiter).

3.2 Mảng

Khai báo: new Array() hoặc literal [].

  • Truy xuất: arr.length, indexOf(element) (chỉ trả index đầu tiên).
  • Độ dài nếu thay đổi arr.length: tăng → thêm phần tử undefined; giảm → mất phần tử.

Phép toán thường gặp

  • Đảo mảng: reverse().
  • Phân mảng: slice(start, end) (trả mảng con, không thay đổi gốc).
  • Thêm/xóa cuối: push() / pop(); thêm/xóa đầu: unshift() / shift().
  • Sắp xếp: sort() mặc định ranks theo chuỗi; cần hàm so sánh cho số:
    arr.sort((a, b) => a - b).
  • Nối mảng: concat() hoặc [...arr1, ...arr2] (ES6).
  • Nối thành chuỗi: join('separator').
  • Trừ trùng: dùng indexOf kiểm tra có chưa, nếu chưa → push vào mảng tạm.
  • Kiểm tra mảng: hoặc Array.isArray(value).

3.3 Đối tượng

Tạo đối tượng bằng 3 cách: literal {}, new Object(), hoặc构造 hàm (constructor function).

// Constructor
function Person(name, age) {
  this.name = name;
  this.age = age;
}
const p1 = new Person('Tenglong', 3);
  • Truy cập thuộc tính: obj.prop hoặc obj['prop'].
  • Duyệt thuộc tính: for (const key in obj) { ... }.
  • Sửa/xóa/kiểm tra: delete obj.prop; 'prop' in obj; hasOwnProperty('prop')>.

3.4 ES6: MapSet

  • Map: cặp key-value.
    let m = new Map([['a',1],['b',2]]);
    m.get('a'); m.set('c',3); m.delete('b');
  • Set: tập hợp không trùng lặp.
    let s = new Set([1,1,2,3]); // {1,2,3}
    s.add(4); s.has(2); s.delete(1);

Duyệt bằng for...of (trên các iterable như map, set, array), còn for...in duyệt key trên object.

3.5 Hàm

// Thư viện hàm
function getAbs(x) {
  return x ≥ 0 ? x : -x;
}

// Anonymous function expression
const sqrt = function (x) { return x * x; };

// ES6 arrow function
const square = x => x * x;

Tham số và arguments:
- JS không ràng buộc số lượng tham số.
- Truy cập mọi tham số đã truyền: dùng arguments (giống array nhưng không có pop(), shift()...).

rest parameter (ES6):
function f(a, b, ...rest) { console.log(rest); }rest phải là tham số cuối.

Ứng dụng: tìm max từ arguments

function getMax() {
  if (arguments.length === 0) return undefined;
  let max = arguments[0];
  for (let i = 1; i < arguments.length; i++) {
    if (arguments[i] > max) max = arguments[i];
  }
  return max;
}

3.6 Phạm vi biến và nâng cao

  • var có scope trong function, nếu không có khai báo → biến toàn cục (gắn vào window).
  • Phạm vi: nghị dùng var tại đầu hàm để tránh "hoisting"意外.
  • Hoisting: trình thông dịch tự động dời khai báo var và khai báo hàm lên đầu phạm vi (chỉ dời phần khai báo, không dời gán trị).

let (block scope) → nên ưu tiên thay cho var.

{
  let temp = 1; // chỉ tồn tại trong block {}
}
// temp không tồn tại ở đây

const: hằng số (phải gán trị ngay tại khai báo; nếu là object/array → đọc không đổi địa chỉ, nhưng nội dung có thể thay đổi).

3.7 Global object và tên miền

  • Toàn bộ biến global tự động gắn vào đối tượng window trong trình duyệt.
  • Để giảm xung đột, dùng "namespacing": tạo một đối tượng bao gói toàn bộ code của bạn:
    const MyApp = { add(a,b) { return a+b; } };

3.8 Hàm và this, apply, call

this trỏ đến object đang gọi hàm đó.
Ví dụ:

function getCalcAge() {
  return new Date().getFullYear() - this.birth;
}
const person = { name: 'Tenglong', birth: 2020 };

// Gắn hàm vào object
person.age = getCalcAge;
person.age(); // dùng trong context của person

// hoặc dùng apply/call
getCalcAge.call(person);     // gọi trực tiếp, truyền this = person
getCalcAge.apply(person, []); // truyền mảng tham số (ví dụ rỗng ở đây)

4. Đối tượng nội tại (Built-in Objects)

4.1 Date và thời gian

const now = new Date();
// Các phương thức
now.getFullYear();
now.getMonth() + 1; // tháng từ 0–11
now.getDate();
now.getHours();
now.getTime();      // epoch (milliseconds)
+new Date();        // shorthand lấy miliseconds hiện tại

// Tạo ngày từ chuỗi hoặc mảng
new Date('2022-05-01 12:00:00');
new Date(2022, 4, 1, 12);

Bộ đếm thời gian (Countdown)

function countdown(targetDate) {
  const start = +new Date();
  const end = +new Date(targetDate);
  const diffSec = Math.max(0, Math.floor((end - start) / 1000));
  
  const d = Math.floor(diffSec / 86400);
  const h = Math.floor((diffSec % 86400) / 3600);
  const m = Math.floor((diffSec % 3600) / 60);
  const s = diffSec % 60;

  return `${d} días ${h}:${m}:${s}`;
}

4.2 JSON

JSON là định dạng dữ liệu dựa trên JS object literal.
Chuyển đổi:

const person = { name: 'Tenglong', age: 3 };
const jsonStr = JSON.stringify(person);
const parsed = JSON.parse(jsonStr);

4.3 Toán học (Math)

  • Không cần gọi new Math().
  • Thường dùng: Math.random(), Math.floor(), Math.ceil(), Math.abs(), Math.max/min().
  • Random số nguyên trong khoảng [min, max]:
function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

5. Lập trình hướng đối tượng

5.1 Prototype và kế thừa

Mỗi object có một liên kết __proto__ trỏ至 prototype của constructor.
- Khi truy cập thuộc tính không có, JS lần ngược chuỗi prototype.
- Thay đổi __proto__ động sau khi tạo là có thể (ít dùng).

5.2 ES6 Class (cú pháp糖)

class Student {
  constructor(name) {
    this.name = name;
  }
  hello() {
    alert(`Hello, ${this.name}`);
  }
}

class Pupil extends Student {
  constructor(name, grade) {
    super(name);
    this.grade = grade;
  }
  study() {
    alert('I am studying in grade ' + this.grade);
  }
}

Bản chất: JS vẫn dùng prototype dưới lớp syntactic sugar này.

6. Thao tác với BOM

BOM (Browser Object Model) → làm việc với trình duyệt và môi trường chạy.

  • window: global scope, chứa toàn bộ đối tượng trình duyệt.
    window.innerWidth / innerHeight (content area), outer ( Including chrome).
  • navigator: thông tin trình duyệt. Dùng thường xuyên để xác định platform: platform, userAgent.
  • screen: cấu hình màn hình (width, height).
  • location: URL hiện tại, có thể reload hoặc redirect:
    location.assign('https://example.com') hoặc location.href = 'https://example.com'.
  • history: quản lý lịch sử lui/mở trang:
    history.back(), history.forward().

7. Thao tác với DOM

DOM (Document Object Model) → cây HTML/XML có thể thao tác bằng JS.

7.1 Lấy phần tử

  • document.getElementById(id)
  • document.getElementsByClassName(className)
  • document.getElementsByTagName(tagName)
  • document.querySelector(selector) (CSS selector)
  • element.parentElement, element.children[0], element.firstElementChild.

7.2 Cập nhật DOM

  • Text: innerText (không bao gồm HTML), textContent (toàn bộ nội dung bao gồm script).
  • HTML: innerHTML (dễ bị XSS nếu dùng chuỗi chưa xác thực).
  • Thuộc tính: element.setAttribute(name, value), hoặc element.style.color = 'red'.
  • Đổi CSS: style.fontSize = '16px' (chuyển thành camelCase).

7.3 Thao tác với node

  • Thêm mới node:
const newP = document.createElement('p');
newP.innerText = 'Added paragraph';
newP.className = 'highlight';
container.appendChild(newP);
  • Xóa node: parent.removeChild(child).
  • Thay thế node: parent.replaceChild(newNode, oldNode).
  • Chèn trước/after: insertBefore(newNode, referenceNode), hoặc dùng before()/after() (ES6).

8. Thao tác với biểu mẫu (form)

Biểu mẫu HTML chứa các thành phần như <input>, <select>, <textarea>...
Để lấy/gán giá trị:

const username = document.getElementById('username');
// đọc
console.log(username.value); 
// gán
username.value = 'New value';

Tham khảo cách ràng buộc (validation) DATE, format, required,最小长度通过 HTML attributes hoặc JS.

9. jQuery cơ bản (giới thiệu)

$(selector).method(action);

// Ví dụ
$('#btn').click(function() {
  alert('Button clicked!');
});

// Interval
$(document).ready(function() {
  // code here
});

// Hoặc ngắn gọn
$(function() { ... });
  • Viết nghiệc chọn: $('p'), $('.class'), $('#id').
  • Thay đổi thuộc tính CSS: .css('color', '#000'), hoặc .css({color:'red', fontSize:'20px'}).
  • Show/Hide: .show(), .hide().
  • Sự kiện chuột: .mousemove(), .click().

Lưu ý: Các thư viện như jQuery giúp rút gọn code, nhưng về lâu dài nên làm quen với DOM API hiện đại (Vanilla JS) trước khi dùng thư viện.

Thẻ: JavaScript DOM BOM es6 map

Đăng vào ngày 18 tháng 6 lúc 23:03