javascript意思




應該在JavaScript比較中使用哪個等於運算符(== vs===)? (20)

我正在使用JSLint來通過JavaScript,並且在執行諸如比較idSele_UNVEHtype.value.length == 0類的內容時返回了許多建議來替換== (兩個等號) === (三個等號)聲明。

===替換==是否有性能優勢?

任何性能改進都會受到歡迎,因為存在許多比較運算符

如果沒有進行類型轉換,那麼性能會超過==嗎?


JavaScript === vs ==

0==false   // true
0===false  // false, because they are of a different type
1=="1"     // true, auto type coercion
1==="1"    // false, because they are of a different type

identity( === )運算符的行為與equality( == )運算符的行為相同,但不進行類型轉換,並且類型必須相同才能被視為相等。

參考: Javascript教程:比較運算符

在執行任何必要的類型轉換後==運算符將比較相等性。 ===運算符不會進行轉換,因此如果兩個值不是同一類型===將只返回false 。 兩者都同樣快。

引用Douglas Crockford的優秀JavaScript:The Good Parts

JavaScript有兩組相等運算符: ===!== ,它們的邪惡雙胞胎==!= 。 優秀的工作方式與您期望的方式相同。 如果兩個操作數具有相同的類型且具有相同的值,則===生成true並且!==生成false 。 當操作數屬於同一類型時,邪惡的雙胞胎做正確的事,但如果它們屬於不同的類型,它們會試圖強迫價值觀。 他們這樣做的規則是複雜和不可取的。 這些是一些有趣的案例:

'' == '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

缺乏傳遞性令人震驚。 我的建議是永遠不要使用邪惡的雙胞胎。 相反,始終使用===!== 。 剛顯示的所有比較都與===運算符產生false

更新:

@Casebash在評論和@Phillipe Laybaert關於參考類型的 answer中提出了一個很好的觀點。 對於引用類型, =====彼此一致地行動(特殊情況除外)。

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

特殊情況是,當您將文字與評估為同一文字的對象進行比較時,由於其toStringvalueOf方法。 例如,考慮將字符串文字與String構造函數創建的字符串對象進行比較。

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

這裡==運算符正在檢查兩個對象的值並返回true ,但===看到它們不是同一類型並返回false 。 哪一個是正確的? 這真的取決於你想要比較的東西。 我的建議是完全繞過這個問題,不要使用String構造函數來創建字符串對象。

參考
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3


===運算符檢查值以及變量的類型是否相等。

==運算符只是檢查變量的值是否相等。


等於比較運算符==令人困惑,應該避免。

如果你必須忍受它,那麼請記住以下三件事:

  1. 它不具有傳遞性: (a == b)(b == c)不會導致(a == c)
  2. 它與否定是相互排斥的: (a == b)(a!= b)總是保持相反的布爾值,所有a和b。
  3. 如有疑問,請通過以下真值表了解:

JAVASCRIPT中的等號運算符真值表

  • 表中的每一行都是一組3個相互“相等”的值,這意味著它們中的任何2個值都相等,使用等於==符號*

** STRANGE:請注意,第一列中的任何兩個值在這個意義上都不相等。**

''       == 0 == false   // Any two values among these 3 ones are equal with the == operator
'0'      == 0 == false   // Also a set of 3 equal values, note that only 0 and false are repeated
'\t'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\r'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\n'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\t\r\n' == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

null == undefined  // These two "default" values are not-equal to any of the listed values above
NaN                // NaN is not equal to any thing, even to itself.

是! 這非常重要。

===運算符在javascript中檢查值以及鍵入 where ==運算符只檢查值(如果需要,進行類型轉換)

你可以輕鬆測試它。 將以下代碼粘貼到HTML文件中,然後在瀏覽器中打開它

<script>

function onPageLoad()
{
    var x = "5";
    var y = 5;
    alert(x === 5);
};

</script>

</head>

<body onload='onPageLoad();'>

