javascript - js数据类型mdn - 的区别




应该在JavaScript比较中使用哪个等于运算符(== vs===)? (20)

JSLint有时会给你修改内容的不切实际的理由。 =====具有完全相同的性能,如果类型已经相同。

仅当类型不相同时才更快,在这种情况下它不会尝试转换类型但直接返回false。

因此, 恕我直言, JSLint可能用于编写新代码,但应该不惜一切代价避免无用的过度优化。

意思是,当你知道a只能是一个字符串的事实时,没有理由在if (a == 'test')这样的检查中改变=====

修改大量代码会浪费开发人员和审阅者的时间并且什么都不会实现。

我正在使用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

平等比较:

操作者 ==

当两个操作数相等时返回true。在比较之前,操作数被转换为相同的类型。

>>> 1 == 1
true
>>> 1 == 2
false
>>> 1 == '1'
true

平等和类型比较:

操作者 ===

如果两个操作数相等且类型相同,则返回true。如果你比较这种方式通常会更好更安全,因为没有幕后类型的转换。

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

===运算符检查值以及变量的类型是否相等。

==运算符只是检查变量的值是否相等。


===运算符称为严格比较运算符,它与==运算符不同。

让我们采取2个变量a和b。

要使“a == b”评估为真,a和b需要是相同的值

“a === b”的情况下,a和b必须是相同的值,并且它的相同类型才能评估为真。

以下面的例子为例

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

总之 ; 使用==运算符可能会在您不希望它的情况下评估为true,因此使用===运算符会更安全。

在90%的使用场景中,使用哪一个并不重要,但是当你有一天意外行为时,知道差异就很方便了。


为什么==是如此不可预测?

将空字符串""与数字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();
}

那么这是什么意思?

这意味着==很复杂。

因为它很复杂,所以很难知道当你使用它时会发生什么。

这意味着你最终可能会遇到错误。

所以这个故事的寓意是......

让你的生活变得简单。

使用===而不是==

结束。


null和undefined是虚无,也就是说,

var a;
var b = null;

在这里ab没有价值观。然而,0,false和''都是值。所有这些之间的共同点是,它们都是假值,这意味着它们都满足虚假条件。

因此,0,false和''一起形成一个子组。另一方面,null和undefined形成第二个子组。检查下图中的比较。null和undefined会相等。其他三个将彼此相等。但是,它们都被视为JavaScript中的虚假条件。

这与任何对象(如{},数组等)相同,非空字符串和布尔值都是真实的条件。但是,他们都不平等。


一个有趣的图示表示=====之间的相等比较。

资料来源: dorey.github.io/JavaScript-Equality-Tabledorey.github.io/JavaScript-Equality-Table

var1 === var2

当使用===进行JavaScript相等测试时,一切都是原样。 在评估之前没有任何东西被转换。

var1 == var2

使用==进行JavaScript相等测试时,会发生一些时髦的转换。

故事的道德启示:

除非您完全理解使用==的转换,否则请使用===


严格相等的Javascript执行流程图/比较'==='

用于非严格相等/比较的Javascript执行流程图'=='


使用==运算符( Equality

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

使用===运算符( 标识

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

这是因为等于运算符==确实类型强制 ,这意味着解释器隐式地尝试在比较之前转换值。

另一方面, 身份运算符===不进行类型强制 ,因此在比较时不会转换值。


在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

问题是你很容易遇到麻烦,因为JavaScript有很多隐含的转换意味着......

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

这很快就会成为一个问题。隐式转换为“邪恶”的原因的最佳样本可以从MFC / C ++中的代码中获取,由于从CString到HANDLE的隐式转换,它实际上将被编译,这是一个指针typedef类型...

CString x;
delete x;

显然在运行时期间有很多未定义的东西......

谷歌在C ++和STL进行隐式转换以获得一些反对它的论据......



前两个答案都提到==表示平等,===表示身份。不幸的是,这种说法不正确。

如果==的两个操作数都是对象,则比较它们以查看它们是否是同一个对象。如果两个操作数都指向同一个对象,则等于运算符返回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