Kiểm tra null JavaScript


170

Tôi đã xem qua đoạn mã sau:

function test(data) {
    if (data != null && data !== undefined) {
        // some code here
    }
}

Tôi hơi mới đối với JavaScript, nhưng, từ những câu hỏi khác mà tôi đã đọc ở đây, tôi có ấn tượng rằng mã này không có nhiều ý nghĩa.


Đặc biệt, câu trả lời này nói rằng

Bạn sẽ gặp lỗi nếu bạn truy cập vào một biến không xác định trong bất kỳ ngữ cảnh nào khác ngoài typeof.

Cập nhật: Câu trả lời (trích dẫn) ở trên có thể gây hiểu nhầm. Nó sẽ nói «một biến không được khai báo» , thay vì «một biến không xác định» .

Như tôi đã tìm ra, trong các câu trả lời của Ryan ♦ , maericsnwellnhof , ngay cả khi không có đối số nào được cung cấp cho hàm, các biến của nó cho các đối số luôn được khai báo. Thực tế này cũng chứng minh sai mục đầu tiên trong danh sách dưới đây.


Theo hiểu biết của tôi, các kịch bản sau đây có thể được trải nghiệm:

  • Hàm được gọi không có đối số, do đó tạo datamột biến không xác định và gây ra lỗi data != null.

  • Hàm được gọi cụ thể với null(hoặc undefined), như là đối số của nó, trong trường hợp đó data != nullđã bảo vệ mã bên trong, khiến cho && data !== undefinedvô dụng.

  • Hàm được gọi với một đối số không null, trong trường hợp đó, nó sẽ vượt qua cả hai data != null data !== undefined .

Q: sự hiểu biết của tôi có đúng không?


Tôi đã thử các cách sau, trong bảng điều khiển của Firefox:

--
[15:31:31.057] false != null
[15:31:31.061] true
--
[15:31:37.985] false !== undefined
[15:31:37.989] true
--
[15:32:59.934] null != null
[15:32:59.937] false
--
[15:33:05.221] undefined != null
[15:33:05.225] false
--
[15:35:12.231] "" != null
[15:35:12.235] true
--
[15:35:19.214] "" !== undefined
[15:35:19.218] true

Tôi không thể tìm ra một trường hợp mà data !== undefined sau này data != null có thể được sử dụng.


9
Chỉ cần sử dụng if (data). Đó là cách Javascript thông thường để kiểm tra xem databiến có đánh giá đúng không. undefined,, nullfalse, 0, chuỗi rỗng, mảng trống và đối tượng (?) không có thuộc tính ước tính thành false, phần còn lại là true.
J0HN

20
@ J0HN - Sử dụng if(data)có nghĩa là anh ta không thể vượt qua falsehoặc 0làm giá trị cho data.
techfoobar

@ J0HN Ngoài ra, câu trả lời tương tự tôi đề cập cũng nói rằng: if(typeof someUndefVar == whatever) -- worksif(someUnderVar) -- error.
afsantos

2
Nó có lẽ được cho là data !== null && data !== undefined, data != nulltương đương với data != undefined. Hình thức trước có xu hướng được ưa chuộng vì nó rõ ràng hơn về các điều kiện, trong khi đó dễ dàng bỏ qua cả hai nullundefinedđang được kiểm tra với hai điều kiện sau.
zzzzBov

2
Nhân tiện, các bài kiểm tra rõ ràng cho undefinedIMO là một mùi mã. Đây không phải là một từ khóa được bảo vệ như null, đó là một biến không xác định được. Điều này là hoàn toàn hợp lệ và sẽ phá vỡ mã của bạn:undefined = 1
Izkata

Câu trả lời:


106

Một biến số không xác định của người khác là khác với giá trị undefined.

Một biến không xác định:

var a;
alert(b); // ReferenceError: b is not defined

Một biến có giá trị undefined:

var a;
alert(a); // Alerts “undefined”

Khi một hàm lấy một đối số, đối số đó luôn được khai báo ngay cả khi giá trị của nó là undefinedvà do đó sẽ không có bất kỳ lỗi nào. Bạn đúng về != nullsau !== undefinedlà vô dụng, mặc dù.


32
data !== null && data !== undefinedsẽ có ý nghĩa, mặc dù.
bfavaretto

@bfavaretto: Đúng, vì vậy nó thực sự có thể là một lỗi đánh máy. Nhưng bạn không bao giờ biết
Lát

1
Đúng như tôi nghĩ, cảm ơn đã làm rõ. Ngoài ra, tôi không nghĩ đó là một lỗi đánh máy. Tôi đã chạy tìm và đếm trong toàn bộ kịch bản và nó đã tìm thấy 10 lần xuất hiện, vì vậy ... tôi đoán tác giả cũng cần làm rõ về điều này.
afsantos

