Sự khác biệt giữa null và không xác định trong JavaScript là gì?


1086

Tôi muốn biết sự khác biệt giữa nullundefinedtrong JavaScript.




11
Tôi luôn nghĩ: nullbạn có đặt nó trống không, undefinednó trống vì nó chưa được đặt. Hoặc nulllà trống rỗng về mục đích, trong khi undefinedvẫn còn trống. Về cơ bản nó cho thấy ý định.
Muhammad Umer


15
NaN. Xem cho chính mình. console.log (null-không xác định). Sự khác biệt giữa null và không xác định là NaN. (Lưu ý rằng đây là một nỗ lực hài hước, trước khi bạn khiến tôi hiểu nhầm câu hỏi.)
Ivan

Câu trả lời:


1040

Trong JavaScript, undefinedcó nghĩa là một biến đã được khai báo nhưng chưa được gán một giá trị, chẳng hạn như:

var TestVar;
alert(TestVar); //shows undefined
alert(typeof TestVar); //shows undefined

nulllà một giá trị chuyển nhượng. Nó có thể được gán cho một biến như là một đại diện không có giá trị:

var TestVar = null;
alert(TestVar); //shows null
alert(typeof TestVar); //shows object

Từ các ví dụ trước, rõ ràng rằng undefinednullcó hai loại riêng biệt: undefinedlà một loại chính nó (không xác định) trong khi nulllà một đối tượng.

null === undefined // false
null == undefined // true
null === null // true

null = 'value' // ReferenceError
undefined = 'value' // 'value'

301
Trích dẫn từ cuốn sách Professional JS For Web Developers (Classicalx): "Bạn có thể tự hỏi tại sao toán tử typeof trả về 'đối tượng' cho một giá trị là null. Đây thực sự là một lỗi trong triển khai JavaScript ban đầu được sao chép trong ECMAScript. , được hợp lý hóa rằng null được coi là giữ chỗ cho một đối tượng, mặc dù về mặt kỹ thuật, nó là một giá trị nguyên thủy. "
Thuyền trưởng Sensible

34
biến cũng có thể không được xác định. ví dụ: console.log (typeof (abc)); không xác định
Nir O.

19
Nhận xét từ Nir O. rất quan trọng. Nếu tôi muốn có một biến không có giá trị ngay từ đầu, tôi viết "... = null", ví dụ "myvar = null". Bằng cách này - khi tôi gõ nhầm "if (myxar == null) {...}" - khối if không được thực thi. Tôi không có lợi thế này với không xác định: myvar = không xác định; myvar = 4; if (typeof myxar == "không xác định") {...}
Wolfgang Adamec

11
@Wolfgang Adamec, lập trình không có lỗi không phải là về những sai lầm.
Jorge Fuentes González

12
vì vậy về cơ bản giá trị null có nghĩa là một biến đã được đặt rõ ràng là (không có giá trị = null) hoặc đã được khởi tạo và được định nghĩa là không có gì. Trong khi phương tiện không xác định. nó có lẽ không bao giờ được khởi tạo hoặc nếu nó không bao giờ được định nghĩa.
Muhammad Umer

74

Tôi đã chọn cái này từ đây

Giá trị không xác định là giá trị nguyên thủy được sử dụng khi một biến chưa được gán giá trị.

Giá trị null là một giá trị nguyên thủy đại diện cho tham chiếu null, rỗng hoặc không tồn tại.

Khi bạn khai báo một biến qua var và không cho nó một giá trị, nó sẽ có giá trị không xác định. Chính nó, nếu bạn cố gắng WScript.Echo () hoặc alert () giá trị này, bạn sẽ không thấy gì. Tuy nhiên, nếu bạn nối một chuỗi trống vào chuỗi thì đột nhiên nó sẽ xuất hiện:

var s;
WScript.Echo(s);
WScript.Echo("" + s);

Bạn có thể khai báo một biến, đặt nó thành null và hành vi giống hệt nhau ngoại trừ việc bạn sẽ thấy "null" được in ra so với "không xác định". Đây thực sự là một sự khác biệt nhỏ.

Bạn thậm chí có thể so sánh một biến không xác định thành null hoặc ngược lại và điều kiện sẽ là đúng:

undefined == null
null == undefined

Họ, tuy nhiên, được coi là hai loại khác nhau. Mặc dù không xác định là một kiểu tất cả, null được coi là một giá trị đối tượng đặc biệt. Bạn có thể thấy điều này bằng cách sử dụng typeof () trả về một chuỗi đại diện cho loại chung của một biến:

var a;
WScript.Echo(typeof(a));
var b = null;
WScript.Echo(typeof(b));

Chạy đoạn script trên sẽ dẫn đến kết quả đầu ra sau:

undefined
object

Bất kể chúng là loại nào khác nhau, chúng vẫn sẽ hoạt động giống nhau nếu bạn cố gắng truy cập một thành viên của một trong hai, ví dụ như nói rằng chúng sẽ ném ngoại lệ. Với WSH, bạn sẽ thấy "'varname" đáng sợ là null hoặc không phải là một đối tượng "và đó là nếu bạn may mắn (nhưng đó là một chủ đề cho một bài viết khác).

Bạn rõ ràng có thể đặt một biến là không xác định, nhưng tôi khuyên bạn nên chống lại nó. Tôi khuyên bạn chỉ nên đặt biến thành null và không xác định giá trị cho những thứ bạn quên đặt. Đồng thời, tôi thực sự khuyến khích bạn luôn đặt mọi biến. JavaScript có chuỗi phạm vi khác với ngôn ngữ kiểu C, dễ gây nhầm lẫn ngay cả các lập trình viên kỳ cựu và đặt biến thành null là cách tốt nhất để ngăn chặn lỗi dựa trên nó.

