Var trong javascript đã lỗi thời chưa?

ES6 đi kèm với rất nhiều tính năng mới tuyệt vời bao gồm hai cách mới để xác định các biến trong JavaScript. Hiện tại có ba từ khóa hoặc mã định danh khác nhau để khai báo một biến trong JavaScript. Trong bài viết này, tôi sẽ giải thích sự khác biệt chính giữa var, let và const và khi nào bạn nên sử dụng chúng

Để hiểu đầy đủ sự khác biệt giữa từng mã định danh, trước tiên chúng ta cần hiểu khái niệm về phạm vi

Phạm vi là gì?

Phạm vi xác định khả năng truy cập hoặc khả năng hiển thị của các biến đối với JavaScript. Có ba loại phạm vi trong JavaScript

1. Phạm vi toàn cầu

2. Phạm vi chức năng (cục bộ)

3. Phạm vi chặn (mới với ES6)

Các biến được khai báo bên ngoài một hàm nằm trong phạm vi toàn cầu. Các biến toàn cục có thể được truy cập và thay đổi trong bất kỳ phạm vi nào khác. Các biến được xác định trong một hàm thuộc phạm vi cục bộ và không thể truy cập được trong các hàm khác. Mỗi chức năng khi được gọi sẽ tạo ra một phạm vi mới, do đó các biến có cùng tên có thể được sử dụng trong các chức năng khác nhau

Phạm vi khối bao gồm các câu lệnh và vòng lặp if hoặc bất kỳ mã nào khác được gói trong {}. Khi được gọi, chúng không tạo phạm vi mới. Các biến được khai báo bên trong phạm vi khối sẽ vẫn ở trong phạm vi mà chúng đã có

Từ khóa Var

Trước ES6, từ khóa var được sử dụng để khai báo một biến trong JavaScript. Từ khóa var đã xuất hiện kể từ khi JavaScript ra đời và đó là thứ bạn sẽ thấy trong bất kỳ mã ES6 nào trước đây

Các biến được khai báo bằng từ khóa var có phạm vi toàn cầu hoặc chức năng, chúng không hỗ trợ phạm vi cấp khối. Điều này có nghĩa là nếu một biến được định nghĩa trong vòng lặp hoặc trong câu lệnh if thì nó có thể được truy cập bên ngoài khối và vô tình được định nghĩa lại dẫn đến chương trình có lỗi. Về nguyên tắc chung, bạn nên luôn khai báo biến với const, nếu bạn nhận thấy giá trị của biến cần thay đổi, hãy quay lại và thay đổi thành let

Khai báo

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 tương tự như
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
6. Hầu hết thời gian chúng ta có thể thay thế
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
6 bằng
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 hoặc ngược lại và mong mọi thứ hoạt động

var message = "Hi";
alert(message); // Hi

Nhưng bên trong

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 là một con quái vật rất khác, có nguồn gốc từ rất xa xưa. Nó thường không được sử dụng trong các kịch bản hiện đại, nhưng vẫn ẩn nấp trong các kịch bản cũ

Nếu bạn không có kế hoạch gặp những kịch bản như vậy, bạn thậm chí có thể bỏ qua chương này hoặc hoãn lại

Mặt khác, điều quan trọng là phải hiểu sự khác biệt khi di chuyển các tập lệnh cũ từ

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 sang
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
6, để tránh các lỗi lạ

Các biến, được khai báo bằng

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8, thuộc phạm vi chức năng hoặc phạm vi toàn cầu. Chúng có thể nhìn thấy thông qua các khối

Ví dụ

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if

Khi

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 bỏ qua các khối mã, chúng ta có một biến toàn cục
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
18

Nếu chúng ta sử dụng

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
19 thay vì
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
30, thì biến sẽ chỉ hiển thị bên trong
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
31

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
1

Điều tương tự cho các vòng lặp.

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 không thể là khối hoặc vòng lặp cục bộ

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
3

Nếu một khối mã nằm trong một hàm, thì

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 sẽ trở thành một biến cấp hàm

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
9

Như chúng ta có thể thấy,

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 xuyên qua
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
31,
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
36 hoặc các khối mã khác. Đó là bởi vì cách đây rất lâu trong JavaScript, các khối không có Môi trường từ vựng và
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 là phần còn lại của điều đó

Nếu chúng ta khai báo cùng một biến với

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
6 hai lần trong cùng một phạm vi, thì đó là một lỗi

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
5

Với

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8, chúng ta có thể khai báo lại một biến nhiều lần. Nếu chúng ta sử dụng
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 với một biến đã được khai báo, nó sẽ bị bỏ qua

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8

Khai báo

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 được xử lý khi chức năng bắt đầu (hoặc tập lệnh bắt đầu cho toàn cục)

Nói cách khác, các biến

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 được định nghĩa ngay từ đầu hàm, bất kể định nghĩa ở đâu (giả sử rằng định nghĩa không có trong hàm lồng nhau)

Vì vậy, mã này

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
1

…Về mặt kỹ thuật giống như thế này (đã di chuyển

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
93 ở trên)

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
3

…Hoặc thậm chí như thế này (hãy nhớ rằng, các khối mã bị bỏ qua)

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
4

Người ta còn gọi hành vi đó là “hoisting” (nâng cao), bởi vì tất cả

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 đều được “hoisted” (nâng) lên trên cùng của hàm

