Độ ưu tiên các toán tử trong JavaScript
Biểu thức điều kiện là một trong những khía cạnh rất quan trong trong mọi ngôn ngữ lập trình. Chúng ta đã quen với các mệnh đề điều kiện như 6 hay 7. Chúng là những cú pháp hữu dụng để tạo ra những quyết định trong lập trình. Show Bài viết này sẽ tập trung vào các biểu thức điều kiện trong Javascript và cách sử dụng chúng một cách ngắn gọn so với các mệnh đề điều kiện. Biểu thức và Mệnh đề (Expressions vs Statements)Trước khi đi vào nội dung chính, chúng ta cần phân biệt giữa biểu thức và mệnh đề trong Javascript. Nếu coi Javascript là một ngôn ngữ có ngữ pháp thì biểu thức chính là cụm từ, trong khi đó mệnh đề là một câu hoàn chỉnh. Biểu thức có thể là bất kỳ thể hiện nào mà Javascript engine có thể tính toán và trả về một giá trị. Chẳng hạn như: thể hiện của biến, phép gán, biểu thức hàm, phép logic, toán tử bitwise, phép truy cập thuộc tính của đối tượng, lời gọi hàm, eval, .... Đoạn code dưới đây chỉ ra một số biểu thức Javascript:
Mệnh đề là bất kỳ thể hiện hay câu lệnh nào mà Javascript engine có thể thực thi để chạy chương trình hoặc gây ra những tác động kèm theo khác. Ví dụ: mệnh đề điều kiện, khai báo biến hoặc hàm, vòng lặp, throw, return, try/catch/finally, ... Một số biểu thức Javascript như phép gán và lời gọi hàm có thể gây ra những tác động kèm theo. Do đó, chúng lại được coi là một mệnh đề (mệnh đề biểu thức). Phép điều kiện và giá trị kiểu booleanTrong Javascript, phép điều kiện có thể là bất kỳ biểu thức hợp lệ nào. Thông thường, biểu thức điều kiện sẽ được tính toán để trả về một trong hai giá trị kiểu booleans: 8 hoặc 9Việc hiểu đúng cách mà Javascript engine chuyển đổi biểu thức điều kiện về giá trị boolean là điều cần thiết để viết các phép logic điều kiện một cách chính xác và khả dự. Hai khái niệm cơ bản có thể hiểu về phép chuyển đổi này:
Truthy vs FalsyMọi giá trị trong Javascript đều có thể phân loại thành truthy hay falsy. Những giá trị sau được coi là falsy trong Javascript.
Những giá trị khác các giá trị trên sẽ được coi là truthy. Các giá trị truthy sẽ được ép kiểu ngầm định thành giá trị 8. Trong khi giá trị falsy sẽ trả về giá trị 9.Tuy nhiên, việc chuyển đổi này có thể được khai báo tường minh nhờ hàm Boolean.
Ngoài ra, toán tử logic NOT ( 2) cũng chuyển đổi một giá trị về kiểu boolean. Toán tử 2 chuyển đổi toán hạng của nó thành giá trị phủ định ở kiểu boolean. Do đó, giá trị này luôn là giá trị boolean.Sử dụng toán tử 2 sẽ trả về 9 trên những giá trị truthy và 8 trên những giá trị falsy. Để chuyển về giá trị boolean tương ứng, chúng ta cần sử dụng 2 hai lần.
Short-Circuiting (Mạch chập)Toán tử AND ( 8) và OR ( 9) đều yêu cầu hai toán hạng và được sử dụng để thực hiện phép toán Boolean trên những toán hạng này.Cho hai toán hạng kiểu boolean ( 8 hoặc 9)
Chú ý rằng toán tử 8 có độ ưu tiên hơn 9. Do đó, nó sẽ được tính toán trước. Khi sử dụng cả hai toán tử này trong cùng một biểu thức, có thể sử dụng dấu ngoặc 2 để nhóm các phép tính theo thứ tự ưu tiên.
Khi sử dụng những toán tử này, toán hạng đầu tiên luôn được tính toán trước. Tuy nhiên, toán hạng thứ hai có thể không bao giờ được sử dụng tùy theo kết quả tính toán của toán hạng đầu tiên. Điều này được gọi là short-circuiting (mạnh chập hay đoản mạch). Toán tử 8 và 9 không phải lúc nào cũng trả về giá trị kiểu boolean. Thông thường, chúng có thể trả về bất kỳ giá trị nào. Dưới đây là mô tả chính xác về tính đoản mạch của chúng:
Thay thế mệnh đề bằng biểu thức1. Đơn giản hóa mệnh đề let strength = null; if (password.length > 7) { strength = 'Strong'; } else { strength = 'Weak'; } 7Rất nhiều câu điện kiện 8 có thể dễ dàng được thay thế bởi biểu thức điều kiện bằng cách áp dụng khái niệm mạch chập. Xem xét ví dụ sau:
Trong đoạn code này, mệnh đề 8 đảm bảo rằng hàm 0 chỉ được gọi khi phép điều kiện trả về 8Mệnh đề 8 trên có thể được thay thế bằng biểu thức điều kiện rất đơn giản như sau:
Mặc dù biểu thức điều kiện này có cách thực thi giống với mệnh đề điều kiện trên, nhưng thực chất chúng khác nhau. Mệnh đề điều kiện trả về một giá trị. Do đó, nó có thể được gán cho một biến hoặc được sử dụng ở nơi khác mà yêu cầu một giá trị cụ thể. Việc sử dụng biểu thức điều kiện như này đồng nghĩa với việc phải rất cận trọng về khái niệm mạch chập. Rất có thể toán hạng không được thực thi như đã đề cập ở mục trước của bài viết về mạch chập. 2. Mệnh đề If...ElseXem xét ví dụ đơn giản sau để xác định độ mạnh của mật khẩu:
Ý tưởng của đoạn code trên rất đơn giản: Kiểm tra nếu mật khẩu có độ dài lớn hơn 7 ký tự thì gán trị cho biến là 3 , ngược lại gán à 4Đoạn code trước có thể được rút gọn như sau:
Đoạn code này thực hiện giống hệt như đoạn code lúc trước, tất cả chỉ trong một dòng. Điều này trông khá ổn. Đoạn code dưới đây sẽ giải thích cơ chế tính toán của biểu thức điều kiện ở đoạn code trên. 0Có một cách khác để viết lại những biểu thức điện kiện 5 là sử dụng toán tử điều kiện, hay còn được gọi là toán tử ba ngôi (ternary operator). Cú pháp như sau: 1Đoạn code kiểm tra mật khẩu lúc trước có thể được viết lại sử dụng toán tử ba ngôi như sau: 2Mặc dùng trong ví dụ này, toán tử ba ngôi và toán tử logic hoạt động giống nhau nhưng cần nhớ rằng chúng không thể thay thế được cho nhau. Tốt hơn hết là nên sử dụng toán tử ba ngôi trong những trường hợp không biết rõ về toán hạng sẽ được thực hiện. Xem xét đoạn code sau để hiểu về sự nguy hiểm của việc sử dụng toán tử logic cho những trường hợp như này: 3Dưới đây là một mệnh đề rất quen thuộc thường được tìm thấy ở các thư viện AJAX đa nền tảng: 4Sử dụng toán tử logic: 5Sử dụng toán tử ba ngôi: 6Mẹo nhỏ và cú pháp viết tắt.Dưới đây là một số mẹo và cú pháp viết tắt hữu dụng khi sử dụng các toán tử logic và toán tử điều kiện: Chuẩn hóa về kiểu BooleanCho giá trị 6 cần chuẩn hóa để luôn trả về giá trị kiểu boolean theo quy tắc sau:
Đoạn code dưới đây mô tả phép chuẩn hóa trên: 7Định lý De MorganĐịnh lý toán học quen thuộc này có thể được mô tả như sau: 8Sự đồng nhất của BooleanKhi xử lý với giá trị boolean, có một số phép đồng nhất luôn đúng. Cho 02, 03 và 04 là những giá trị boolean, đoạn code sau sẽ chỉ ra sự đồng nhất này: 9Những toán tử ba ngôi phức hợpNhư đã đề cập ở các phần trước của bài viết, toán tử ba ngôi có thể được lồng với nhau để xử lý những đoạn logic liên quan đến mệnh đề 5Tuy nhiên, để có thể sử dụng chúng hiệu quả trong những biểu thức phức hợp thì cần hiểu về độ ưu tiên và tính kết hợp của toán tử ba ngôi.
0
1Khi sử dụng nhiều toán tử ba ngôi trong cùng một biểu thức, dấu ngoặc 2 có thể cần được sử dụng để thay đổi thứ tự tính toán. Ví dụ: |