Một trường hợp khác mà bạn sẽ thấy cửa sổ bật lên không xác định là khi sử dụng toán tử xóa. Những người trong chúng ta từ thế giới C có thể giải thích không chính xác điều này là phá hủy một vật thể, nhưng thực tế không phải vậy. Những gì hoạt động này làm là loại bỏ một chỉ mục từ một mảng hoặc một thành viên khỏi một đối tượng. Đối với Mảng, nó không ảnh hưởng đến độ dài, nhưng thay vào đó, chỉ số đó được coi là không xác định.

var a = [ 'a', 'b', 'c' ];
delete a[1];
for (var i = 0; i < a.length; i++)
WScript.Echo((i+".) "+a[i]);

Kết quả của đoạn script trên là:

0.) a
1.) undefined
2.) c

Bạn cũng sẽ nhận được trả lại không xác định khi đọc một mục con hoặc thành viên chưa từng tồn tại.

Sự khác biệt giữa null và không xác định là: JavaScript sẽ không bao giờ đặt bất kỳ thứ gì thành null, đó thường là những gì chúng ta làm. Mặc dù chúng tôi có thể đặt các biến thành không xác định, chúng tôi thích null vì đó không phải là điều đã từng làm cho chúng tôi. Khi bạn gỡ lỗi, điều này có nghĩa là mọi thứ được đặt thành null đều do bạn tự làm chứ không phải JavaScript. Ngoài ra, hai giá trị đặc biệt này gần như tương đương.


8
Thực sự là một câu trả lời tốt. Nhưng chỉ để chỉ ra, khi bạn kiểm tra "không xác định == null" thì việc kiểm tra kiểu không nghiêm ngặt. Do đó, nó trả về "đúng". Nếu bạn chọn "không xác định === null", nó sẽ trả về false.
wOlVeRiNe

3
Điều đáng chú ý là trong khi nhận xét này là đúng trong '11, với sự xuất hiện của các tham số chức năng tùy chọn, sự xuất hiện của các hệ thống kiểm tra kiểu như Flow và tính phổ biến của React (tất cả đều đối xử không xác định và không khác biệt), sự khôn ngoan cũ của nói chung sử dụng null thay vì không xác định không còn giữ nghiêm ngặt như vậy. không xác định thực sự thích hợp hơn null trong nhiều trường hợp bạn muốn sử dụng rõ ràng giá trị mặc định (ví dụ: đối với tùy chọn param hoặc prop React tùy chọn).
0x24a537r9

66

Đây là sự khác biệt

(thêm ký tự do thiếu ký tự, vì vậy tôi được phép đăng bài này.)


1
Bạn có thể bao gồm các thuộc tính cho nguồn hình ảnh, xin vui lòng?
Vega

1
@Vega Thật không may, tôi không nhớ tôi đã lấy nó từ đâu ngoài nơi nào trên imgur.com và đó có lẽ là từ một repost, không phải là nguồn ORIGINAL. Ngay cả liên kết nhúng ở đây cũng không cung cấp bất kỳ manh mối nào về người đã đăng phiên bản này, vì vậy tôi cũng không thể thực sự tìm kiếm nó.
Sebastian Norr

1
ha ha ha ... đây là lời giải thích tốt nhất mà tôi từng thấy! mát mẻ!
Akbar Mirsiddikov

36

null là một từ khóa đặc biệt chỉ ra sự vắng mặt của giá trị.

nghĩ về nó như một giá trị, như:

  • "foo" là chuỗi,
  • đúng là boolean,
  • 1234 là số
  • null là không xác định.

thuộc tính không xác định chỉ ra rằng một biến chưa được gán một giá trị bao gồm cả null. Giống

var foo;

biến rỗng được định nghĩa là nullcủa kiểu dữ liệuundefined


Cả hai đều đại diện cho một giá trị của một biến không có giá trị

AND null không đại diện cho một chuỗi không có giá trị - chuỗi rỗng-


Giống

var a = ''; 
console.log(typeof a); // string 
console.log(a == null); //false 
console.log(a == undefined); // false 

Bây giờ nếu

var a;
console.log(a == null); //true
console.log(a == undefined); //true 

NHƯNG

var a; 
console.log(a === null); //false 
console.log(a === undefined); // true

mỗi người có cách sử dụng riêng.

không xác định sử dụng nó để so sánh kiểu dữ liệu biến

null sử dụng nó để làm trống một giá trị của một biến

var a = 'javascript';
a = null ; // will change the type of variable "a" from string to object 

null cũng là một kiểu dữ liệu Cả không xác định và null đều là kiểu dữ liệu và giá trị
danwellman

9
nullHoàn toàn là một loại dữ liệu: msdn.microsoft.com/en-us/l Library / i / 7wkd9z69 (v = vs.9.9) .aspx. Thực tế là typeof nulltrả về objectlà một lỗi đã được biết đến và được ghi lại trong các phiên bản đầu của ECMAScript vẫn còn tương thích ngược. Liên kết mà bạn thực sự đăng trong bình luận của bạn cho biết một nửa trang "typeof null // object (lỗi trong ECMAScript, nên là null)"! Vì vậy, xin vui lòng, hiển thị một số nỗ lực tìm kiếm trước khi bình luận về phiếu bầu xuống
danwellman

1
Các định nghĩa mâu thuẫn: "thiếu giá trị" so với "chưa được gán giá trị". Nó không giống nhau sao?
Zon

