Biến trong JavaScript

bởi Phạm Công Thành - 5 tháng trước

Biến (variable) nói chung và biến trong JavaScript nói riêng là tên đặc trưng cho một giá trị dữ liệu có thể bị thay đổi bởi các đoạn mã trong code của bạn.

Hiểu đơn giản nếu như bạn có một cái hộp được đặt tên thì biến là tên của hộp còn giá trị của biến được ta gán vào sẽ là những thứ trong hộp. Khi cần sử dụng giá trị của biến tức là những thứ trong hộp, ta chỉ việc tìm hộp có tên biến và lấy nó thôi.

Phạm vi của biến

Khi bạn khai báo một biến bên ngoài function, biến đó được gọi là global variable, bởi vì biến đó sẽ có hiệu lực đến bất kì đoạn code nào khác trong document hiện tại. Khi bạn khai báo một biến bên trong một function, nó gọi là local variable, vì nó chỉ có thể dùng được trong phạm vi function đó.

Javascript trước phiên bản ECMAScript 6 không có định nghĩa block statement scope (phạm vi của khối lệnh) thay vào đó, một biến được khai báo trong một block được xem là có giá trị local đối với function (hoặc global scope) mà block đó cư trú.

Khai báo biến

Có 3 kiểu khai báo biến trong JavaScript bạn có thể khai báo bằng một trong các kiểu sau đây:

1. var Khai báo một biến globallocal tùy thuộc vào từng ngữ cảnh.

var bienso_1;

2. let Khai báo một block-scoped, hoặc biến local chỉ có thể truy cập được trong block đó (thông thường là 1 function hay điều kiện if).

function foo() { 
    var x = 10; 
    if (true) { 
       let x = 20; // x ở đây được khai báo lại bằng let trong block-scoped
       console.log(x); // in ra 20 
    } 
       console.log(x); // in ra 10
}

3. const Khai báo một hằng số, cũng là đề khai báo biến local giá trị này không thể thay đổi được. Về mặt bản chất thì hằng không thuộc biến vì nó không thay đổi được giá trị như biến, tuy nhiên mình vẫn liệt kê ở đây vì hằng cũng cần được khai báo.

const Pi = 3.14;

Một hằng số đã khai báo không thể thay đổi giá trị thông qua việc gán lại giá trị hoặc không thể bị khai báo lại trong khi đoạn code đang chạy, bắt buộc phải được gán giá trị ngay khi khởi tạo. Bạn không thể khai báo một hằng số với tên trùng với tên function hoặc biến trong cùng một phạm vi code. Ví dụ:

function f() {};
const f = 5;
// Uncaught SyntaxError: Identifier 'f' has already been declared

function f() {
    const g = 5;
    var g;
  }
// Uncaught SyntaxError: Identifier 'g' has already been declared

Chú ý: Dấu chấm phẩy ở phía cuối của dòng để đánh dấu điểm kết thúc của câu lệnh. Bạn có thể đặt nhiều câu lệnh trên một dòng, miễn cuối mỗi cuâ lệnh có dấu “;” nhưng chúng ta chỉ nên đặt một câu lệnh trên một dòng để giữ code sạch và dễ nhìn hơn.

if (true) {
    var a = 1;
    const b = 2;
    console.log(b); // 2
}
console.log(a); // 1
console.log(b); // Uncaught ReferenceError: y is not defined

if (true) {
    let c = 3;
}
console.log(c); // Uncaught ReferenceError: c is not defined

Bạn cũng có thể không cần khai báo biến mà sử dụng ngay VD x=20; điều này sẽ tạo ra một biến undeclared global variable có thể dẫn đến các lỗi không mong muốn. Cho nên mình khuyến cáo khai báo bằng 3 kiểu trên.

Tên của biến

Tên của biến được bắt đầu bằng “chữ cái”, ký tự _ hoặc ký tự $, các ký tự tiếp theo có thể bổ sung thêm các ký tự số từ 0-9. Bản thân JavaScript là case sensitive tức là nó sẽ phân biệt chứ hoa và chữ thường. Đặc biệt ta không thể sử dụng khoảng trắng (space) hoặc dấu gạch ngang - trong tên biến.

var X;
var x;
//Biến X và x là hai biến khác nhau
//Một số cách đặt tên biến
var bien_chu;
var bien_123;
var _bien;
var bien01;

Giá trị của biến

