a

Câu hỏi Mà bằng toán tử (== vs ===) nên được sử dụng trong so sánh JavaScript?


Tôi đang sử dụng JSLint đi qua JavaScript và trả lại nhiều đề xuất để thay thế == (hai bằng dấu) với === (ba bằng dấu) khi làm những việc như so sánh idSele_UNVEHtype.value.length == 0 bên trong của một if tuyên bố.

Có lợi ích hiệu suất để thay thế không == với ===?

Bất kỳ cải tiến hiệu suất nào cũng sẽ được hoan nghênh khi có nhiều toán tử so sánh tồn tại.

Nếu không có chuyển đổi loại nào xảy ra, sẽ có hiệu suất vượt trội hơn ==?


5674
2017-12-11 14:19


gốc


Ai có thể quan tâm đến cùng một chủ đề === vs ==, nhưng trong PHP, có thể đọc ở đây: stackoverflow.com/questions/2401478/why-is-faster-than-in-php/… - Marco Demaio
Chỉ trong trường hợp bất cứ ai đã tự hỏi vào năm 2012: === Là đường nhanh hơn so với ==. jsperf.com/comparison-of-comparisons - Ry-♦
@minitech nó nên được như nó không làm loại chuyển đổi - Umur Kontacı
@minitech, tôi nghi ngờ bất cứ ai sẽ làm cho ứng dụng của họ đáng chú ý nhanh hơn bằng cách sử dụng === kết thúc ==. Trên thực tế, điểm chuẩn không cho thấy sự khác biệt lớn giữa cả hai trên các trình duyệt hiện đại. Cá nhân, tôi thường sử dụng == ở khắp mọi nơi trừ khi tôi thực sự cần sự bình đẳng nghiêm ngặt. - this.lau_
@johndodo: Tối ưu hóa sớm chỉ là một điều vì mã được tối ưu hóa có thể ít lý tưởng hơn từ quan điểm bảo trì và khả năng đọc, nhưng nếu tính năng chuyển đổi kiểu của == không cần thiết, việc sử dụng === thay vào đó là thực hành tốt, không tối ưu hóa sớm. Không có gì về === làm giảm khả năng bảo trì hoặc khả năng đọc mã. - Robert Harvey♦


Các câu trả lời:


Nhận dạng (===) toán tử hoạt động giống hệt nhau (==) nhà điều hành ngoại trừ không có chuyển đổi loại nào được thực hiện và các loại phải giống nhau để được xem là bằng nhau.

Tài liệu tham khảo: Hướng dẫn Javascript: Toán tử so sánh

Các == toán tử sẽ so sánh với bình đẳng sau khi thực hiện bất kỳ chuyển đổi loại cần thiết nào. Các === nhà điều hành sẽ không phải thực hiện chuyển đổi, vì vậy nếu hai giá trị không cùng loại === sẽ đơn giản trở lại false. Cả hai đều đều nhanh chóng.

Để trích dẫn tuyệt vời của Douglas Crockford JavaScript: Các bộ phận tốt,

JavaScript có hai bộ toán tử bình đẳng: === và !==và cặp song sinh độc ác của họ == và !=. Những người tốt làm việc theo cách bạn mong đợi. Nếu hai toán hạng cùng loại và có cùng giá trị, thì === sản xuất true và !== sản xuất false. Cặp song sinh độc ác làm điều đúng khi các toán hạng có cùng loại, nhưng nếu chúng thuộc loại khác nhau, chúng cố gắng ép buộc các giá trị. các quy tắc mà họ làm rất phức tạp và không đáng kể. Đây là một số trường hợp thú vị:

'' == '0'           // false
0 == ''             // true
0 == '0'            // true

false == 'false'    // false
false == '0'        // true

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

' \t\r\n ' == 0     // true

Việc thiếu sự chuyển đổi là đáng báo động. Lời khuyên của tôi là không bao giờ sử dụng cặp song sinh độc ác. Thay vào đó, hãy luôn sử dụng === và !==. Tất cả các so sánh chỉ hiển thị sản phẩm false với === nhà điều hành.