3
Tôi không đồng ý với câu trả lời này. Null và không xác định là cả hai kiểu dữ liệu riêng biệt. null là loại null và không xác định là loại không xác định. Chỉ khi sử dụng toán tử trung thực (==), chúng ta mới có thể thấy javascript nói đúng nhưng so sánh nghiêm ngặt (===) mới tạo ra sai.
alaboudi

19

null : không có giá trị cho một biến; không xác định : sự vắng mặt của chính biến;

..where biến là một tên tượng trưng liên quan đến một giá trị.

JS có thể đủ tử tế để khởi tạo các biến mới được khai báo bằng null , nhưng không.


25
var a = {}; a.n = undefined;' then ..a.hasOwnProperty ('n') == true` ... vì vậy nói rằng sự vắng mặt của biến không còn đúng nữa
Muhammad Umer

17

Vui lòng đọc kỹ phần sau đây. Nó sẽ xóa mọi nghi ngờ của bạn về sự khác biệt giữa nullkhông xác định trong JavaScript. Ngoài ra, bạn có thể sử dụng chức năng tiện ích được cung cấp dưới đây để xác định chính xác các loại.

Trong JavaScript chúng ta có thể có các loại biến sau.

  1. Biến không khai báo
  2. Khai báo nhưng biến không được gán
  3. Các biến được gán với nghĩa đen không xác định
  4. Các biến được gán với null nghĩa đen
  5. Các biến được gán với bất kỳ thứ gì khác ngoài không xác định hoặc null

Sau đây giải thích từng trường hợp một

  1. Các biến không được khai báo: Theo sau đúng với các biến không được khai báo

    • Chỉ có thể được kiểm tra bởi typeof () trả về chuỗi 'không xác định'
    • Không thể được kiểm tra với == hoặc === hoặc bởi nếu hoặc toán tử có điều kiện ? (ném lỗi tham chiếu)
  2. Khai báo nhưng biến không được gán

    • typeof trả về chuỗi 'không xác định'
    • == kiểm tra với null trả về đúng
    • == kiểm tra với trả về không xác định đúng
    • === kiểm tra với null trả về false
    • === kiểm tra với trả về không xác định đúng
    • nếu hoặc điều hành điều hành ? trả về sai
  3. Các biến được gán với nghĩa đen không xác định : Các biến này được xử lý tương tự như các biến được khai báo nhưng không được gán .

  4. Các biến được gán với null nghĩa đen

    • typeof trả về chuỗi 'object'
    • == kiểm tra với null trả về đúng
    • == kiểm tra với trả về không xác định đúng
    • === kiểm tra với null trả về đúng
    • === kiểm tra với trả về không xác định sai
    • nếu hoặc điều hành điều hành ? trả về sai
  5. Các biến được gán với bất kỳ thứ gì khác ngoài không xác định hoặc null

    • typeof trả về một trong các chuỗi sau: 'chuỗi' , 'số' , 'boolean' , 'hàm' , 'đối tượng' , 'biểu tượng'

Sau đây cung cấp thuật toán để kiểm tra loại chính xác của một biến:

  1. Kiểm tra không khai báo / không gán / gán với không xác định bằng cách sử dụng typeof . trả về nếu chuỗi 'không xác định' được trả về.
  2. Kiểm tra null bằng cách sử dụng === . trả về 'null' nếu đúng .
  3. Kiểm tra loại thực tế bằng cách sử dụng typeof . Kiểu trả về nếu không bằng 'đối tượng'
  4. Gọi Object.prototype.toString.call (o) để xác định loại đối tượng thực tế. Nó sẽ trả về một chuỗi loại '[ObjectType]' cho tất cả các Đối tượng được xác định trong Javascript hoặc DOM . Đối với các đối tượng do người dùng xác định, nó trả về '[Object Object]'

Bạn cũng có thể sử dụng chức năng tiện ích sau để xác định loại. Hiện tại nó hỗ trợ tất cả các loại ECMA 262 2017.

