我使用JSLint的经历JavaScript和它的返回许多建议更换==
(双等号)与===
(三级等号)做这样的事情进行比较时idSele_UNVEHtype.value.length == 0
内部的if
声明。
将==
替换为===
有性能优势吗?
由于存在许多比较运算符,因此任何性能改进都将受到欢迎。
如果没有进行类型转换,是否会获得==
以上的性能提升?
#1楼
JSLint有时会给您不切实际的理由来进行修改。 如果类型已经相同,则===
与==
具有完全相同的性能。
仅当类型不同时,它才更快,在这种情况下,它不尝试转换类型,而是直接返回false。
因此, 恕我直言, JSLint可能用于编写新代码,但应不惜一切代价避免无用的过度优化。
意思是,当您因为a只能是String的事实而知道if (a == 'test')
的检查时,没有理由将==
更改为===
。
修改大量代码会浪费开发人员和审阅者的时间,却一无所获。
#2楼
根据经验,我通常会使用===
代替==
(和!==
代替!=
)。
原因在上面的答案中进行了解释,Douglas Crockford对此也很清楚( JavaScript:The Good Parts )。
但是,只有一个例外 : == null
是检查“是否为null或未定义”的有效方法:
if( value == null ){
// value is either null or undefined
}
例如,jQuery 1.9.1使用此模式43次,因此eqnull
语法检查器甚至提供eqnull
松弛选项。
从jQuery样式指南 :
应该使用严格的相等性检查(===)来支持==。 唯一的例外是通过null检查undefined和null时。
// Check for both undefined and null values, for some important reason. undefOrNull == null;
#3楼
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
#4楼
让我补充一下这个建议:
如有疑问,请阅读规格 !
ECMA-262是JavaScript语言为方言的脚本语言规范。 当然,在实践中,最重要的浏览器的行为方式比对应该如何处理某些事物的深奥定义更为重要。 但是了解为什么新的String(“ a”)!==“ a”很有帮助。
请让我解释如何阅读规范以阐明此问题。 我看到,在这个非常老的话题中,没有人对非常奇怪的结果有任何答案。 因此,如果您可以阅读规范,这将对您的职业产生极大的帮助。 这是一项后天的技能。 因此,让我们继续。
在PDF文件中搜索===使我进入规范的第56页: 11.9.4。 Strict Equals运算符(===) ,在仔细研究了规范性语言后,我发现:
11.9.6严格相等比较算法
比较x === y(其中x和y是值)产生true或false 。 这样的比较执行如下:
1.如果Type(x)与Type(y)不同,则返回false 。
2.如果Type(x)为Undefined,则返回true 。
3.如果Type(x)为Null,则返回true 。
4.如果Type(x)不是Number,请转到步骤11。
5.如果x为NaN ,则返回false 。
6.如果y为NaN ,则返回false 。
7.如果x与y相同,则返回true 。
8.如果x为+0且y为−0,则返回true 。
9.如果x为−0且y为+0,则返回true 。
10.返回false 。
11.如果Type(x)为String,则如果x和y是完全相同的字符序列(相同的长度和相同位置的相同字符),则返回true;否则,返回true 。 否则,返回false 。
12.如果Type(x)为布尔值,则如果x和y均为true或均为false ,则返回true ; 否则,返回false 。
13.如果x和y指的是同一个对象,或者它们指的是彼此连接的对象,则返回true (请参见13.1.2)。 否则,返回false 。
有趣的是步骤11。是的,字符串被视为值类型。 但这并不能解释为什么new String(“ a”)!==“ a” 。 我们是否有不符合ECMA-262的浏览器?
没那么快!
让我们检查操作数的类型。 通过将它们包装在typeof()中 ,自己尝试一下。 我发现new String(“ a”)是一个对象,并使用了步骤1:如果类型不同,则返回false 。
如果您想知道为什么new String(“ a”)不返回字符串,那么阅读规范的一些练习呢? 玩得开心!
Aidiakapi在下面的评论中写道:
从规格
11.2.2新的运营商 :
如果Type(constructor)不是Object,则抛出TypeError异常。
换句话说,如果String不属于Object类型,则不能与new运算符一起使用。
即使对于String构造函数, new也会始终返回Object。 a! 字符串的值语义(请参见步骤11)丢失。
这最终意味着: new String(“ a”)!==“ a” 。
#5楼
上面提到的前两个答案==表示平等,===表示身份。 不幸的是,这个说法是不正确的。
如果==的两个操作数都是对象,则将它们进行比较以查看它们是否是同一对象。 如果两个操作数都指向同一个对象,则equal操作符将返回true。 否则,两者不相等。
var a = [1, 2, 3];
var b = [1, 2, 3];
console.log(a == b) // false
console.log(a === b) // false
在上面的代码中,==和===都为假,因为a和b不是同一对象。
这就是说:如果==的两个操作数都是对象,则==的行为与===相同,这也意味着标识。 这两个运算符的本质区别在于类型转换。 ==在检查相等性之前已经进行了转换,但是===没有。
#6楼
平等比较:
运算子==
当两个操作数相等时,返回true。 在比较之前,将操作数转换为相同类型。
>>> 1 == 1
true
>>> 1 == 2
false
>>> 1 == '1'
true
相等和类型比较:
运算子===
如果两个操作数相等且类型相同,则返回true。 如果以这种方式进行比较,通常会更好,更安全,因为没有幕后类型转换。
>>> 1 === '1'
false
>>> 1 === 1
true
#7楼
* 运算子=== vs == *
1 == true => true
true == true => true
1 === true => false
true === true => true
#8楼
这是一个方便的比较表,其中显示了发生的转换以及==
和===
之间的差异。
结论表明:
“除非您完全了解两个相等的转换,否则请使用三个相等。”
http://dorey.github.io/JavaScript-Equality-Table/
#9楼
==
和===
之间的相等比较的有趣的图形表示。
资料来源: http : //dorey.github.io/JavaScript-Equality-Table/
var1 === var2
当使用
===
进行JavaScript相等性测试时,一切保持原样。 在评估之前,没有任何转换。
var1 == var2
当使用
==
进行JavaScript相等性测试时,会发生一些时髦的转换。
这个故事所讲的道德:
除非您完全了解
==
的转换,否则请使用===
。
#10楼
是! 这非常重要。
javascript中的===
运算符会检查值以及类型 ,其中==
运算符只检查值(如果需要,则进行类型转换) 。
您可以轻松地对其进行测试。 将以下代码粘贴到HTML文件中,然后在浏览器中将其打开
<script>
function onPageLoad()
{
var x = "5";
var y = 5;
alert(x === 5);
};
</script>
</head>
<body onload='onPageLoad();'>
您将在警报中得到“ 假 ”。 现在将onPageLoad()
方法修改为alert(x == 5);
你会得到正确的 。
#11楼
它检查相同边的类型和值是否相等。
例:
'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
#12楼
在JavaScript中,它表示相同的值和类型。
例如,
4 == "4" // will return true
但
4 === "4" // will return false
#13楼
在PHP和JavaScript中,它是严格的相等运算符。 这意味着它将比较类型和值。
#14楼
这意味着没有类型强制的相等性类型强制意味着JavaScript不会自动将任何其他数据类型转换为字符串数据类型
0==false // true,although they are different types
0===false // false,as they are different types
2=='2' //true,different types,one is string and another is integer but
javaScript convert 2 to string by using == operator
2==='2' //false because by using === operator ,javaScript do not convert
integer to string
2===2 //true because both have same value and same types
#15楼
===
如果操作数严格相等(请参见上文)且没有类型转换,则返回true
。
#16楼
===
运算符检查变量的值和类型是否相等。
==
运算符只是检查变量的值是否相等。
#17楼
这是严格的检查测试。
这是一件好事,尤其是如果您要检查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
#18楼
只是
==
表示具有 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
#19楼
一个简单的例子是
2 == '2' -> true, values are SAME because of type conversion.
2 === '2' -> false, values are NOT SAME because of no type conversion.
#20楼
严格相等的Javascript执行流程图/比较'==='
非严格相等/比较'=='的JavaScript执行流程图
#21楼
身份( ===
)运算符的行为与相等( ==
)运算符相同,只是不进行类型转换,并且类型必须相同才能被视为相等。
==
运算符将在进行任何必要的类型转换后比较是否相等。 ===
运算符将不进行转换,因此,如果两个值不同,则类型===
只会返回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关于引用类型的 答案中提出了一个很好的观点。 对于引用类型, ==
和===
一致(除非在特殊情况下)。
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
特殊情况是将文字与对象结果相同的文字进行比较,这是由于其toString
或valueOf
方法。 例如,考虑将字符串文字与由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
#22楼
使用==
操作符( 平等 )
true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2; //true, because "2" is converted to 2 and then compared
使用===
运算符( Identity )
true === 1; //false
"2" === 2; //false
这是因为等于运算符==
确实键入了coercion ,这意味着解释器在比较之前隐式尝试转换值。
另一方面, 身份运算符===
不会强制类型化 ,因此在比较时不会转换值,因此跳过一个步骤会更快(根据This JS基准测试)。
#23楼
您的用法中的两个操作之间不可能有任何性能差异。 由于两个参数已经是相同的类型,因此无需进行类型转换。 这两个操作都将进行类型比较,然后进行值比较。
#24楼
===运算符称为严格比较运算符,它确实与==运算符不同。
让我们2瓦尔a和b。
为了使“ a == b”评估为真,a和b必须为相同的值 。
在“ a === b”的情况下,a和b必须具有相同的值和相同的类型 ,才能将其评估为true。
请看下面的例子
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%的使用情况下,使用哪一个无关紧要,但是,有一天在您遇到某些意外行为时,很容易知道它们之间的区别。
#25楼
在典型的脚本中,不会有性能差异。 可能更重要的事实是千个“ ===”比1个“ ==”重1KB。JavaScript分析器可以告诉您您的情况是否存在性能差异。
但是我个人会按照JSLint的建议去做。 出现此建议并不是因为性能问题,而是因为类型强制表示('\\t\\r\\n' == 0)
为true。
#26楼
为什么==
如此不可预测?
比较空字符串""
和数字零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**
这只是您使用基元所获得的疯狂东西。
当对对象使用==
时,这是一个全新的疯狂级别。
在这一点上,您可能想知道...
为什么会这样?
这是因为与“三重等于”( ===
)不同,它仅检查两个值是否相同。
==
还有很多其他的东西 。
您可以对函数进行特殊处理,对null,undefined,字符串进行特殊处理。
很古怪。
实际上,如果您试图编写一个执行==
功能的函数,它将看起来像这样:
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();
}
那么这是什么意思?
这意味着==
很复杂。
因为它很复杂,所以很难知道使用它时会发生什么。
这意味着您可能会遇到bug。
所以这个故事的寓意是...
让您的生活不再那么复杂。
使用===
代替==
。
结束。
#27楼
我使用以下代码在Firefox中使用Firebug测试了此代码:
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中一样安全),代码质量也是如此。
#28楼
问题是您可能很容易遇到麻烦,因为JavaScript具有很多隐式转换,这意味着...
var x = 0;
var isTrue = x == null;
var isFalse = x === null;
哪一个很快成为问题。 隐式转换为什么是“邪恶的”的最佳示例可以从MFC / C ++中的此代码中获取,该代码实际上将由于从CString到HANDLE的隐式转换而编译,HANDLE是指针typedef类型。
CString x;
delete x;
这显然在运行时会执行非常不确定的事情...
Google在C ++和STL中进行隐式转换,以获取一些反对它的论点...
#29楼
相等的比较运算符==令人困惑,应避免使用。
如果你必须忍受它,那么请记住以下三两件事:
- 它不是传递的: (a == b)和(b == c)不会导致(a == c)
- 它与否定是互斥的: (a == b)和(a!= b)始终持有相反的布尔值,并且所有a和b。
- 如有疑问,请认真学习以下真值表:
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.
#30楼
在这里的答案中,我什么都没有读到什么相等的意思。 有人会说===
表示equal且具有相同的类型 ,但这并不是真的。 实际上, 这意味着两个操作数都引用相同的对象 ,或者在值类型的情况下,它们具有相同的value 。
因此,让我们采用以下代码:
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
具有相同的值并且属于相同的类型,则a === b
返回true
对于参考类型:
如果a
和b
引用完全相同的对象,则a === b
返回true
对于字符串:
如果a
和b
都是字符串并且包含完全相同的字符,则a === b
返回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
类型的Object
,该Object
大多数情况下都表现为字符串。