Cập nhật:

Một điểm tốt đã được đưa lên bởi @Casebash trong các ý kiến ​​và trong @Phillipe Laybaert's  câu trả lời liên quan đến các loại tham chiếu. Đối với các loại tham chiếu == và === hành động nhất quán với nhau (trừ trường hợp đặc biệt).

var a = [1,2,3];
var b = [1,2,3];

var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };

var e = "text";
var f = "te" + "xt";

a == b            // false
a === b           // false

c == d            // false
c === d           // false

e == f            // true
e === f           // true

Trường hợp đặc biệt là khi bạn so sánh một chữ với một đối tượng đánh giá cùng một chữ, do toString hoặc là valueOf phương pháp. Ví dụ, hãy xem xét sự so sánh của một chuỗi ký tự bằng một đối tượng chuỗi được tạo bởi String constructor.

"abc" == new String("abc")    // true
"abc" === new String("abc")   // false

Ở đây == toán tử đang kiểm tra các giá trị của hai đối tượng và quay trở lại true, nhưng === đang thấy rằng họ không cùng loại và quay trở lại false. Cái nào đúng? Điều đó thực sự phụ thuộc vào những gì bạn đang cố gắng so sánh. Lời khuyên của tôi là bỏ qua câu hỏi hoàn toàn và không sử dụng String constructor để tạo các đối tượng chuỗi.

Tài liệu tham khảo
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3


5728
2017-12-11 14:25



=== không nhanh hơn nếu các kiểu giống nhau. Nếu các loại không giống nhau, === sẽ nhanh hơn vì nó sẽ không cố gắng thực hiện chuyển đổi. - Bill the Lizard
=== sẽ không bao giờ chậm hơn ==. Cả hai đều thực hiện kiểm tra kiểu, vì vậy === không thực hiện thêm bất kỳ điều gì so với ==, nhưng việc kiểm tra loại có thể cho phép === thoát sớm hơn khi các loại không giống nhau. - Bill the Lizard
Thay thế tất cả == /! = Bằng === /! == tăng kích thước của tệp js, sẽ mất nhiều thời gian hơn để tải. :) - Marco Demaio
"... các quy tắc mà họ làm điều đó phức tạp và không đáng kể ..." Bây giờ những tuyên bố đó khiến bạn cảm thấy an toàn khi lập trình ... - Johan
Đôi khi hệ thống kiểu của JavaScript khiến tôi muốn chạy đi la hét. - Yawar


Sử dụng ==nhà điều hành (Bình đẳng)

true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2;  //true, because "2" is converted to 2 and then compared

Sử dụng ===nhà điều hành (Danh tính)

true === 1; //false
"2" === 2;  //false

Điều này là do toán tử bình đẳng == gõ ép buộc, nghĩa là trình thông dịch ngầm cố gắng chuyển đổi các giá trị trước khi so sánh.

Mặt khác, nhà điều hành danh tính === không làm ép buộcvà do đó không chuyển đổi các giá trị khi so sánh.


990
2018-06-05 19:11



@Software Monkey: không dành cho các loại giá trị (số, boolean, ...) - Philippe Leybaert
type coercion vs type casting vs type convertion: stackoverflow.com/questions/8857763/… - Adrien Be
Vì không ai đề cập đến Bảng bình đẳng Javascript, ở đây là: dorey.github.io/JavaScript-Equality-Table - blaze
Trong câu lệnh đầu tiên, bạn có chắc rằng 'true' được chuyển thành 1 và không 1 được chuyển thành true? - Shadi Namrouti
Các thuật ngữ "bình đẳng" và "danh tính" đến từ đâu? Tiêu chuẩn không sử dụng các điều khoản đó. Nó gọi == "bình đẳng trừu tượng" và nó gọi === "bình đẳng nghiêm ngặt". Đã gọi điện thoại == bất kỳ loại "bình đẳng" là IMHO khủng khiếp, vì nó không phải là transitive, nhưng tại sao phân? Tôi có nhiều vấn đề hơn với "danh tính" mặc dù; Tôi nghĩ rằng thuật ngữ đó là khá sai lầm, mặc dù nó "hoạt động". Nhưng nghiêm túc, người đặt ra thuật ngữ "danh tính"? Tôi tìm kiếm tiêu chuẩn và không thể tìm thấy nó. - Ray Toal