function TypeOf(o,bReturnConstructor)
 {
   if(typeof o==='undefined') return 'undefined'
   if(o===null) return 'null'   
   if(typeof o!=='object') return typeof o

   var type=Object.prototype.toString.call(o)
  switch(type)
  {
     //Value types:4
     case '[object Number]': type='number';break;
     case '[object String]': type='string';break;
     case '[object Boolean]': type='boolean';break;
     case '[object Date]': type='date';break;


   //Error Types:7
     case '[object Error]': type='error';break;
     case '[object EvalError]': type='evalerror';break;
     case '[object RangeError]': type='rangeerror';break;
     case '[object ReferenceError]': type='referenceerror';break;
     case '[object SyntaxError]': type='syntaxerror';break;
     case '[object TypeError]': type='typeerror';break;
     case '[object URIError]': type='urierror';break;


    //Indexed Collection and Helper Types:13
     case '[object Array]': type='array';break;
     case '[object Int8Array]': type='int8array';break;
     case '[object Uint8Array]': type='uint8array';break;
     case '[object Uint8ClampedArray]': type='uint8clampedarray';break;
     case '[object Int16Array]': type='int16array';break;
     case '[object Uint16Array]': type='uint16array';break;
     case '[object Int32Array]': type='int32array';break;
     case '[object Uint32Array]': type='uint32array';break;
     case '[object Float32Array]': type='float32array';break;
     case '[object Float64Array]': type='float64array';break;
     case '[object ArrayBuffer]': type='arraybuffer';break;
     case '[object SharedArrayBuffer]': type='sharedarraybuffer';break;
     case '[object DataView]': type='dataview';break;

    //Keyed Collection Types:2
     case '[object Map]': type='map';break;
     case '[object WeakMap]': type='weakmap';break;

    //Set Types:2
     case '[object Set]': type='set';break;
     case '[object WeakSet]': type='weakset';break;

    //Operation Types
    case '[object RegExp]': type='regexp';break;
    case '[object Proxy]': type='proxy';break;
    case '[object Promise]': type='promise';break;

    case '[object Object]': type='object';
             if(bReturnConstructor && o.constructor) type=o.constructor.toString().match(/^function\s*([^\s(]+)/)[1];
         break;
    default:
        type=type.split(' ')[1]
        type=type.substr(0,type.length-1)   

   }
    return type 
}

12

Bạn có thể xem xét không xác định để thể hiện sự vắng mặt của giá trị ở cấp độ hệ thống, không mong muốn hoặc giống như lỗi để thể hiện sự vắng mặt của giá trị ở cấp độ chương trình, bình thường hoặc dự kiến.

thông qua JavaScript: Hướng dẫn dứt khoát


11

Tôi sẽ giải thích undefined, nullUncaught ReferenceError:

Uncaught ReferenceErrorBiến 1 - : chưa được khai báo trong tập lệnh của bạn, không có tham chiếu đến biến này
2 - undefined: Biến được khai báo nhưng không khởi tạo
3 - null: Biến được khai báo và là giá trị trống


9

Không xác định có nghĩa là một biến đã được khai báo nhưng không có giá trị:

var var1;
alert(var1); //undefined
alert(typeof var1); //undefined

Null là một nhiệm vụ:

var var2= null;
alert(var2); //null
alert(typeof var2); //object

9

nullkhông xác định là hai loại đối tượng riêng biệt có điểm chung sau:

  • cả hai chỉ có thể giữ một giá trị duy nhất, nullkhông xác định tương ứng;
  • cả hai đều không có thuộc tính hoặc phương thức và cố gắng đọc bất kỳ thuộc tính nào của một trong hai sẽ dẫn đến lỗi thời gian chạy (đối với tất cả các đối tượng khác, bạn nhận được giá trị không xác định nếu bạn cố đọc thuộc tính không tồn tại);
  • giá trị vô giá trịkhông xác định được coi là bình đẳng với nhau và không có gì khác bởi ==!=khai thác.

Sự tương đồng tuy nhiên kết thúc ở đây. Lần đầu tiên, có một sự khác biệt cơ bản trong cách thực hiện từ khóa nullkhông xác định . Điều này không rõ ràng, nhưng hãy xem xét ví dụ sau:

var undefined = "foo";
WScript.Echo(undefined); // This will print: foo

không xác định , NaNInfinity chỉ là tên của các biến "siêu lớp" được khởi tạo trước - chúng được khởi tạo vào thời gian chạy và có thể bị ghi đè bởi biến toàn cục hoặc biến cục bộ có cùng tên.

Bây giờ, hãy thử điều tương tự với null :

var null = "foo"; // This will cause a compile-time error
WScript.Echo(null);

Giáo sư! null , truefalse là các từ khóa dành riêng - trình biên dịch sẽ không cho phép bạn sử dụng chúng làm tên biến hoặc thuộc tính

Một điểm khác biệt nữa là không xác định là kiểu nguyên thủy, trong khi null là kiểu đối tượng (biểu thị sự vắng mặt của tham chiếu đối tượng). Hãy xem xét những điều sau đây:

WScript.Echo(typeof false); // Will print: boolean
WScript.Echo(typeof 0); // Will print: number
WScript.Echo(typeof ""); // Will print: string
WScript.Echo(typeof {}); // Will print: object
WScript.Echo(typeof undefined); // Will print: undefined
WScript.Echo(typeof null); // (!!!) Will print: object

Ngoài ra, có một sự khác biệt quan trọng trong cách xử lý nullkhông xác định trong ngữ cảnh số:

var a; // declared but uninitialized variables hold the value undefined
WScript.Echo(a === undefined); // Prints: -1

var b = null; // the value null must be explicitly assigned 
WScript.Echo(b === null); // Prints: -1

WScript.Echo(a == b); // Prints: -1 (as expected)
WScript.Echo(a >= b); // Prints: 0 (WTF!?)

WScript.Echo(a >= a); // Prints: 0 (!!!???)
WScript.Echo(isNaN(a)); // Prints: -1 (a evaluates to NaN!)
WScript.Echo(1*a); // Prints: -1.#IND (in Echo output this means NaN)

WScript.Echo(b >= b); // Prints: -1 (as expected)
WScript.Echo(isNaN(b)); // Prints: 0 (b evaluates to a valid number)
WScript.Echo(1*b); // Prints: 0 (b evaluates to 0)

WScript.Echo(a >= 0 && a <= 0); // Prints: 0 (as expected)
WScript.Echo(a == 0); // Prints: 0 (as expected)
WScript.Echo(b >= 0 && b <= 0); // Prints: -1 (as expected)
WScript.Echo(b == 0); // Prints: 0 (!!!)

null trở thành 0 khi được sử dụng trong các biểu thức số học hoặc so sánh số - tương tự như sai , về cơ bản nó chỉ là một loại "không" đặc biệt. mặt khác , không xác định là "không có gì" thực sự và trở thành NaN ("không phải là số") khi bạn cố gắng sử dụng nó trong ngữ cảnh số.

Lưu ý rằng nullkhông xác định sẽ nhận được một điều trị đặc biệt từ các toán tử ==!=toán tử, nhưng bạn có thể kiểm tra đẳng thức số thực của ab bằng biểu thức (a >= b && a <= b).


8

tl; dr

Sử dụng nullđể đặt một biến mà bạn biết đó là một đối tượng.

Sử dụng undefinedđể đặt một biến có loại hỗn hợp.


Đây là cách sử dụng của tôi cho cả 5 loại nguyên thủy và loại Đối tượng và điều đó giải thích sự khác biệt giữa «trường hợp sử dụng» của undefinedhoặc null.

Chuỗi

Nếu bạn biết một biến chỉ là một chuỗi trong khi tất cả vòng đời, theo quy ước, bạn có thể khởi tạo nó, thành "":

("") ? true : false; // false
typeof ""; // "string";
("Hello World") ? true : false; // true
typeof "Hello World"; // "string"

Con số

Nếu bạn biết một biến chỉ là một số trong khi tất cả vòng đời, theo quy ước, bạn có thể khởi tạo nó, thành 0(hoặc NaNnếu 0là một giá trị quan trọng trong việc sử dụng của bạn):

(0) ? true : false; // false
typeof 0; // "number";
(16) ? true : false; // true
typeof 16; // "number"

hoặc là

(NaN) ? true : false; // false
typeof NaN; // "number";
(16) ? true : false; // true
typeof 16; // "number"

Boolean

Nếu bạn biết một biến chỉ là một boolean trong khi tất cả các vòng đời, theo quy ước, bạn có thể khởi tạo nó, thành false:

(false) ? true : false; // false
typeof false; // "boolean";
(true) ? true : false; // true
typeof true; // "boolean"

Vật

Nếu bạn biết một biến chỉ là một Đối tượng trong khi tất cả vòng đời, theo quy ước, bạn có thể khởi tạo nó, thành null:

(null) ? true : false; // false
typeof null; // "object";
({}) ? true : false; // true
typeof {}; // "object"

Lưu ý: việc sử dụng thông minh tắt null là phiên bản giả mạo của Object vì Object luôn luôn truevà vì typeof nulltrả về object. Điều đó có nghĩa là typeof myVarObjecttrả về giá trị phù hợp cho cả loại Object và null.

Tất cả

Nếu bạn biết một biến có một loại hỗn hợp (bất kỳ loại nào trong khi tất cả vòng đời), theo quy ước, bạn có thể khởi tạo nó, thành undefined.


7

nulllà một giá trị đặc biệt có nghĩa là "không có giá trị". nulllà một đối tượng đặc biệt vì typeof nulltrả về 'đối tượng'.

Mặt khác, undefinedcó nghĩa là biến chưa được khai báo hoặc chưa được đưa ra một giá trị.


2
Điều quan trọng cần lưu ý là, mặc dù undefinedcó thể có nghĩa là một biến chưa được khai báo, nhưng không đảm bảo điều đó. Một biến có thể được khai báo là var thing;và nó sẽ bằng undefined.
Yura

6

Cách tốt nhất để hiểu sự khác biệt là trước tiên hãy làm rõ suy nghĩ của bạn về hoạt động bên trong của JavaScript và chỉ cần hiểu sự khác biệt về ý nghĩa giữa:

let supervisor = "None"
    // I have a supervisor named "None"

let supervisor = null
    // I do NOT have a supervisor. It is a FACT that I do not.

let supervisor = undefined
    // I may or may not have a supervisor. I either don't know
    // if I do or not, or I am choosing not to tell you. It is
    // irrelevant or none of your business.

Có một sự khác biệt về ý nghĩa giữa ba trường hợp này và JavaScript phân biệt hai trường hợp sau với hai giá trị khác nhau nullundefined. Bạn có thể tự do sử dụng những giá trị đó một cách rõ ràng để truyền đạt những ý nghĩa đó.

Vì vậy, một số vấn đề cụ thể về JavaScript phát sinh do cơ sở triết học này là gì?

  1. Một biến được khai báo mà không có bộ khởi tạo sẽ nhận được giá trị undefinedbởi vì bạn không bao giờ nói bất cứ điều gì về giá trị dự định là gì.

    let supervisor;
    assert(supervisor === undefined);
  2. Một thuộc tính của một đối tượng chưa bao giờ được thiết lập để đánh giá undefinedvì không ai từng nói bất cứ điều gì về tài sản đó.

    const dog = { name: 'Sparky', age: 2 };
    assert(dog.breed === undefined);
  3. nullundefined"tương tự" với nhau vì Brendan Eich đã nói như vậy. Nhưng họ nhất quyết không bằng nhau.

    assert(null == undefined);
    assert(null !== undefined);
  4. nullundefinedrất may có nhiều loại khác nhau. nullthuộc loại Nullundefinedthuộc loại Undefined. Đây là thông số kỹ thuật, nhưng bạn sẽ không bao giờ biết điều này vì sự typeofkỳ lạ mà tôi sẽ không lặp lại ở đây.

  5. Một hàm đạt đến phần cuối của cơ thể mà không có câu lệnh return return rõ ràng undefinedvì bạn không biết gì về hàm trả về.

Nhân tiện, có những dạng "hư vô" khác trong JavaScript (thật tốt khi nghiên cứu Triết học ....)

  • NaN
  • Sử dụng một biến chưa bao giờ được khai báo và nhận ReferenceError
  • Sử dụng một biến cục bộ lethoặc constđược xác định trong vùng chết tạm thời của nó và nhận được mộtReferenceError
  • Các ô trống trong mảng thưa thớt. Vâng, những điều này thậm chí không phải undefinedmặc dù chúng so sánh ===với không xác định.

    $ node
    > const a = [1, undefined, 2]
    > const b = [1, , 2]
    > a
    [ 1, undefined, 2 ]
    > b
    [ 1, <1 empty item>, 2 ]

Câu trả lời tốt nhất! Hầu hết các câu trả lời bỏ qua thực tế là bạn có thể xác định giá trị của một biếnundefined như trong let supervisor = undefinedtrường hợp.
J. Bruni

Cảm ơn bạn, và vâng, quan niệm sai lầm rằng một cái gì đó undefinedchỉ khi nó chưa được tuyên bố hoặc chưa được đưa ra một giá trị quá lan man và thực sự rất khó để vượt qua mọi người (mặc dù tôi vẫn cố gắng). Vì vậy, nhiều người rác JavaScript vì có cả hai nullundefinednhững giá trị này có ý nghĩa hoàn toàn khác biệt và phần lớn chúng hoạt động tốt với ý nghĩa dự định của chúng (tất nhiên là IMHO).
Ray Toal

5

Trong JavasSript có 5 kiểu dữ liệu nguyên thủy String, Number, Boolean, null và không xác định. Tôi sẽ cố gắng giải thích với một số ví dụ đơn giản

giả sử chúng ta có một chức năng đơn giản

 function test(a) {

     if(a == null){
        alert("a is null");
     } else {
        alert("The value of a is " + a);
     }
  }

cũng ở hàm trên nếu (a == null) giống như nếu (! a)

Bây giờ khi chúng ta gọi hàm này mà không truyền tham số a

   test(); it will alert "a is null";
   test(4); it will alert "The value of a is " + 4;

cũng thế

var a;
alert(typeof a); 

điều này sẽ không xác định; chúng tôi đã khai báo một biến nhưng chúng tôi chưa gán bất kỳ giá trị nào cho biến này; nhưng nếu chúng ta viết

var a = null;
alert(typeof a); will give alert as object

vì vậy null là một đối tượng. theo cách chúng tôi đã gán giá trị null cho 'a'


Biểu tượng là một kiểu nguyên thủy mới :)
Alexander Mills