你會在警報中得到' '。 現在將onPageLoad()方法修改為alert(x == 5); 你會成真的


為什麼==是如此不可預測?

將空字符串""與數字0 0進行比較時,您會得到什麼?

true

是的,根據==一個空字符串是正確的,數字零是同一時間。

它並沒有結束,這是另一個:

'0' == false // true

數組的事情變得非常奇怪。

[1] == true // true
[] == false // true
[[]] == false // true
[0] == false // true

然後用字符串怪異

[1,2,3] == '1,2,3' // true - REALLY?!
'\r\n\t' == 0 // true - Come on!

情況變得更糟:

什麼時候不相等?

let A = ''  // empty string
let B = 0   // zero
let C = '0' // zero string

A == B // true - ok... 
B == C // true - so far so good...
A == C // **FALSE** - Plot twist!

讓我再說一遍:

(A == B) && (B == C) // true
(A == C) // **FALSE**

而這只是你用原語獲得的瘋狂東西。

當你使用==對象時,這是一個全新的瘋狂程度。

此時你可能想知道......

為什麼會這樣?

嗯,這是因為不像“三等於”( === ),只檢查兩個值是否相同。

==做了很多其他的事情

它具有對函數的特殊處理,對空值的特殊處理,未定義,字符串,您可以對其進行命名。

這很古怪。

事實上,如果你試圖寫一個做==的函數,它會看起來像這樣:

function isEqual(x, y) { // if `==` were a function
    if(typeof y === typeof x) return y === x;
    // treat null and undefined the same
    var xIsNothing = (y === undefined) || (y === null);
    var yIsNothing = (x === undefined) || (x === null);

    if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing);

    if(typeof y === "function" || typeof x === "function") {
        // if either value is a string 
        // convert the function into a string and compare
        if(typeof x === "string") {
            return x === y.toString();
        } else if(typeof y === "string") {
            return x.toString() === y;
        } 
        return false;
    }

    if(typeof x === "object") x = toPrimitive(x);
    if(typeof y === "object") y = toPrimitive(y);
    if(typeof y === typeof x) return y === x;

    // convert x and y into numbers if they are not already use the "+" trick
    if(typeof x !== "number") x = +x;
    if(typeof y !== "number") y = +y;
    // actually the real `==` is even more complicated than this, especially in ES6
    return x === y;
}

function toPrimitive(obj) {
    var value = obj.valueOf();
    if(obj !== value) return value;
    return obj.toString();
}

那麼這是什麼意思?

這意味著==很複雜。

因為它很複雜,所以很難知道當你使用它時會發生什麼。

這意味著你最終可能會遇到錯誤。

所以這個故事的寓意是......

讓你的生活變得簡單。

使用===而不是==

結束。


一個有趣的圖示表示=====之間的相等比較。

資料來源: dorey.github.io/JavaScript-Equality-Tabledorey.github.io/JavaScript-Equality-Table

var1 === var2

當使用===進行JavaScript相等測試時,一切都是原樣。 在評估之前沒有任何東西被轉換。

var1 == var2

使用==進行JavaScript相等測試時,會發生一些時髦的轉換。

故事的道德啟示:

除非您完全理解使用==的轉換,否則請使用===


一個簡單的例子是

2 == '2'  -> true, values are SAME because of type conversion.

2 === '2'  -> false, values are NOT SAME because of no type conversion.

只是

==裝置的比較操作數之間 type conversion

===意味著沒有操作數之間的比較 type conversion

javaScript中的類型轉換意味著javaScript會自動將任何其他數據類型轉換為字符串數據類型。

例如:

123=='123'   //will return true, because JS convert integer 123 to string '123'
             //as we used '==' operator 

123==='123' //will return false, because JS do not convert integer 123 to string 
            //'123' as we used '===' operator 

問題是你很容易遇到麻煩,因為JavaScript有很多隱含的轉換意味著......

