By GokiSoft.Com| 14:00 18/05/2020|
Tài Liệu Javascript

JavaScript Common Mistakes - Những lỗi thường gặp của JavaScript

Chương này chỉ ra một vài các sai lầm thường gặp trong JavaScript.



Vô tình sử dụng các toán tử gán


Các chương trình JavaScript có thể sinh ra các kết quả không ngờ tới nếu một lập trình viên vô tình sử sụng toán tử gán  (=), thay vì một toán tử so sánh (==) trong một câu lệnh if.

Câu lệnh if này trả về false (như mong muốn) bởi vì x không bằng 10:

var x = 0;
if (x == 10)
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var x = 0;
document.getElementById("demo").innerHTML = Boolean(x == 10);
</script>

</body>
</html>


Câu lệnh if này trả về true (có thể không như mong muốn) bởi vì 10 là true:

var x = 0;
if (x = 10)
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var x = 0;
document.getElementById("demo").innerHTML = Boolean(x = 10);
</script>

</body>
</html>


Câu lệnh if này trả về false (có thể không như mong muốn) bởi vì 0 là false:

var x = 0;
if (x = 0)
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var x = 0;
document.getElementById("demo").innerHTML = Boolean(x = 0);
</script>

</body>
</html>


Một phép gán luôn trả về giá trị được gán. 



Khi bạn muốn so sánh thông thường


Trong so sánh thông thường, kiểu dữ liệu không quan trọng. Câu lệnh if này trả về true:

var x = 10;
var y = "10";
if (x == y)
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var x = 10;
var y = "10";
document.getElementById("demo").innerHTML = Boolean(x == y);
</script>

</body>
</html>


Trong so sánh nghiêm ngặt, kiểu dữ liệu là quan trọng. Câu lệnh if này trả về false:

var x = 10;
var y = "10";
if (x === y)
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var x = 10;
var y = "10";
document.getElementById("demo").innerHTML = Boolean(x === y);
</script>

</body>
</html>


Đây là một sai lầm phổ biến khi bạn quên các câu lệnh switch sử dụng so sánh nghiêm ngặt:
case switch này sẽ hiển thị một cảnh báo:

var x = 10;
switch(x) {
  case 10: alert("Hello");
}
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var x = 10;
switch(x) {
  case 10: alert("Hello");
}
</script>

</body>
</html>


case switch sẽ không hiển thị cảnh báo:

var x = 10;
switch(x) {
  case "10": alert("Hello");
}
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var x = 10;
switch(x) {
  case "10": alert("Hello");
}
</script>

</body>
</html>



Dùng phép cộng và nối chuỗi một cách khó hiểu


Cộng là về cộng các chữ số.

Nối là về cộng các chuỗi.

Trong JavaScript cả hai hành động đều dùng cùng toán tử +.

Chính vì điều này, cộng một số với một số sẽ cho ra một kết quả khác biệt với cộng một số với một chuỗi.

var x = 10 + 5;          // the result in x is 15
var x = 10 + "5";        // the result in x is "105"
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var x = 10 + "5";
document.getElementById("demo").innerHTML = x;
</script>

</body>
</html>


Khi cộng hai biến, nó có thể khá khó khăn để dự đoán kết quả:

var x = 10;
var y = 5;
var z = x + y;           // the result in z is 15

var x = 10;
var y = "5";
var z = x + y;           // the result in z is "105"
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var x = 10;
var y = "5";
var z = x + y;
document.getElementById("demo").innerHTML = z;
</script>

</body>
</html>



Hiểu nhầm các số thực


Tất cả các số trong JavaScript được lưu dưới dạng các số thực dấu phẩy động 64-bits.

Tất cả các ngôn ngữ lập trình, bao gồm JavaScript, gặp khó khăn với việc lấy chính xác các giá trị dấu phẩy động.

var x = 0.1;
var y = 0.2;
var z = x + y            // the result in z will not be 0.3
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var x = 0.1;
var y = 0.2;
var z = x + y;
document.getElementById("demo").innerHTML = z;
</script>