4

Đối với undefinedloại, có một và chỉ một giá trị : undefined.

Đối với nullloại, có một và chỉ một giá trị : null.

Vì vậy, đối với cả hai, nhãn là cả loại và giá trị của nó.

Sự khác biệt giữa chúng. Ví dụ:

  • null là một giá trị trống
  • undefined là một giá trị còn thiếu

Hoặc là:

  • undefined chưa có giá trị
  • null có giá trị và không còn nữa

Trên thực tế, nulllà một từ khóa đặc biệt , không phải là một định danh và do đó bạn không thể coi nó là một biến để gán cho.

Tuy nhiên, undefinedlà một định danh . Tuy nhiên, trong cả non-strictchế độ và strictchế độ, bạn có thể tạo một biến cục bộ của tên không xác định. Nhưng đây là một ý tưởng khủng khiếp!

function foo() {
    undefined = 2; // bad idea!
}

foo();

function foo() {
    "use strict";
    undefined = 2; // TypeError!
}

foo();

4

Khi bạn khai báo một biến trong javascript, nó được gán giá trị undefined. Điều này có nghĩa là biến không bị ảnh hưởng và có thể được gán bất kỳ giá trị nào trong tương lai. Nó cũng ngụ ý rằng bạn không biết giá trị mà biến này sẽ giữ tại thời điểm khai báo.