Trong các câu trả lời ở đây, tôi không đọc bất cứ điều gì về những gì công bằng có nghĩa. Một số sẽ nói rằng === có nghĩa bằng và cùng loạinhưng điều đó không thực sự đúng. Nó thực sự có nghĩa là cả hai toán hạng đều tham chiếu cùng một đối tượnghoặc trong trường hợp loại giá trị, có cùng giá trị.

Vì vậy, hãy lấy đoạn mã sau:

var a = [1,2,3];
var b = [1,2,3];
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Tương tự ở đây:

var a = { x: 1, y: 2 };
var b = { x: 1, y: 2 };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Hoặc thậm chí:

var a = { };
var b = { };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Hành vi này không phải lúc nào cũng rõ ràng. Có nhiều câu chuyện hơn là bằng nhau và cùng loại.

Quy tắc là:

Đối với các loại giá trị (số):
a === b trả về true nếu a và b có cùng giá trị và cùng loại

Đối với các loại tham chiếu:
a === b trả về true nếu a và b tham chiếu chính xác cùng một đối tượng

Đối với chuỗi:
a === b trả về true nếu a và b là cả hai chuỗi và chứa các ký tự giống hệt nhau


Strings: trường hợp đặc biệt ...

Chuỗi không phải là loại giá trị, nhưng trong Javascript, chúng hoạt động giống như các loại giá trị, vì vậy chúng sẽ "bằng nhau" khi các ký tự trong chuỗi giống nhau và khi chúng có cùng độ dài (như được giải thích trong quy tắc thứ ba)

Bây giờ nó trở nên thú vị:

var a = "12" + "3";
var b = "123";

alert(a === b); // returns true, because strings behave like value types

Nhưng làm thế nào về điều này ?:

var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

Tôi nghĩ chuỗi hoạt động như các loại giá trị? Vâng, nó phụ thuộc vào người bạn yêu cầu ... Trong trường hợp này a và b không cùng loại. a thuộc loại Object, trong khi b thuộc loại string. Chỉ cần nhớ rằng việc tạo một đối tượng chuỗi bằng cách sử dụng String constructor tạo ra kiểu gì đó Object hoạt động như một chuỗi hầu hết thời gian.


546
2018-05-05 05:21



activa: Tôi sẽ làm rõ, rằng các chuỗi chỉ bằng nhau khi chúng là chữ. Chuỗi mới ("abc") === "abc" là sai (theo nghiên cứu của tôi). - Lawrence Dol
new Number() == "0". Cũng trong Firefox: (function(){}) == "function () {\n}" - Thomas Eding
Cảm ơn bạn đã giải thích lý do new String("123") !== "123". Họ là những loại khác nhau. Đơn giản, nhưng khó hiểu. - styfle
String các đối tượng hoạt động như chuỗi bất kỳ đối tượng nào khác. new String không bao giờ nên được sử dụng, vì điều đó không tạo ra chuỗi thực. Một chuỗi thực và có thể được tạo bằng chuỗi ký tự hoặc gọi điện String như một hàm không có  new, ví dụ: String(0); //"0", Real string, not an object - Esailija
Nhưng trong trường hợp bạn chi tiết, toán tử "==" hoạt động giống hệt nhau. - Yaron Levi


Một đại diện hình ảnh thú vị về sự so sánh bình đẳng giữa == và ===.

Nguồn: http://dorey.github.io/JavaScript-Equality-Table/


var1 === var2

Khi đang sử dụng === để kiểm tra bình đẳng JavaScript, mọi thứ đều như vậy. Không có gì được chuyển đổi trước khi được đánh giá.