Một biến được khai báo với cú pháp var hoặc let mà không gán giá trị sẽ có giá trị mặc định là undefined và việc khai báo phải được thực hiện trước khi biến được gọi lên.

Trong trường hợp truy cập đến một biến chưa được khai báo, thì console.log sẽ báo lỗi ReferenceError:

var a;
console.log('Giá trị của a: ' + a); // Giá trị của a: undefined

let b = 2;
console.log('Giá trị của b: ' + b); // Giá trị của b: 2

console.log('Giá trị của c: ' + c); // Uncaught ReferenceError: c is not defined

console.log('Giá trị của d is ' + d); // Uncaught ReferenceError: d is not defined
let d; 

Chúng ta có thể sử dụng undefined  để xét xem một biến có đang mang giá trị không. Dưới đây là một ví dụ, biến input chưa được gán giá trị nên lúc này nó mang giá trị mặc định undefined vậy câu điều kiện if là trả về true và chạy hàm doThis().

var input;
if (input === undefined) {
    doThis();
} else {
    doThat();
}

Tương tự undefined cũng trả về false trong kiểu dữ liệu boolean, như ví dụ sau đây chương trình sẽ trả về "Sai" vì boolean của biến input là false.

var input;
if (!input) {
    console.log('Sai');
} else {
    console.log('Đúng');
}
//Kết quả trả về 'Sai'

Khi biến có giá trị = undefined thực hiện phép toán với biến có giá trị cụ thể hoặc hằng số sẽ cho ra giá trị  = NaN (not a number). 

var a;
console.log(a + 2); // NaN

null khác với Undefined. Khi biến có giá trị null, biến sẽ mang giá trị 0 trong các phép toán (numeric) và false trong các ngữ cảnh boolean. Ví dụ:

var n = null;
console.log(n * 32); // 0

Variable hoisting (tiếng việt không biết gọi là gì)

Một thứ không bình thường về các biến trong JavaScript là bạn có thể sử dụng hoặc tham chiếu đến một biến tại vị trí phía trước câu lệnh khai báo. Khái niệm này gọi là hoisting, các biến trong JavaScript ở khía cạnh nào đó sẽ được “hoisted” (treo) hoặc lifted (nâng) vào vị trí trên cùng của câu lệnh hoặc hàm gần nó nhất.

Tuy nhiên, các biến bị hoisted này sẽ trả về giá trị undefined (khi được khai báo bằng  var . Nên cho dù bạn khai báo và khởi tạo sau khi bạn sử dụng hoặc tham chiếu đến biến này, thì trước đó nó vẫn trả về undefined. Hơi trìu tượng một chút, chúng ta sẽ xem ví dụ cho dễ hiểu hơn:

console.log(x); // "undefined" chứ không báo lỗi "Uncaught ReferenceError: x is not defined" vì bên dưới ta có khai báo biến x = 3
var x = 3;
console.log(x); // 3

// Khi chúng ta gọi biến x bên trên khai báo biến var x = 3;
// Kết quả trả về "undefined" tương đương với var x;
// Code tương đương với:

var x;
console.log(x); // undefined
x = 3;
var x = 1;

(function() {
    console.log(x); // undefined vì bên dưới có dòng khai báo var x = 2;
    var x = 2;
    console.log(x); // 2
})();

// Bên trong function cũng tương tự như vậy
// Code tương đương với;

var x = 1;

(function() {
    var x;
    console.log(x); // undefined
    x = 2;
    console.log(x); // 2
})();
console.log(x); // 1

Các biến được khai báo với keyword let (và const) cũng được hoisted nhưng không giống như var, chúng không được khởi tạo. Chúng ta sẽ không thể truy cập chúng cho tới khi chúng ta khai báo (khởi tạo) chúng. Người ta gọi đó là “temporal dead zone”. Khi ta truy cập đến một giá trị trước khi chúng được khai báo, JavaScript sẽ throws một ReferenceError.

function sayHi() {
  console.log(name);
  console.log(age);
  var name = "Lydia";
  let age = 21;
}

sayHi();
// undefined
// Uncaught ReferenceError: Cannot access 'age' before initialization

Nên nhớ: Luôn khai báo biến và đặt chúng ở trên cùng của code hay trong function để đảm bảo không xảy ra lỗi không mong muốn.

Bài trước

Bài tiếp

1
Bình luận

avatar
Mới nhất Cũ hơn Đánh giá
trackback

[…] còn nhớ về Variable Hoisting trong bài viết về Biến trong JavaScript không? Giống như biến functiong cũng có […]