Bây giờ bạn có thể chỉ định rõ ràng một biến null. Nó có nghĩa là biến không có bất kỳ giá trị. Ví dụ: Một số người không có tên đệm. Vì vậy, trong trường hợp như vậy, tốt hơn là gán giá trị null cho biến trung gian của đối tượng người.

Bây giờ giả sử rằng ai đó đang truy cập vào biến trung gian của đối tượng người của bạn và nó có giá trị undefined. Anh ta sẽ không biết nếu nhà phát triển quên khởi tạo biến này hay nếu nó không có bất kỳ giá trị nào. Nếu nó có giá trị null, thì người dùng có thể dễ dàng suy ra rằng middlename không có bất kỳ giá trị nào và nó không phải là một biến không được chạm tới.


3

null và không xác định đều được sử dụng để thể hiện sự vắng mặt của một số giá trị.

var a = null;

a được khởi tạo và định nghĩa.

typeof(a)
//object

null là một đối tượng trong JavaScript

Object.prototype.toString.call(a) // [object Object]

var b;

b là không xác định và chưa được khởi tạo

thuộc tính đối tượng không xác định cũng không xác định. Ví dụ "x" không được xác định trên đối tượng c và nếu bạn cố truy cập cx, nó sẽ trả về không xác định.

Nói chung, chúng tôi gán null cho các biến không xác định.


1
Object.prototype.toString.call(null); // "[object Null]"
Paul S.

3

Theo bài viết kỹ lưỡng của Ryan Morr về chủ đề này ...

"Nói chung, nếu bạn cần gán giá trị không cho biến hoặc thuộc tính, chuyển nó cho hàm hoặc trả về từ hàm, null hầu như luôn là lựa chọn tốt nhất. Nói một cách đơn giản, JavaScript sử dụng không xác định và lập trình viên nên sử dụng null. "

Xem Khám phá Vực thẳm vĩnh cửu của Null và Không xác định


3

Cả Null và không xác định trong JavaScript đều biểu thị sự vắng mặt của giá trị.

var a = null; //variable assigned null value
var b;  // undefined