</body>
</html>


Để giải quyết vấn đề trên, nó có thể được giúp đỡ bằng việc nhân và chia:

ví dụ

var z = (x * 10 + y * 10) / 10;       // z will be 0.3
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var x = 0.1;
var y = 0.2;
var z = (x * 10 + y *10) / 10;
document.getElementById("demo").innerHTML = z;
</script>

</body>
</html>



Ngắt một chuỗi JavaScript


JavaScript sẽ cho phép bạn ngắt một câu lệnh thành hai dòng:

ví dụ 1

var x =
"Hello World!";
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML =
"Hello World!";
</script>

</body>
</html>


Nhưng, ngắt một câu lệnh ở giữa một chuỗi sẽ không hoạt động:

ví dụ 2

var x = "Hello
World!";
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = "Hello 
World!";
</script>

</body>
</html>


Bạn phải sử dụng một "dấu gạch chéo ngược" nếu bạn muốn ngắt một câu lệnh trong một chuỗi:

ví dụ 3

var x = "Hello \
World!";
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = "Hello \
World!";
</script>

</body>
</html>



Đặt nhầm chỗ dấu chấm phẩy


Bởi vì một lần đặt nhầm chỗ dấu chấm phẩy, khối code này sẽ thực thi bất kể giá trị của x là gì:

if (x == 19);
{
  // code block 
}
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var x = 5;
if (x == 19);
{
document.getElementById("demo").innerHTML = "Hello";
}
</script>

</body>
</html>



Ngắt một câu lệnh Return


Đây là một hành vi mặc định của JavaScript là tự động đóng các cậu lệnh ở kết thúc của mỗi dòng.

Chính vì điều này, hai ví dụ ở dưới sẽ trả về cùng một kết quả giống nhau:

ví dụ 1

function myFunction(a) {
  var power = 10 
  return a * power
}
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = myFunction(55);
function myFunction(a) {
  var power = 10
  return a * power
}
</script>

</body>
</html>


ví dụ 2

function myFunction(a) {
  var power = 10;
  return a * power;
}
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = myFunction(55);
function myFunction(a) {
  var power = 10;
  return a * power;
}
</script>

</body>
</html>


JavaScript cũng sẽ cho phép bạn ngắt câu lệnh thành hai dòng:

Chính vì điều này, ví dụ 3 cũng sẽ trả về cùng một kết quả:

function myFunction(a) {
  var
  power = 10; 
  return a * power;
}
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = myFunction(55);
function myFunction(a) {
  var
  power = 10;
  return a * power;
}
</script>

</body>
</html>


Nhưng điều gì sẽ xảy ra nếu bạn ngắt câu lệnh return thành hai dòng như thế này:

ví dụ 4

function myFunction(a) {
  var
  power = 10; 
  return
  a * power;
}
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = myFunction(55);
function myFunction(a) {
  var
  power = 10;
  return
  a * power;
}
</script>

</body>
</html>


Hàm sẽ trả về undefined!

Tại sao? bởi vì JavaScript tưởng ý của bạn là:

ví dụ 5

function myFunction(a) {
  var
  power = 10; 
  return;
  a * power;
}
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = myFunction(55);
function myFunction(a) {
  var
  power = 10;
  return;
  a * power;
}
</script>

</body>
</html>


Giải thích

Nếu một câu lệnh chưa hoàn thiện như thế này:

var


JavaScript sẽ cố để hoàn thiện nó bằng cách đọc dòng tiếp theo:

power = 10;


Nhưng khi câu lệnh đã hoàn thiện:

return


JavaScript sẽ tự động đóng nó như thế này:

return;


Điều này xảy ra bởi vì đóng (kết thúc) các câu lệnh với dấu chấm phẩy là tùy chọn trong JavaScript.

JavaScript sẽ đóng các câu lệnh return ở cuối dòng, bởi vì nó là một câu lệnh hoàn thiện.

Không bao giờ ngắt một câu lệnh return.



Truy cập mảng bằng các chỉ mục


