Trong phần 2, chúng ta sẽ tìm hiểu về cách làm việc với biến trong JavaScript, bao gồm khai báo, gán giá trị, và thay đổi giá trị của biến. Ngoài ra, chúng ta cũng sẽ khám phá phạm vi (scope) trong JavaScript và một số hàm thường dùng.
JavaScript cung cấp ba từ khóa để khai báo biến: var
, let
, và const
.
var
var
có phạm vi trong hàm chứa nó.var
được hoisting lên đầu phạm vi của nó, nhưng chỉ hoisting phần khai báo, không hoisting phần gán giá trị.<div id="output1"></div>
<script>
// document.getElementById('output1').textContent = x; // undefined
setTimeout(() => {
var x = 5;
document.getElementById('output1').textContent += ' → ' + x; // 5
}, 1000);
</script>
let
let
có phạm vi trong khối code (block) chứa nó.let
cũng được hoisting nhưng nằm trong “Temporal Dead Zone” cho đến khi gặp dòng khai báo.<div id="output2"></div>
<script>
let x = 5;
if (x > 4) {
let y = 10;
document.getElementById('output2').textContent = y; // 10
}
// y không thể truy cập ở đây vì nằm ngoài block
// Nếu thử truy cập y ở đây sẽ gây lỗi
</script>
const
let
, const
có phạm vi trong khối code.const
phải được gán giá trị khi khai báo và không thể gán lại sau đó.<div id="output3"></div>
<script>
const z = 15;
document.getElementById('output3').textContent = z; // 15
// Dòng dưới đây sẽ gây lỗi nếu được bỏ comment
// z = 20; // Error: Assignment to constant variable
</script>
Hoisting là một hành vi trong JavaScript khi các khai báo biến và hàm được đưa lên đầu phạm vi của chúng trước khi code được thực thi.
var
Khi sử dụng var
, JavaScript hoisting phần khai báo biến lên đầu phạm vi, nhưng không hoisting phần gán giá trị.
<div id="hoisting-var"></div>
<script>
// document.getElementById('hoisting-var').textContent = 'Trước khai báo: ' + x; // undefined
setTimeout(() => {
var x = 10;
document.getElementById('hoisting-var').textContent += 'Sau khai báo: ' + x; // 10
}, 1000);
</script>
Trong ví dụ trên, JavaScript xử lý như sau:
<div id="hoisting-explained"></div>
<script>
// JavaScript ngầm hiểu code như sau:
var x; // Hoisted declaration
document.getElementById('hoisting-explained').textContent =
'Biến x được khởi tạo với giá trị: ' + x; // undefined
setTimeout(() => {
x = 10; // Assignment happens here
document.getElementById('hoisting-explained').textContent +=
', Sau đó được gán giá trị: ' + x; // 10
}, 1000);
</script>
let
và const
- Temporal Dead Zonelet
và const
cũng được hoisting, nhưng khác với var
, chúng không được khởi tạo với giá trị undefined
. Thay vào đó, chúng tồn tại trong “Temporal Dead Zone” cho đến khi đến dòng khai báo.
Đặc điểm | var | let | const |
---|---|---|---|
Phạm vi | Global scope | Block scope | Block scope |
Hoisting | Hoisted và khởi tạo với undefined |
Hoisted nhưng không khởi tạo (TDZ) | Hoisted nhưng không khởi tạo (TDZ) |
Gán lại giá trị | Có thể | Có thể | Không thể |
Khai báo lại | Có thể | Không thể trong cùng phạm vi | Không thể trong cùng phạm vi |
Khởi tạo | Không bắt buộc | Không bắt buộc | Bắt buộc |
Giới thiệu từ | ES1 (1997) | ES6 (2015) | ES6 (2015) |
Sử dụng var
:
var
trong code mớiSử dụng let
:
Sử dụng const
:
const
làm mặc định<div id="const-object"></div>
<script>
// Với const và object
const person = { name: 'Nguyen Van A', age: 30 };
// Không thể gán lại reference
// person = {}; // Error!
// Nhưng có thể thay đổi thuộc tính
person.age = 31;
document.getElementById('const-object').textContent =
'Đối tượng person sau khi thay đổi: ' + JSON.stringify(person); // { name: "Nguyen Van A", age: 31 }
</script>
Toán tử gán =
được sử dụng để gán giá trị cho biến.
<div id="assign"></div>
<script>
let a = 5;
const b = 'Hello';
var c = true;
document.getElementById(
'assign'
).textContent = `a = ${a}, b = ${b}, c = ${c}`;
</script>
Biến khai báo bằng var
hoặc let
có thể thay đổi giá trị trong quá trình thực thi.
<div id="change"></div>
<script>
let count = 0;
setInterval(() => {
count = count + 1;
document.getElementById('change').textContent =
'Count sau khi tăng: ' + count; // 1
}, 1000);
</script>
Scope (phạm vi) xác định nơi biến có thể được truy cập trong code.
Biến khai báo ngoài mọi hàm hoặc khối code có phạm vi toàn cục.
<div id="global"></div>
<script>
var globalVar = 'Tôi là biến toàn cục';
function showGlobal() {
document.getElementById('global').textContent = globalVar;
}
showGlobal();
</script>
Biến khai báo trong hàm hoặc khối code có phạm vi cục bộ.
<div id="local"></div>
<script>
function localExample() {
let localVar = 'Tôi là biến cục bộ';
document.getElementById('local').textContent = localVar;
}
localExample();
// Dòng dưới đây sẽ gây lỗi nếu được bỏ comment
// console.log(localVar); // Error: localVar is not defined
</script>
let
và const
để kiểm soát phạm vi biến chặt chẽ hơn.alert()
Hiển thị hộp thoại thông báo.
<button id="alert-btn">Hiển thị Alert</button>
<script>
document.getElementById('alert-btn').addEventListener('click', function () {
alert('Xin chào!');
});
</script>
confirm()
Hiển thị hộp thoại xác nhận với hai nút OK và Cancel.
<button id="confirm-btn">Hiển thị Confirm</button>
<div id="confirm-result"></div>
<script>
document.getElementById('confirm-btn').addEventListener('click', function () {
if (confirm('Bạn có chắc chắn không?')) {
document.getElementById('confirm-result').textContent =
'Người dùng đã xác nhận';
} else {
document.getElementById('confirm-result').textContent =
'Người dùng đã hủy';
}
});
</script>
setTimeout()
Thực thi hàm sau một khoảng thời gian.
<button id="timeout-btn">Chạy setTimeout</button>
<div id="timeout-result"></div>
<script>
document.getElementById('timeout-btn').addEventListener('click', function () {
document.getElementById('timeout-result').textContent = 'Đang đợi...';
setTimeout(() => {
document.getElementById('timeout-result').textContent =
'Đã chạy sau 2 giây!';
}, 2000);
});
</script>
setInterval()
Thực thi hàm định kỳ sau mỗi khoảng thời gian.
<button id="interval-btn">Bắt đầu/Dừng Interval</button>
<div id="interval-result">0</div>
<script>
let count = 0;
let intervalId = null;
document
.getElementById('interval-btn')
.addEventListener('click', function () {
if (intervalId === null) {
// Bắt đầu interval
intervalId = setInterval(() => {
count++;
document.getElementById('interval-result').textContent = count;
}, 1000);
this.textContent = 'Dừng Interval';
} else {
// Dừng interval
clearInterval(intervalId);
intervalId = null;
this.textContent = 'Bắt đầu Interval';
}
});
</script>
Trong phần tiếp theo, chúng ta sẽ khám phá sâu hơn về các toán tử, biểu thức cơ bản, các kiểu so sánh, câu lệnh rẽ nhánh, vòng lặp bờ la bờ la. Nói chung là nếu mình khum lười hihi. Cảm ơn các bạn đã đọc ạaa