Mặc dù thực tế cả hai tồn tại mà không có giá trị nhưng: Không xác định thực sự có nghĩa là biến không được khởi tạo. Các hàm trả về không có gì và các tham số hàm không có giá trị nào được cung cấp, giá trị không xác định được trả về. Sử dụng toán tử đẳng thức nghiêm ngặt === để phân biệt giữa null và không xác định.

Tham khảo: http://www.thesstech.com/javascript/null-and-und xác định


3

OK, chúng ta có thể bị nhầm lẫn khi nghe về nullundefined, nhưng hãy bắt đầu đơn giản, cả hai đều sai lệch và giống nhau theo nhiều cách, nhưng phần kỳ lạ của JavaScript, làm cho chúng có một vài sự khác biệt đáng kể, ví dụ, typeof null'object'trong khi typeof undefined'undefined'.

typeof null; //"object"
typeof undefined; //"undefined";

Nhưng nếu bạn kiểm tra chúng ==như dưới đây, bạn sẽ thấy cả hai đều sai lệch :

null==undefined; //true

Ngoài ra, bạn có thể gán nullcho một thuộc tính đối tượng hoặc cho một nguyên thủy, trong khiundefined đơn giản có thể đạt được bằng cách không gán cho bất cứ thứ gì.

Tôi tạo ra một hình ảnh nhanh chóng để hiển thị sự khác biệt cho bạn trong nháy mắt.

Không và không xác định


2

Vì typeof trả về không xác định, không xác định là loại trong đó null là trình khởi tạo chỉ ra các điểm biến thành không có đối tượng (hầu như mọi thứ trong Javascript là một đối tượng).


2

Trong javascript, tất cả các biến được lưu trữ dưới dạng cặp giá trị chính. Mỗi biến được lưu dưới dạng biến_name: biến_value / tham chiếu .

chưa xác định có nghĩa là một biến đã được cung cấp một khoảng trắng trong bộ nhớ, nhưng không có giá trị nào được gán cho nó. Như một thực tiễn tốt nhất, bạn không nên sử dụng loại này như một bài tập.

Trong trường hợp đó làm thế nào để biểu thị khi bạn muốn một biến không có giá trị tại một điểm sau trong mã? Bạn có thể sử dụng loại null , cũng là loại được sử dụng để xác định cùng một thứ, không có giá trị, nhưng nó không giống như không xác định, như trong trường hợp này bạn thực sự có giá trị trong bộ nhớ. Giá trị đó là null

Cả hai đều giống nhau nhưng cách sử dụng và ý nghĩa là khác nhau.


2

Tôi muốn thêm một sự khác biệt rất tinh tế giữa nullundefinedđiều tốt để biết khi bạn đang cố gắng học Vanilla JavaScript (JS) từ đầu:

  • nulllà một từ khóa dành riêng trong JS trong khi undefinedlà một biến trên đối tượng toàn cầu của môi trường thời gian chạy mà bạn đang ở.

Trong khi viết mã, sự khác biệt này không thể xác định được là cả hai nullundefinedluôn được sử dụng trong RHS của một câu lệnh JavaScript. Nhưng khi bạn sử dụng chúng trong LHS của một biểu thức thì bạn có thể quan sát sự khác biệt này một cách dễ dàng. Vì vậy, trình thông dịch JS diễn giải mã dưới đây là lỗi:

var null = 'foo'

Nó đưa ra lỗi dưới đây:

Uncaught SyntaxError: Mã thông báo bất ngờ null

Mặc dù bên dưới mã chạy thành công mặc dù tôi không khuyên bạn nên làm như vậy trong cuộc sống thực:

var undefined = 'bar'

Điều này hoạt động vì undefinedlà một biến trên đối tượng toàn cục (đối tượng cửa sổ trình duyệt trong trường hợp JS phía máy khách)


1
undefined='bar'không thực sự gán bất kỳ giá trị nào cho undefined(điều này là bất biến), nó chỉ không gây ra lỗi một cách khó hiểu.
Dmitri Zaitsev

1

Sự khác biệt giữa undefinednulllà tối thiểu, nhưng có một sự khác biệt. Một biến có giá trị undefinedchưa bao giờ được khởi tạo. Một biến có giá trị nullđược cung cấp một giá trị rõ ràng null, có nghĩa là biến đó được đặt rõ ràng là không có giá trị. Nếu bạn so sánh undefinednullbằng cách sử dụng null==undefinedbiểu thức, chúng sẽ bằng nhau.


Câu trả lời này là sai lệch ... xem các cuộc thảo luận trong câu trả lời được chấp nhận. Dòng dưới cùng - chỉ null==undefinedtruedo truyền ẩn (hoặc thuật ngữ tương đương trong JS). Rõ ràng, null===undefinedfalsebởi vì sử dụng khi bạn sử dụng ===nó cũng so sánh các loại .
Guyarad

1

Về cơ bản, Undinite là một biến toàn cục mà javascript tạo ra tại thời điểm chạy cho dù null có nghĩa là không có giá trị nào được gán cho biến đó (thực ra null là một đối tượng).

Hãy lấy một ví dụ:

        var x;  //we declared a variable x, but no value has been assigned to it.
        document.write(x) //let's print the variable x

Không xác định đó là những gì bạn sẽ nhận được như là đầu ra.

Hiện nay,

        x=5;
        y=null;
        z=x+y;

và bạn sẽ nhận được 5 là đầu ra. Đó là sự khác biệt chính giữa Không xác địnhnull


1

null - Đó là một giá trị gán, được sử dụng với biến để biểu thị không có giá trị (nó là một đối tượng).