Equality evaluation of === in JS


var1 == var2

Khi đang sử dụng == để kiểm tra bình đẳng JavaScript, một số   chuyển đổi sôi nổi diễn ra.

Equality evaluation of == in JS

Đạo đức của câu chuyện: 

Sử dụng === trừ khi bạn hoàn toàn hiểu được   chuyển đổi diễn ra với ==.


522
2017-11-28 18:18



@mfeineis nghĩa là === hoặc! == thay vì == hoặc! =. Không muốn nhầm lẫn các lập trình viên mới;) - katalin_2003
@ katalin_2003 oops, bạn đúng === và! ==, d ** n lỗi chính tả, thx - mfeineis
@ vsync: Wow, những người lạm dụng JQuery cũng nói điều tương tự. Tôi không bao giờ biết bạn có nhiều điểm chung ...
@vsync: Nếu bạn thực sự không muốn các loại bằng nhau, bạn Nên sử dụng ba bằng! - SNag
Câu trả lời này rất hữu ích! - skiabox


Hãy để tôi thêm lời khuyên này:

Nếu nghi ngờ, hãy đọc đặc điểm kỹ thuật! 

ECMA-262 là đặc tả cho một ngôn ngữ kịch bản mà JavaScript là một phương ngữ. Tất nhiên trong thực tế, điều quan trọng hơn là các trình duyệt quan trọng nhất hoạt động như thế nào so với định nghĩa bí truyền về cách thức xử lý của một thứ gì đó. Nhưng nó là hữu ích để hiểu tại sao Chuỗi mới ("a")! == "a".

Xin vui lòng cho tôi giải thích làm thế nào để đọc các đặc điểm kỹ thuật để làm rõ câu hỏi này. Tôi thấy rằng trong chủ đề rất cũ này, không ai có câu trả lời cho hiệu ứng rất kỳ lạ. Vì vậy, nếu bạn có thể đọc một đặc điểm kỹ thuật, điều này sẽ giúp bạn trong nghề của bạn rất nhiều. Nó là một kỹ năng có được. Vì vậy, chúng ta hãy tiếp tục.

Tìm kiếm tệp PDF cho === đưa tôi đến trang 56 của đặc tả: 11.9.4. Toán tử ngang bằng (===), và sau khi lội qua cụ thể tôi tìm thấy:

11.9.6 Thuật toán so sánh chính xác nghiêm ngặt
  So sánh x === y, trong đó x và y là các giá trị, tạo ra thật hoặc là sai. So sánh như vậy được thực hiện như sau:
  1. Nếu Type (x) khác với Type (y), return sai.
  2. Nếu Type (x) là Undefined, return thật.
  3. Nếu Type (x) là Null, trả về thật.
  4. Nếu Type (x) không phải là Number, chuyển sang bước 11.
  5. Nếu x là NaN, trở về sai.
  6. Nếu y là NaN, trở về sai.
  7. Nếu x có giá trị số giống y, trả về thật.
  8. Nếu x là +0 và y là −0, trả về thật.
  9. Nếu x là −0 và y là +0, trả về thật.
  10. Return sai.
  11. Nếu Type (x) là String, sau đó trả về thật nếu x và y chính xác là cùng một chuỗi các ký tự (cùng độ dài và các ký tự giống nhau trong các vị trí tương ứng); nếu không, trả lại sai.
  12. Nếu Type (x) là Boolean, trả về thật nếu x và y là cả hai thật hoặc cả hai sai; nếu không, trả lại sai.
  13. Trở lại thật nếu x và y tham chiếu đến cùng một đối tượng hoặc nếu chúng tham chiếu đến các đối tượng được nối với nhau (xem 13.1.2). Nếu không, trả lại sai.

Thú vị là bước 11. Có, các chuỗi được coi là các loại giá trị. Nhưng điều này không giải thích tại sao Chuỗi mới ("a")! == "a". Chúng tôi có trình duyệt không phù hợp với ECMA-262 không?

Không quá nhanh!