Vì vậy, trong ví dụ trên, nhánh

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
95 không bao giờ thực thi, nhưng điều đó không thành vấn đề.
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 bên trong nó được xử lý khi bắt đầu hàm, vì vậy tại thời điểm
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
97 biến tồn tại

Các tuyên bố được nâng lên, nhưng các bài tập thì không

Điều đó được thể hiện rõ nhất bằng một ví dụ

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
0

Dòng

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
98 có hai hành động trong đó

  1. Khai báo biến
    if (true) {
      var test = true; // use "var" instead of "let"
    }
    
    alert(test); // true, the variable lives after if
    8
  2. Phép gán biến
    if (true) {
      var test = true; // use "var" instead of "let"
    }
    
    alert(test); // true, the variable lives after if
    50

Khai báo được xử lý khi bắt đầu thực thi hàm (“hoisted”), nhưng phép gán luôn hoạt động tại nơi nó xuất hiện. Vì vậy, mã hoạt động cơ bản như thế này

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
1

Bởi vì tất cả các khai báo của

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 đều được xử lý khi bắt đầu hàm, nên chúng ta có thể tham chiếu chúng ở bất kỳ đâu. Nhưng các biến không được xác định cho đến khi các bài tập

Trong cả hai ví dụ trên,

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
52 chạy không có lỗi, vì biến
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
53 tồn tại. Nhưng giá trị của nó chưa được gán, vì vậy nó hiển thị
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
54

Trước đây, vì chỉ có

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 và nó không có khả năng hiển thị ở cấp độ khối nên các lập trình viên đã phát minh ra một cách để mô phỏng nó. Những gì họ đã làm được gọi là "biểu thức hàm được gọi ngay lập tức" (viết tắt là IIFE)

Đó không phải là thứ chúng ta nên sử dụng ngày nay, nhưng bạn có thể tìm thấy chúng trong các tập lệnh cũ

Một IIFE trông như thế này

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
2

Tại đây, một Biểu thức hàm được tạo và được gọi ngay lập tức. Vì vậy, mã thực thi ngay lập tức và có các biến riêng của nó

Biểu thức hàm được bao bọc bởi dấu ngoặc đơn

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
56, bởi vì khi công cụ JavaScript gặp
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
57 trong mã chính, nó sẽ hiểu đó là phần đầu của Tuyên bố hàm. Nhưng một Khai báo hàm phải có tên, vì vậy loại mã này sẽ báo lỗi

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
3

Ngay cả khi chúng ta nói. "Được rồi, hãy thêm một cái tên", điều đó sẽ không hoạt động, vì JavaScript không cho phép gọi Khai báo hàm ngay lập tức

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
4

Vì vậy, dấu ngoặc đơn xung quanh hàm là một thủ thuật để cho JavaScript thấy rằng hàm được tạo trong ngữ cảnh của một biểu thức khác và do đó, nó là Biểu thức hàm. nó không cần tên và có thể được gọi ngay lập tức

Có tồn tại những cách khác ngoài dấu ngoặc đơn để nói với JavaScript rằng chúng tôi muốn nói đến Biểu thức hàm

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
5

Trong tất cả các trường hợp trên chúng ta khai báo một Biểu thức hàm và chạy nó ngay lập tức. Hãy lưu ý lại. ngày nay không có lý do gì để viết mã như vậy

Có hai điểm khác biệt chính của

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 so với
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
59

  1. Biến
    if (true) {
      var test = true; // use "var" instead of "let"
    }
    
    alert(test); // true, the variable lives after if
    8 không có phạm vi khối, khả năng hiển thị của chúng nằm trong phạm vi chức năng hiện tại hoặc toàn cục, nếu được khai báo bên ngoài chức năng
  2. Khai báo
    if (true) {
      var test = true; // use "var" instead of "let"
    }
    
    alert(test); // true, the variable lives after if
    8 được xử lý khi bắt đầu chức năng (bắt đầu tập lệnh cho toàn cầu)

Có một sự khác biệt rất nhỏ nữa liên quan đến đối tượng toàn cầu, mà chúng ta sẽ đề cập trong chương tiếp theo

Những khác biệt này làm cho

if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
8 tệ hơn
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
6 hầu hết thời gian. Các biến cấp độ khối là một điều tuyệt vời. Đó là lý do tại sao
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
6 đã được giới thiệu trong tiêu chuẩn từ lâu và hiện là một cách chính (cùng với
if (true) {
  var test = true; // use "var" instead of "let"
}

alert(test); // true, the variable lives after if
7) để khai báo một biến

Có cần thiết phải sử dụng var trong JavaScript không?

Luôn khai báo các biến JavaScript với var , let hoặc const. Từ khóa var được sử dụng trong tất cả các mã JavaScript từ 1995 đến 2015. Từ khóa let và const đã được thêm vào JavaScript vào năm 2015. Nếu bạn muốn mã của mình chạy trong các trình duyệt cũ hơn, bạn phải sử dụng var .

Vấn đề với var trong JavaScript là gì?

“var” không có phạm vi chặn . Khi var bỏ qua các khối mã, chúng ta có một bài kiểm tra biến toàn cục. Như chúng ta có thể thấy, var xuyên qua if , for hoặc các khối mã khác. Đó là bởi vì từ lâu trong JavaScript, các khối không có Môi trường từ điển và var là phần còn lại của điều đó.