Nhiều các ngôn ngữ lập trình hỗ trợ các mảng với các chỉ mục được đặt tên.

Các mảng với chỉ mục được đặt tên được gọi là mảng liên kết (hoặc băm).

Trong JavaScript không hỗ trợ các mảng với chỉ mục được đặt tên.

Trong JavaScript, các mảng dùng các chỉ mục được đánh số:

ví dụ

var person = [];
person[0] = "John";
person[1] = "Doe";
person[2] = 46;
var x = person.length;       // person.length will return 3
var y = person[0];           // person[0] will return "John"
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Arrays</h2>

<p id="demo"></p>

<script>
var person = [];
person[0] = "John";
person[1] = "Doe";
person[2] = 46; 
document.getElementById("demo").innerHTML =
person[0] + " " + person.length;
</script>

</body>
</html>


Trong JavaScript, các đối tượng sử dụng các chỉ mục đặt tên.

Nếu bạn sử dụng các chỉ mục đặt tên, khi truy cập một mảng, JavaScript sẽ định nghĩa lại mảng thành một đối tượng tiêu chuẩn.

Sau việc định nghĩa lại tự động, các phương thức mảng và các thuộc tính sẽ cho ra undefined hoặc các kết quả sai:

ví dụ

var person = [];
person["firstName"] = "John";
person["lastName"] = "Doe";
person["age"] = 46;
var x = person.length;      // person.length will return 0
var y = person[0];          // person[0] will return undefined
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Arrays</h2>

<p>If you use a named index when accessing an array, JavaScript will redefine the array to a standard object, and some array methods and properties will produce undefined or incorrect results.</p>

<p id="demo"></p>

<script>
var person = [];
person["firstName"] = "John";
person["lastName"] = "Doe";
person["age"] = 46; 
document.getElementById("demo").innerHTML =
person[0] + " " + person.length;
</script>

</body>
</html>



Kết thúc việc định nghĩa bằng dấu phẩy


Dấu phẩy cuối cùng trong định nghĩa đối tượng và mảng là hợp lệ trong ECMAScript 5.

ví dụ đối tượng:

person = {firstName:"John", lastName:"Doe", age:46,}


ví dụ mảng:

points = [40, 100, 1, 5, 25, 10,];


Cảnh báo!!

IE 8 sẽ sập.

JSON không cho phép dấu phẩy cuối cùng.

JSON:

person = {"firstName":"John", "lastName":"Doe", "age":46}


JSON:

points = [40, 100, 1, 5, 25, 10];



Undefined không phải là Null


Các đối tượng, biến, thuộc tính, và phương thức JavaScript có thể undefined.

Trong việc thêm vào, đối tượng JavaScript rỗng có thể có giá trị  null.

Điều này có thể làm cho nó có đôi chút khó để kiểm tra nếu một đối tượng là rỗng.

Bạn có thể kiểm trả nếu một đối tượng tồn tại bằng cách kiểm tra kiểu của nó có phải undefined:

ví dụ

if (typeof myObj === "undefined") 
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript</h2>

<p>To test if an object does not exist, test if the type is undefined:</p>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = typeof myObj === "undefined";
</script>

</body>
</html>


Nhưng bạn không thể kiểm tra một đối tượng có phải null, bởi vì nó sẽ quăng một lỗi nếu đối tượng là undefined:

Không đúng:

if (myObj === null) 


Để giải quyết vấn đề này, bạn phải kiểm tra nếu một đối tượng không null, và không undefined.

Nhưng nó vẫn sẽ quăng một lỗi:

Không đúng:

if (myObj !== null && typeof myObj !== "undefined") 


Chính vì thế, bạn phải kiểm tra không undefined trước khi bạn có thể kiểm tra không null:

Đúng:

if (typeof myObj !== "undefined" && myObj !== null) 
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript</h2>

<p>If you want to test if an object is not null, you must test if it not undefined first.</p>

<p id="demo"></p>

<script>
document.getElementById("demo").innerHTML = typeof myObj !== "undefined" && myObj !== null;
</script>

</body>
</html>