2010-05-26 51 views
104

Tôi đã phải viết một thói quen tăng giá trị của một biến bằng 1 nếu loại của nó là number và gán 0 cho biến nếu không, trong đó biến ban đầu là null hoặc undefined.Tại sao `null> = 0 && null <= 0` nhưng không phải` null == 0`?

Triển khai đầu tiên là v >= 0 ? v += 1 : v = 0 vì tôi nghĩ bất kỳ thứ gì không phải là số sẽ làm cho biểu thức số học sai, nhưng đã sai vì null >= 0 được đánh giá là đúng. Sau đó, tôi đã học được null hoạt động như 0 và các biểu thức sau đây được đánh giá là đúng.

  • null >= 0 && null <= 0
  • !(null < 0 || null > 0)
  • null + 1 === 1
  • 1/null === Infinity
  • Math.pow(42, null) === 1

Tất nhiên, null không phải là 0. null == 0 được đánh giá là false. Điều này làm cho biểu thức có vẻ như taut (v >= 0 && v <= 0) === (v == 0) sai.

Tại sao null như 0, mặc dù nó không thực sự là 0?

+3

Ông đang nói về Javascript. Ví dụ của bạn là bằng PHP. Trong toán tử PHP == so sánh các giá trị theo một cách đặc biệt. Bạn có thể làm cho một số so sánh thực sự điên rồ như "10" == "1e1" (đó là sự thật). Nếu bạn sử dụng toán tử ===, bạn sẽ nhận được một kết quả hoàn toàn khác vì nó kiểm tra xem loại khớp với giá trị hay không. Kiểm tra liên kết này: http://www.php.net/manual/en/language.operators.comparison.php – Pijusn

+0

Toán tử PHP '==' thực sự hoạt động theo cách "đặc biệt". –

+0

Nếu yêu cầu của bạn là bắt đầu đếm tại 1 thay vì 0, có một cách thực sự terse để tăng quầy mà ban đầu hoặc là 'null' hoặc' undefined': 'c = - ~ c // Kết quả trong 1 cho null/undefined; số gia tăng nếu đã là một số' –

Trả lời

160

câu hỏi thực sự của bạn dường như là:

Tại sao:

null >= 0; // true 

Nhưng:

null == 0; // false 

Điều gì thực sự xảy ra là điều hành Greater hơn hoặc bằng nhau (>=), thực hiện loại cưỡng chế (ToPrimitive), với một gợi ý loại Number, thực sự tất cả các toán tử quan hệ đều có hành vi này.

null được xử lý theo cách đặc biệt bởi Nhà điều hành bằng (==). Trong một ngắn gọn, nó chỉ coerces-undefined:

null == null; // true 
null == undefined; // true 

Value như false, '', '0', và [] này tùy thuộc vào số kiểu ép buộc, tất cả trong số họ ép buộc không.

Bạn có thể xem chi tiết bên trong của quy trình này trong The Abstract Equality Comparison AlgorithmThe Abstract Relational Comparison Algorithm.

Trong Tóm tắt:

  • Relational So sánh: nếu cả hai giá trị này được không gõ String, ToNumber được gọi trên cả hai. Điều này tương tự như việc thêm một + ở phía trước, đối với null coerces là 0.

  • So sánh bình đẳng: chỉ cuộc gọi ToNumber trên Chuỗi, số và Booleans.

+1

Hi CMS, theo cách giải thích null nguyên thủy của bạn là 0, vì vậy 0> = 0 trả về true và == trả về false.but theo thuật toán ecma Nếu Type (x) là Object và Type (y) là String hoặc Number , trả về kết quả của phép so sánh ToPrimitive (x) == y.then trong đó nó sẽ trả về true.please giải thích cho tôi –

+0

cho tôi câu trả lời không cung cấp câu trả lời * - 'null được xử lý theo cách đặc biệt bởi Bằng toán tử (==). Tóm lại, nó chỉ coerces để undefined: '- và cái gì? Bạn có thể giải thích, tại sao 'null> = 0'? :) –

+0

@bharathmuppa @ andrey-deineko: Câu trả lời còn lại của CMS có tại đây: [Thuật toán so sánh tương quan trừu tượng] (http://www.ecma-international.org/ecma-262/5.1/#sec -11.8.5) giải thích tại điểm 3. rằng nếu cả hai giá trị không phải là loại Chuỗi, ToNumber được gọi trên cả hai. Điều này cũng giống như thêm một '+' ở phía trước, mà cho null coerces để '0'. Bình đẳng chỉ gọi ToNumber trên Strings, Numbers và Booleans. –

7

Tôi muốn mở rộng các câu hỏi để cải thiện hơn nữa tầm nhìn của vấn đề:

null >= 0; //true 
null <= 0; //true 
null == 0; //false 
null > 0; //false 
null < 0; //false 

Nó chỉ làm cho không có ý nghĩa. Giống như ngôn ngữ của con người, những điều này cần được học bằng trái tim.

0

Tôi đã gặp vấn đề tương tự !!. Hiện tại, giải pháp duy nhất của tôi là tách biệt.

var a = null; 
var b = undefined; 

if (a===0||a>0){ } //return false !work! 
if (b===0||b>0){ } //return false !work! 

//but 
if (a>=0){ } //return true ! 
3

JavaScript có cả so sánh nghiêm ngặt và kiểu chuyển đổi

null >= 0; là đúng nhưng (null==0)||(null>0) là sai

null <= 0; là đúng nhưng (null==0)||(null<0) là sai

"" >= 0 cũng đúng

Đối với các so sánh trừu tượng quan hệ (< =,> =), các toán hạng đầu tiên được chuyển đổi thành nguyên thủy, sau đó sang cùng một loại, trước khi so sánh.

typeof null returns "object"

Khi loại là đối tượng javascript cố gắng stringify đối tượng (tức là null) các bước sau đây được thực hiện (ECMAScript 2015):

  1. Nếu PreferredType đã không được thông qua, chúng ta hãy hint được "mặc định ".
  2. Khác nếu PreferredTypehint Chuỗi, hãy để hint là "chuỗi".
  3. Khác PreferredTypehint Số, hãy để hint là "số".
  4. Hãy để exoticToPrimGetMethod(input, @@toPrimitive).
  5. ReturnIfAbrupt(exoticToPrim).
  6. Nếu exoticToPrim không được xác định, thì
    a) Hãy để kết quả là Call(exoticToPrim, input, «hint»).
    b) ReturnIfAbrupt(result).
    c) Nếu Type(result) không phải là Đối tượng, trả lại kết quả.
    d) Ném ngoại lệ TypeError.
  7. Nếu hint là "mặc định", hãy để hint là "số".
  8. Trả lại OrdinaryToPrimitive(input,hint).

Giá trị được phép cho gợi ý là "mặc định", "số" và "chuỗi". Các đối tượng ngày tháng, là duy nhất trong số đối tượng ECMAScript có sẵn trong đó chúng xử lý "mặc định" là tương đương với "chuỗi". Tất cả các đối tượng ECMAScript tích hợp khác xử lý "mặc định" là tương đương với "số". (ECMAScript 20.3.4.45)

Vì vậy, tôi nghĩ null chuyển thành 0.

Các vấn đề liên quan