var x = 0;
var isTrue = x == null;
var isFalse = x === null;

這很快就會成為一個問題。隱式轉換為“邪惡”的原因的最佳樣本可以從MFC / C ++中的代碼中獲取,由於從CString到HANDLE的隱式轉換,它實際上將被編譯,這是一個指針typedef類型...

CString x;
delete x;

顯然在運行時期間有很多未定義的東西......

谷歌在C ++和STL進行隱式轉換以獲得一些反對它的論據......


在JavaScript中,它意味著相同的值和類型。

例如,

4 == "4" // will return true

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

在PHP和JavaScript中,它是一個嚴格的相等運算符。 這意味著,它將比較類型和值。


在您的使用中,這兩個操作之間不可能有任何性能差異。 沒有要進行類型轉換,因為兩個參數已經是同一類型。 兩個操作都將進行類型比較,然後進行值比較。


在這裡的答案中,我沒有讀到關於什麼是平等的意思。 有人會說===意味著相同和相同的類型 ,但事實並非如此。 它實際上意味著兩個操作數引用相同的對象 ,或者在值類型的情況下,具有相同的值

那麼,我們來看下面的代碼:

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

和這裡一樣:

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

甚至:

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

這種行為並不總是很明顯。 故事不僅僅是平等而且屬於同一類型。

規則是:

對於值類型(數字):
a === b如果ab具有相同的值且屬於同一類型,則返回true

對於參考類型:
如果ab引用完全相同的對象,則a === b返回true

對於字符串:
a === b如果ab都是字符串並且包含完全相同的字符,則返回true

字符串:特例......

字符串不是值類型,但在Javascript中它們的行為類似於值類型,因此當字符串中的字符相同且長度相同時(如第三條規則中所述),它們將“相等”

現在它變得有趣:

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

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

但是怎麼樣?:

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

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

我認為字符串的行為類似於值類型? 嗯,這取決於你問誰...在這種情況下,a和b不是同一類型。 a的類型為Object ,而b的類型為string 。 請記住,使用String構造函數創建一個字符串對象會創建一些Object類型的東西,它在大多數情況下都表現為字符串。


它檢查相同的邊是否在類型上相等。

例:

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

常見例子:

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

另一個常見例子:

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

我使用Firebug在Firefox中測試了這個,使用如下代碼:

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");

我的結果(每次測試五次並取平均值):

==: 115.2
===: 114.4

所以我要說微不足道的差異(這是超過100000次迭代,記得)可以忽略不計。 性能不是 ===的理由。 鍵入安全性(嗯,安全性與JavaScript相同),代碼質量也是如此。


這是一項嚴格的檢查測試。

這是一件好事,尤其是如果您在0和false之間進行檢查並且為null。

例如,如果您有:

$a = 0;

然後:

$a==0; 
$a==NULL;
$a==false;

所有都返回true,你可能不想要這個。假設您有一個函數可以返回數組的第0個索引,或者在失敗時返回false。如果您使用“==”false檢查,則可能會產生令人困惑的結果。

所以與上面相同,但嚴格的測試:

$a = 0;

$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false

* 運營商=== vs == *

1 == true    =>    true
true == true    =>    true
1 === true    =>    false
true === true    =>    true

前兩個答案都提到==表示平等,===表示身份。不幸的是,這種說法不正確。

如果==的兩個操作數都是對象,則比較它們以查看它們是否是同一個對象。如果兩個操作數都指向同一個對象,則等於運算符返回true。否則,兩者並不相等。

var a = [1, 2, 3];  
var b = [1, 2, 3];  
console.log(a == b)  // false  
console.log(a === b) // false  

在上面的代碼中,==和===都得到false,因為a和b不是同一個對象。

也就是說:如果==的兩個操作數都是對象,==的行為與===相同,這也意味著身份。這兩個運算符的本質區別在於類型轉換。==在檢查相等性之前進行轉換,但===沒有。








identity-operator