không xác định - Đây là một biến không có bất kỳ giá trị nào được gán cho nó, vì vậy JavaScript sẽ gán một giá trị không xác định cho nó (đó là một kiểu dữ liệu).

không khai báo - Nếu một biến hoàn toàn không được tạo, nó được gọi là không khai báo.


1

Kiểm tra này. Đầu ra đáng giá ngàn lời nói.

var b1 = document.getElementById("b1");

checkif("1, no argument"                        );
checkif("2, undefined explicitly",     undefined);
checkif("3, null explicitly",               null);
checkif("4, the 0",                            0);
checkif("5, empty string",                    '');
checkif("6, string",                    "string");
checkif("7, number",                      123456);

function checkif (a1, a2) {
	print("\ncheckif(), " + a1 + ":");
	if (a2 == undefined) {
		print("==undefined:    YES");
	} else {
		print("==undefined:    NO");
	}
	if (a2 === undefined) {
		print("===undefined:   YES");
	} else {
		print("===undefined:   NO");
	}
	if (a2 == null) {
		print("==null:         YES");
	} else {
		print("==null:         NO");
	}
	if (a2 === null) {
		print("===null:        YES");
	} else {
		print("===null:        NO");
	}
	if (a2 == '') {
		print("=='':           YES");
	} else {
		print("=='':           NO");
	}
	if (a2 === '') {
		print("==='':          YES");
	} else {
		print("==='':          NO");
	}
	if (isNaN(a2)) {
		print("isNaN():        YES");
	} else {
		print("isNaN():        NO");
	}
	if (a2) {
		print("if-?:           YES");
	} else {
		print("if-?:           NO");
	}
		print("typeof():       " + typeof(a2));
}

function print(v) {
	b1.innerHTML += v + "\n";
}
<!DOCTYPE html>
<html>
<body>
<pre id="b1"></pre>
</body>
</html>

Xem thêm:

Chúc mừng!


1
Từ điều này tôi thực sự đã học được rằng isNaN(null)trở lại false- điều làm tôi ngạc nhiên.
J. Bruni

0

Cả hai giá trị đặc biệt ngụ ý một trạng thái trống rỗng.

Sự khác biệt chính là không xác định đại diện cho giá trị của một biến chưa được khởi tạo, trong khi null thể hiện sự vắng mặt có chủ ý của một đối tượng.

Số biến được xác định, tuy nhiên, không được gán với giá trị ban đầu:

let number;
number; // => undefined

biến số không được xác định, biểu thị rõ ràng một biến chưa được khởi tạo

Khái niệm chưa được khởi tạo tương tự xảy ra khi một thuộc tính đối tượng không tồn tại được truy cập:

const obj = { firstName: 'Dmitri' };
obj.lastName; // => undefined

Vì thuộc tính lastName không tồn tại trong obj, JavaScript đánh giá chính xác obj.lastName thành không xác định.

Trong các trường hợp khác, bạn biết rằng một biến dự kiến ​​sẽ giữ một đối tượng hoặc một hàm để trả về một đối tượng. Nhưng vì một số lý do, bạn không thể khởi tạo đối tượng. Trong trường hợp như vậy null là một chỉ báo có ý nghĩa của một đối tượng bị thiếu.

Ví dụ: clone () là một hàm nhân bản một đối tượng JavaScript đơn giản. Hàm dự kiến ​​sẽ trả về một đối tượng:

function clone(obj) {
  if (typeof obj === 'object' && obj !== null) {
    return Object.assign({}, obj);
  }
  return null;
}
clone({name: 'John'}); // => {name: 'John'}
clone(15);             // => null
clone(null);           // => null

Tuy nhiên, clone () có thể được gọi với đối số không phải đối tượng: 15 hoặc null (hoặc nói chung là giá trị nguyên thủy, null hoặc không xác định). Trong trường hợp như vậy, hàm không thể tạo bản sao, vì vậy nó trả về null - chỉ báo của một đối tượng bị thiếu.

Toán tử typeof phân biệt giữa hai giá trị:

typeof undefined; // => 'undefined'
typeof null;      // => 'object'

Toán tử chất lượng nghiêm ngặt === phân biệt chính xác không xác định từ null:

let nothing = undefined;
let missingObject = null;
nothing === missingObject; // => false

0

Ngoài một ý nghĩa khác, còn có những khác biệt khác:

  1. Phá hủy đối tượng hoạt động khác nhau cho hai giá trị này:
    const { a = "default" } = { a: undefined }; // a is "default"
    const { b = "default" } = { b: null };      // b is null
  2. JSON.opesify () giữ nullnhưng bỏ quaundefined
    const json = JSON.stringify({ undefinedValue: undefined, nullValue: null });
    console.log(json); // prints {"nullValue":null}
  3. toán tử typeof
    console.log(typeof undefined); // "undefined"
    console.log(typeof null);      // "object" instead of "null"

-2

Nếu một biến không được khởi tạo thì nó không được xác định. không xác định không phải là một đối tượng. Ví dụ: var MyName; console.log (typeof MyName);

Kiểm tra nhật ký giao diện điều khiển trong công cụ phát triển, nó sẽ được in dưới dạng không xác định.

null là một đối tượng. Nếu bạn muốn một số biến là null thì null được sử dụng. Biến này tồn tại nhưng giá trị không được biết. Nó nên được gán cho một biến pro về mặt ngữ pháp. null không được tự động khởi tạo.

Ví dụ: var MyName = null; console.log (typeof MyName); Kiểm tra nhật ký csole trong công cụ phát triển, nó sẽ là một đối tượng.

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.