Hãy kiểm tra các loại toán hạng. Hãy thử nó cho chính mình bằng cách gói chúng vào loại(). Tôi thấy rằng Chuỗi mới ("a") là một đối tượng và bước 1 được sử dụng: return sai nếu các loại khác nhau.

Nếu bạn tự hỏi tại sao Chuỗi mới ("a") không trả lại một chuỗi, làm thế nào về một số bài tập đọc một đặc điểm kỹ thuật? Chúc vui vẻ!


Aidiakapi đã viết điều này trong một bình luận dưới đây:

Từ đặc điểm kỹ thuật

11.2.2 Toán tử mới:

Nếu Type (constructor) không phải là Object, hãy ném một ngoại lệ TypeError.

Với các từ khác, nếu String không thuộc kiểu Object thì nó không thể được sử dụng với toán tử mới.

Mới luôn trả về một đối tượng, ngay cả đối với Chuỗi các nhà xây dựng cũng vậy. Và than ôi! Các ngữ nghĩa giá trị cho chuỗi (xem bước 11) bị mất.

Và điều này cuối cùng có nghĩa là: Chuỗi mới ("a")! == "a".


250
2018-05-12 12:58



Kết quả của Type (x) được ngụ ý là giống như typeof? - Dfr


Trong PHP và JavaScript, nó là một toán tử bình đẳng nghiêm ngặt. Có nghĩa là, nó sẽ so sánh cả hai loại và giá trị.


93
2017-12-25 11:17



@ David: chính xác. Đó là lý do tại sao câu trả lời này không chính xác (hoặc thậm chí là sai) - Philippe Leybaert
@David var a = {}, b = {};  a == b trả về false. - nyuszika7h
Có: Hai khác nhau các đối tượng có cùng loại và giá trị so sánh sai, tức là câu trả lời này chỉ là sai. Tại sao nó có 50 upvotes? - alexis
Tôi nhận ra điều này là cũ, nhưng để làm rõ tại sao câu trả lời này vẫn "đúng" là bởi vì trong ví dụ var a = {}, b = {}; Trong khi cả hai a và b thực sự là một đối tượng, nhưng chúng không phải là tương tự giá trị, kỹ thuật nói. họ đang khác nhau trường hợp. Lưu ý rằng so sánh các trường hợp hoạt động khác với so sánh các nguyên thủy. Mà có lẽ thêm vào sự nhầm lẫn này. Bạn sẽ thấy hành vi so sánh tương tự nếu bạn sử dụng phiên bản thể hiện của các kiểu dữ liệu nguyên thủy. Ví dụ new String('asdf') hoặc là new Number(5). Ví dụ: new Number(5) == new Number(5) là sai, mặc dù chúng giữ cùng một giá trị. - Norman Breau


Tôi đã thử nghiệm điều này trong Firefox với Firebug sử dụng mã như thế này:

console.time("testEquality");
var n = 0;
while(true) {
    n++;
    if(n==100000) 
        break;
}
console.timeEnd("testEquality");

console.time("testTypeEquality");
var n = 0;
while(true) {
    n++;
    if(n===100000) 
        break;
}
console.timeEnd("testTypeEquality");

Kết quả của tôi (được kiểm tra năm lần và tính trung bình):

==: 115.2
===: 114.4

Vì vậy, tôi muốn nói rằng sự khác biệt nhỏ (đây là hơn 100.000 lần lặp lại, hãy nhớ) là không đáng kể. Hiệu suất không phải một lý do để làm ===. Loại an toàn (tốt, an toàn như bạn sẽ nhận được trong JavaScript), và chất lượng mã là.


88
2018-05-12 12:58



Hơn an toàn loại bạn muốn tính chính xác hợp lý - đôi khi bạn muốn mọi thứ trở nên trung thực khi == không đồng ý. - rpjohnst
Bây giờ, làm thế nào để so sánh khi có một loại thực sự coersion cho == nhà điều hành? Hãy nhớ rằng, đó là khi có hiệu suất tăng. - Hubert OG
Sự khác biệt chính khi kiểm tra đúng cho những lý do nói trên của nhanh hơn để chỉ kiểm tra bất đẳng thức loại. jsfiddle.net/4jhuxkb2 - Doug Morrow