2
Xem xét nhận xét của tôi ở trên: thực sự, data != nullsẽ kiểm tra cả hai nullundefined(nhưng thật thú vị, chỉ cho nullundefined, chứ không phải các giá trị giả mạo khác).
bfavaretto

90

Trong JavaScript, nulllà một đối tượng singleton đặc biệt hữu ích cho việc báo hiệu "không có giá trị". Bạn có thể kiểm tra nó bằng cách so sánh và, như thường lệ trong JavaScript, nên sử dụng ===toán tử để tránh sự ép buộc kiểu khó hiểu:

var a = null;
alert(a === null); // true

Như @rynah đề cập, "không xác định" là một chút khó hiểu trong JavaScript. Tuy nhiên, luôn an toàn để kiểm tra xem typeof(x)chuỗi có phải là "không xác định" hay không, ngay cả khi "x" không phải là biến được khai báo:

alert(typeof(x) === 'undefined'); // true

Ngoài ra, các biến có thể có "giá trị không xác định" nếu chúng không được khởi tạo:

var y;
alert(typeof(y) === 'undefined'); // true

Đặt tất cả lại với nhau, kiểm tra của bạn sẽ trông như thế này:

if ((typeof(data) !== 'undefined') && (data !== null)) {
  // ...

Tuy nhiên, do "dữ liệu" biến luôn được xác định do là tham số hàm chính thức, nên sử dụng toán tử "typeof" là không cần thiết và bạn có thể so sánh trực tiếp với "giá trị không xác định" một cách an toàn.

function(data) {
  if ((data !== undefined) && (data !== null)) {
    // ...

Đoạn mã này có nghĩa là "nếu hàm được gọi với một đối số được xác định và không phải là null ..."


5
Tại sao nó phải trông như thế, mặc dù? != nullsẽ đúng với tất cả các giá trị ngoại trừ nullundefined, và chúng tôi chắc chắn rằng biến này được khai báo. typeoftrong các tình huống khác thậm chí có thể nguy hiểm - nếu bạn gõ nhầm tên biến thì sao? Điều đó có thể không bị phát hiện trong một thời gian dài vì không có lỗi.
Ry-

@maerics Vì vậy, nếu tôi làm theo đúng câu trả lời của bạn, trong một kiểm tra null như kịch bản trên, bạn hoàn toàn không sử dụng !=, chỉ so sánh nghiêm ngặt , !==?
afsantos

@rynah: Tôi không đoán đủ để biết về giải pháp tổng thể của OP để biết thử nghiệm null có phù hợp hay không nhưng tôi đã chỉnh sửa để đề cập đến thực tế rằng sử dụng "typeof" là không cần thiết.
maerics

@afsantos: trong thực tế tôi không nghĩ rằng nhiều giá trị (bất kỳ?) Sẽ chuyển đổi thành null; tuy nhiên, đó là cách tốt nhất để sử dụng so sánh nghiêm ngặt ( ===) trừ khi bạn thực sự biết những gì bạn đang làm và muốn so sánh sau khi chuyển đổi ( ==).
maerics

1
@Izkata: Bỏ bất kỳ thư viện nào cố gắng xác định lại undefined. Ngoài ra, Safari trên iPad sẽ làm điều đó trong mọi trường hợp. Bạn thậm chí không thể delete window.undefined.
Ry-

10

Trong trường hợp của bạn, hãy sử dụng data==null(CHỈ đúng cho null và không xác định - trên ảnh thứ hai tập trung vào các hàng / cột không xác định)

Ở đây bạn có tất cả ( src ):

nếu

nhập mô tả hình ảnh ở đây

== (phủ định của nó ! = )

nhập mô tả hình ảnh ở đây

=== (phủ định của nó ! == )

nhập mô tả hình ảnh ở đây


8

Q: Hàm được gọi không có đối số, do đó làm cho dữ liệu trở thành một biến không xác định và gây ra lỗi trên dữ liệu! = Null.

A: Có, datasẽ được đặt thành không xác định. Xem phần 10.5 Khai báo ràng buộc ràng buộc của thông số kỹ thuật. Nhưng việc truy cập một giá trị không xác định sẽ không gây ra lỗi. Bạn có thể nhầm lẫn điều này với việc truy cập một biến không được khai báo trong chế độ nghiêm ngặt sẽ gây ra lỗi.

Q: Hàm được gọi cụ thể bằng null (hoặc không xác định), là đối số của nó, trong trường hợp đó dữ liệu! = Null đã bảo vệ mã bên trong, kết xuất && dữ liệu! == không xác định vô dụng.

Q: Hàm được gọi với một đối số không null, trong trường hợp đó, nó sẽ chuyển một cách tầm thường cả dữ liệu! = Null và dữ liệu! == không xác định.

A: Đúng. Lưu ý rằng các xét nghiệm sau là tương đương:

data != null
data != undefined
data !== null && data !== undefined

Xem phần 11.9.3 Thuật toán so sánh đẳng thức trừu tượngphần 11.9.6 Thuật toán so sánh đẳng thức nghiêm ngặt của thông số kỹ thuật.


Tôi không nhầm lẫn với các biến không được khai báo, tôi thực sự không biết nó hoạt động như thế nào khi không có đối số được cung cấp. Tôi đã bị thuyết phục rằng datanó hoàn toàn không tồn tại, thay vì được đặt thành undefined. Tôi đánh giá cao sự làm rõ và những tài liệu tham khảo đó đã giúp tôi hiểu chi tiết hơn về cách thức hoạt động của cả hai đẳng thức.
afsantos

3

Tôi nghĩ rằng, việc kiểm tra các biến cho các giá trị mà bạn không mong đợi nói chung không phải là một ý tưởng hay. Bởi vì bài kiểm tra như bạn có thể coi là viết một danh sách đen các giá trị bị cấm. Nhưng nếu bạn quên liệt kê tất cả các giá trị bị cấm thì sao? Ai đó, thậm chí là bạn, có thể bẻ khóa mã của bạn bằng cách chuyển một giá trị không mong muốn. Vì vậy, một cách tiếp cận phù hợp hơn là một cái gì đó giống như danh sách trắng - chỉ kiểm tra các biến cho các giá trị dự kiến, không bất ngờ. Ví dụ: nếu bạn mong đợi giá trị dữ liệu là một chuỗi, thay vì này:

function (data) {
  if (data != null && data !== undefined) {
    // some code here
    // but what if data === false?
    // or data === '' - empty string?
  }
}

làm một cái gì đó như thế này:

function (data) {
  if (typeof data === 'string' && data.length) {
    // consume string here, it is here for sure
    // cleaner, it is obvious what type you expect
    // safer, less error prone due to implicit coercion
  } 
}

2

typeof foo === "undefined"là khác nhau foo === undefined, không bao giờ nhầm lẫn chúng. typeof foo === "undefined"là những gì bạn thực sự cần. Ngoài ra, sử dụng !==thay thế!=

Vì vậy, tuyên bố có thể được viết là

function (data) {
  if (typeof data !== "undefined" && data !== null) {
    // some code here
  }
}

Biên tập:

Bạn không thể sử dụng foo === undefinedcho các biến không được khai báo.

var t1;

if(typeof t1 === "undefined")
{
  alert("cp1");
}

if(t1 === undefined)
{
  alert("cp2");
}

if(typeof t2 === "undefined")
{
  alert("cp3");
}

if(t2 === undefined) // fails as t2 is never declared
{
  alert("cp4");
}

1
Được rồi, nhưng biến được khai báo trong trường hợp này, vậy vấn đề là gì?
Ry-

Cá nhân, tôi thấy foo === undefinednguy hiểm khi sử dụng. Nó làm cho mã của bạn thất bại với cùng điều kiện mà bạn đang cố gắng ngăn chặn.

Tôi đang nói về đối số cho chức năng trong câu hỏi. Xem thêm bình luận khác của tôi .
Ry-

1
Tại sao điều này bị hạ thấp‽ Câu đầu tiên là một sự phân biệt chính xác và quan trọng !
Izkata

1
@Izkata: vì không có lời giải thích cho tuyên bố ban đầu. foo === undefinedlà hoàn toàn chấp nhận được trong tình huống của OP (giả sử undefinedchưa bị ghi đè). Câu trả lời cũng không giải thích được tại sao !== nên sử dụng thay thế !=.
Matt

1

Cách đơn giản để làm bài kiểm tra của bạn là:

function (data) {
    if (data) { // check if null, undefined, empty ...
        // some code here
    }
}

5
Đây không phải là thử nghiệm phụ thuộc vào bối cảnh? Ý tôi là, nếu loại dự kiến datalà một chuỗi, thử nghiệm này trả về sai trên các chuỗi trống, có thể hoặc không phù hợp (hàm có thể muốn xử lý chuỗi trống theo một cách nào đó).
afsantos

5
Ngoại trừ nếu "dữ liệu" có giá trị ""hoặc 0hoặc NaN(hoặc người khác) thì khối "nếu" sẽ bị bỏ qua; có thể có hoặc không có ý định của OP.
maerics

Xin lỗi @afsantos, tôi không thấy bình luận của bạn, nếu bạn muốn nhận sai khi dữ liệu không được xác định, null ... ngoại trừ khi ngày trống, bạn sẽ cần tạo một var toTest = data khác; với một bài kiểm tra khác sau bài kiểm tra đầu tiên như: if (toTest == "") {// một số mã ở đây}
Kadiri

-5
var a;
alert(a); //Value is undefined

var b = "Volvo"; 
alert(b); //Value is Volvo

var c = null;
alert(c); //Value is null

4
Vui lòng thêm một số giải thích về ý nghĩa của điều này.
Ry-

Điều này không thực sự kiểm tra cho null.
dùng4642212
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.