Trong JavaScript nó có nghĩa là cùng một giá trị và kiểu.

Ví dụ,

4 == "4" // will return true

nhưng

4 === "4" // will return false 

84
2017-12-11 14:58





Các === toán tử được gọi là toán tử so sánh nghiêm ngặt, làm khác với == nhà điều hành.

Cho phép lấy 2 vars a và b.

Dành cho "a == b" để đánh giá đúng a và b cần phải là cùng giá trị.

Trong trường hợp "a === b" a và b phải là cùng giá trị và cũng là cùng loại để nó được đánh giá là đúng.

Lấy ví dụ sau

var a = 1;
var b = "1";

if (a == b) //evaluates to true as a and b are both 1
{
    alert("a == b");
}

if (a === b) //evaluates to false as a is not the same type as b
{
    alert("a === b");
}

Tóm tắt; sử dụng == toán tử có thể đánh giá đúng trong các tình huống mà bạn không muốn nó sử dụng === nhà điều hành sẽ an toàn hơn.

Trong kịch bản sử dụng 90%, nó sẽ không quan trọng mà bạn sử dụng, nhưng nó là tiện dụng để biết sự khác biệt khi bạn nhận được một số hành vi bất ngờ một ngày.


73
2018-05-12 12:58



Đây là bài viết chi tiết về so sánh === so với == - Zaheer Ahmed


Nó sẽ kiểm tra xem các mặt giống nhau có bằng nhau không kiểu cũng như giá trị.

Thí dụ:

'1' === 1 // will return "false" because `string` is not a `number`

Ví dụ phổ biến:

0 == ''  // will be "true", but it's very common to want this check to be "false"

Một ví dụ phổ biến khác:

null == undefined // returns "true", but in most cases a distinction is necessary

64
2017-09-05 13:53



cũng thế, 'string' !== 'number' - Homer


Biểu đồ luồng thực thi Javascript cho sự bình đẳng nghiêm ngặt / So sánh '==='

Javascript strict equality

Biểu đồ luồng thực thi Javascript cho sự bình đẳng / so sánh không nghiêm ngặt '=='

Javascript non equality


61
2017-08-09 16:50



Tôi không hiểu tại sao string mũi tên đang chỉ vào hộp lớn màu xám, có nghĩa là nó có nghĩa là ngắt được đúc chuỗi đến một số? - vsync
@vsync Nó chỉ vào tùy chọn chuỗi trong hộp màu xám, tức là chuỗi -> # || NaN. Javascript không phải là một ngôn ngữ kịch bản kiểu, tức là nó có thể có bất kỳ kiểu biến nào. Vì vậy, nó được chỉ vào hộp màu xám đó. - Samar Panda
Tôi chỉ đơn giản hỏi nếu nó là cho mục đích đúc kể từ khi string được cho là so sánh với một loại number, do đó, ngắt xem xét những gì chuỗi nên được so sánh và đúc chuỗi cho phù hợp? - vsync
Hộp màu xám lớn là gì ToNumber sẽ trở lại khi được cung cấp các loại khác nhau, vì vậy nếu nó được đưa ra một chuỗi nó sẽ chỉ chọn tùy chọn cuối cùng (và chuyển đổi nó thành một số). == sử dụng ToNumber chỉ trong trường hợp string == number hoặc là boolean == anything ở trên (và chỉ trên string/boolean). Điều này có nghĩa là == sẽ không bao giờ chuyển đổi undefined hoặc là null mặc dù họ đang ở trong hộp màu xám. (Đối với bất kỳ sự kết hợp của một trong hai undefined hoặc là null hoặc cả hai, == sẽ luôn quay trở lại true. Ngoài ra, cho dù giá trị ở bên trái hay bên phải không quan trọng, == (và ===) sẽ trả về cùng một kết quả.) - user2033427