我正在使用JSLint来浏览 JavaScript,并且在执行诸如比较语句内部之类的操作时,它会返回许多建议以将==
(两个等号)替换为(三个等号)。===
idSele_UNVEHtype.value.length == 0
if
==
替换为 有性能优势===
吗?
由于存在许多比较运算符,因此欢迎任何性能改进。
如果不进行类型转换,是否会提高性能==
?
我正在使用JSLint来浏览 JavaScript,并且在执行诸如比较语句内部之类的操作时,它会返回许多建议以将==
(两个等号)替换为(三个等号)。===
idSele_UNVEHtype.value.length == 0
if
==
替换为 有性能优势===
吗?
由于存在许多比较运算符,因此欢迎任何性能改进。
如果不进行类型转换,是否会提高性能==
?
严格相等运算符 ( ===
) 的行为与抽象相等运算符 ( ==
) 相同,只是不进行类型转换,并且类型必须相同才能被视为相等。
运算符将在进行任何必要的类型转换后==
比较是否相等。运算符不会进行转换,因此如果两个值的类型不同,将简单地返回。两者都同样快。===
===
false
引用 Douglas Crockford 的优秀JavaScript: The Good Parts 的话,
JavaScript 有两组相等运算符:
===
and!==
,以及它们的邪恶双胞胎==
and!=
。好的工作按您期望的方式工作。如果两个操作数类型相同且值相同,则===
产生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
缺乏传递性令人担忧。我的建议是永远不要使用邪恶的双胞胎。相反,请始终使用
===
and!==
。刚才显示的所有比较都是由操作员产生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
orvalueOf
方法,该对象的计算结果为相同的原语。例如,考虑将字符串原语与使用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
使用==
运算符(平等)
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 benchmark test)。
在这里的答案中,我没有读到任何关于平等的意思。有人会说这===
意味着相等且属于同一类型,但事实并非如此。这实际上意味着两个操作数都引用同一个对象,或者在值类型的情况下,具有相同的值。
因此,让我们采用以下代码:
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
返回 truea
b
对于引用类型:如果和引用完全相同的对象
a === b
则返回 truea
b
对于字符串:如果和都是字符串并且包含完全相同的字符
a === b
返回 truea
b
字符串不是值类型,但在 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
表现为字符串的类型。
让我补充一下这个忠告:
如有疑问,请阅读规范!
ECMA-262 是一种脚本语言规范,JavaScript 是其方言。当然,在实践中,最重要的浏览器的行为方式比对应该如何处理某事的深奥定义更重要。但是理解为什么new String("a") !== "a"会很有帮助。
请让我解释如何阅读规范以澄清这个问题。我看到在这个非常古老的话题中,没有人对非常奇怪的效果有答案。因此,如果您能阅读规范,这将对您的职业有极大的帮助。这是一种后天习得的技能。所以,让我们继续。
在 PDF 文件中搜索 === 会将我带到规范的第 56 页:11.9.4。Strict Equals Operator ( === ),经过规范后,我发现:
11.9.6 严格等式比较算法
比较 x === y,其中 x 和 y 是值,产生true或false。这样的比较执行如下:
1. 如果 Type(x) 与 Type(y) 不同,则返回false。
2. 如果 Type(x) 未定义,则返回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.返回假。
11.如果Type(x)是String,那么如果x和y是完全相同的字符序列(长度相同,对应位置的字符相同),则返回true ;否则,返回false。
12. 如果 Type(x) 是 Boolean,如果 x 和 y 都为真或都为假,则返回真;否则,返回false。 13. 返回真
如果 x 和 y 指的是同一个对象,或者如果它们指的是相互连接的对象(见 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 运算符一起使用。
new总是返回一个 Object,即使对于String构造函数也是如此。唉!字符串的值语义(参见步骤 11)丢失。
这最终意味着:new String("a") !== "a"。
我使用这样的代码在 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 中获得的一样安全),代码质量也是如此。
在 PHP 和 JavaScript 中,它是一个严格的相等运算符。这意味着,它将比较类型和值。
在 JavaScript 中,它意味着相同的值和类型。
例如,
4 == "4" // will return true
但
4 === "4" // will return false
为什么==
如此不可预测?
当您将空字符串""
与数字零进行比较时,您会得到什么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();
}
那么这是什么意思?
意思==
是复杂。
因为它很复杂,所以很难知道使用它时会发生什么。
这意味着您最终可能会遇到错误。
所以这个故事的寓意是……
让你的生活不那么复杂。
使用===
而不是==
.
结束。
===运算符称为严格比较运算符,它确实不同于==运算符。
让我们取 2 个变量 a 和 b。
对于"a == b"评估为真 a 和 b 需要是相同的 value。
在“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% 的使用场景中,你使用哪一个并不重要,但是当你有一天遇到一些意想不到的行为时,很容易知道其中的区别。
===
检查相同边的类型和值是否相等。'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
很多时候,无类型检查会很方便 ,因为您不在乎值是undefined
,null
还是0
""
JavaScript===
与 ==
.
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
这意味着没有类型强制的相等 类型强制意味着 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
在典型的脚本中不会有性能差异。更重要的可能是千个“===”比千个“==”重 1 KB :) JavaScript 分析器可以告诉您在您的情况下是否存在性能差异。
但就我个人而言,我会按照 JSLint 的建议去做。这个建议不是因为性能问题,而是因为类型强制意味着('\t\r\n' == 0)
是真的。
相等比较运算符 == 令人困惑,应避免使用。
如果您必须忍受它,请记住以下三件事:
JAVASCRIPT 中的相等运算符真值表
**奇怪:请注意,第一列上的任何两个值在这个意义上都不相等。**
'' == 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 中的运算符检查值和类型,其中==
运算符只检查值(如果需要,进行类型转换)。
您可以轻松地对其进行测试。将以下代码粘贴到 HTML 文件中并在浏览器中打开
<script>
function onPageLoad()
{
var x = "5";
var y = 5;
alert(x === 5);
};
</script>
</head>
<body onload='onPageLoad();'>
您将在警报中收到“错误”。现在修改onPageLoad()
方法,alert(x == 5);
你会得到true。
简单地
==
表示操作数之间的类型强制比较
和
===
表示没有类型强制的操作数之间的比较。
JavaScript 中的类型强制意味着自动将数据类型转换为其他数据类型。
例如:
123 == "123" // Returns true, because JS coerces string "123" to number 123
// and then goes on to compare `123 == 123`.
123 === "123" // Returns false, because JS does not coerce values of different types here.
===
运算符检查值以及变量的类型是否相等。
==
运算符只检查变量的值是否相等。
这是一个严格的检查测试。
这是一件好事,尤其是当您在 0 和 false 和 null 之间进行检查时。
例如,如果您有:
$a = 0;
然后:
$a==0;
$a==NULL;
$a==false;
全部返回 true,您可能不希望这样。假设您有一个函数可以返回数组的第 0 个索引或在失败时返回 false。如果你用“==”检查,你会得到一个令人困惑的结果。
所以和上面一样,但是经过严格的测试:
$a = 0;
$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false
JSLint 有时会给你不切实际的理由来修改东西。具有与类型已经相同的===
完全相同的性能。==
只有当类型不同时它才会更快,在这种情况下它不会尝试转换类型而是直接返回false。
因此,恕我直言, JSLint 可能用于编写新代码,但应不惜一切代价避免无用的过度优化。
这意味着,当您知道 a 只能是字符串这一事实时,没有理由更改==
为===
检查。if (a == 'test')
以这种方式修改大量代码会浪费开发人员和审阅者的时间,而且一无所获。
根据经验,我通常会使用===
代替==
(和!==
代替!=
)。
原因在上面的答案中进行了解释,Douglas Crockford 也很清楚(JavaScript:The Good Parts)。
但是有一个例外:
== null
是一种检查“为空或未定义”的有效方法:
if( value == null ){
// value is either null or undefined
}
例如 jQuery 1.9.1 使用这种模式 43 次,JSHint 语法检查器甚至eqnull
为此提供了放松选项。
来自jQuery 风格指南:
应该使用严格的相等检查 (===) 来支持 ==。唯一的例外是在通过 null 检查未定义和 null 时。
// Check for both undefined and null values, for some important reason.
undefOrNull == null;
编辑 2021-03:
现在大多数浏览器都
支持Nullish 合并运算符 ( ??
)
和Logical nullish assignment(??=)
,如果变量为 null 或未定义,则可以更简洁地分配默认值,例如:
if (a.speed == null) {
// Set default if null or undefined
a.speed = 42;
}
可以写成这些形式中的任何一种
a.speed ??= 42;
a.speed ?? a.speed = 42;
a.speed = a.speed ?? 42;
一个简单的例子是
2 == '2' -> true, values are SAME because of type conversion.
2 === '2' -> false, values are NOT SAME because of no type conversion.
前 2 个答案都提到 == 表示平等, === 表示身份。不幸的是,这种说法是不正确的。
如果 == 的两个操作数都是对象,则比较它们是否是同一个对象。如果两个操作数都指向同一个对象,则等号运算符返回 true。否则,两者不相等。
var a = [1, 2, 3];
var b = [1, 2, 3];
console.log(a == b) // false
console.log(a === b) // false
在上面的代码中,== 和 === 都为 false,因为 a 和 b 不是同一个对象。
也就是说:如果 == 的两个操作数都是对象,那么 == 的行为与 === 相同,这也意味着身份。这两个运算符的本质区别在于类型转换。== 在检查相等性之前进行了转换,但 === 没有。
问题是你可能很容易遇到麻烦,因为 JavaScript 有很多隐式转换意味着......
var x = 0;
var isTrue = x == null;
var isFalse = x === null;
这很快就会成为一个问题。可以从MFC / C++ 中的这段代码中获取为什么隐式转换是“邪恶”的最佳示例,由于从 CString 到 HANDLE 的隐式转换,它实际上将编译,这是一个指针 typedef 类型......
CString x;
delete x;
这显然在运行时做了非常未定义的事情......
谷歌在 C++ 和STL中进行隐式转换以获得一些反对它的论点......
===
true
如果操作数严格相等(见上文)且没有类型转换,则返回。
平等比较:
操作员==
当两个操作数相等时返回真。在比较之前,操作数被转换为相同的类型。
>>> 1 == 1
true
>>> 1 == 2
false
>>> 1 == '1'
true
相等和类型比较:
操作员===
如果两个操作数相等且类型相同,则返回 true。如果以这种方式进行比较,通常会更好、更安全,因为没有幕后的类型转换。
>>> 1 === '1'
false
>>> 1 === 1
true
==
这是一个方便的比较表,显示了发生的转换以及和之间的差异===
。
正如结论所说:
“除非您完全理解二等式的转换,否则请使用三等式。”
null 和 undefined 是虚无,也就是说,
var a;
var b = null;
这里a
并b
没有值。而 0、false 和 '' 都是值。所有这些之间的共同点是它们都是虚假值,这意味着它们都满足虚假条件。
所以,0、false 和 '' 一起构成了一个子组。另一方面, null & undefined 形成第二个子组。检查下图中的比较。null 和 undefined 将相等。其他三个将彼此相等。但是,它们在 JavaScript 中都被视为虚假条件。
这与任何对象(如 {}、数组等)相同,非空字符串和布尔值 true 都是真值条件。但是,它们都不是平等的。
*运算符 === 与 == *
1 == true => true
true == true => true
1 === true => false
true === true => true
JavaScript 既有严格的比较,也有类型转换的比较。严格比较(例如===
)仅在操作数属于同一类型时才成立。更常用的抽象比较(例如==
)在进行比较之前将操作数转换为相同的类型。
==
如果操作数不是同一类型,则相等 ( ) 运算符转换操作数,然后应用严格比较。如果任一操作数是数字或布尔值,则尽可能将操作数转换为数字;否则,如果任一操作数是字符串,则尽可能将字符串操作数转换为数字。如果两个操作数都是对象,那么当操作数引用内存中的同一个对象时,JavaScript 会比较相等的内部引用。
句法:
x == y
例子:
3 == 3 // true
"3" == 3 // true
3 == '3' // true
===
如果操作数严格相等(见上文)且没有类型转换,则标识/严格相等( )运算符返回 true。
句法:
x === y
例子:
3 === 3 // true
供参考:比较运算符(Mozilla 开发者网络)
如果您正在制作 Web 应用程序或安全页面,则应始终使用(仅在可能的情况下)
===
因为它会检查它是否是相同的内容以及它是否是相同的类型!
所以当有人进入时:
var check = 1;
if(check == '1') {
//someone continued with a string instead of number, most of the time useless for your webapp, most of the time entered by a user who does not now what he is doing (this will sometimes let your app crash), or even worse it is a hacker searching for weaknesses in your webapp!
}
但与
var check = 1;
if(check === 1) {
//some continued with a number (no string) for your script
} else {
alert('please enter a real number');
}
黑客永远不会深入系统来发现错误并破解您的应用程序或用户
我的观点是
===
将为您的脚本增加更多安全性
当然,您也可以检查输入的数字是否有效,是否为字符串等。在第一个示例中使用其他 if 语句,但这至少对我来说更容易理解和使用
我发布此内容的原因是,在此对话中从未提及“更安全”或“安全”一词(如果您查看 iCloud.com,它使用 2019 次 === 和 1308 次 ==,这也意味着您有时使用 == 而不是 === 因为它会阻塞你的功能,但正如开头所说,你应该尽可能使用 ===)
我的推理过程使用 emacs org-mode 和 node.js 运行测试。
| use == | '' | '0' | false | 'false' | undefined | null | ' \t\r\n ' |
| '' | x | f | t | f | f | f | f |
| '0' | | x | t | f | f | f | f |
| false | | | x | f | f | f | t |
| 'false' | | | | x | f | f | f |
| undefined | | | | | x | t | f |
| null | | | | | | x | f |
| ' \t\r\n ' | | | | | | | x |
| use === | '' | '0' | false | 'false' | undefined | null | ' \t\r\n ' |
| '' | x | f | f | f | f | f | f |
| '0' | | x | f | f | f | f | f |
| false | | | x | f | f | f | f |
| 'false' | | | | x | f | f | f |
| undefined | | | | | x | f | f |
| null | | | | | | x | f |
| ' \t\r\n ' | | | | | | | x |
我的测试脚本如下: run > node xxx.js
var rowItems = ['', '0', false, 'false', undefined, null, ' \t\r\n ']
var colItems = rowItems
for(var i = 0; i < rowItems.length; i++) {
for (var j = 0; j < colItems.length; j++) {
var r = (rowItems[i] === colItems[j]) ? true : false;
console.log(rowItems[i] + " = " + colItems[j] + " " + r + " [" + i + "] ==> [" + j + "]")
};
}
===
关心对象是否相同。因此,new String("Hello world") === "Hello world"
返回 false。但是,==
不关心对象是否相同;它只是简单地将一个参数转换为另一个参数的类型:如果无法转换,则返回 false。然后new String("Hello world") == "Hello world"
返回 true 而不是 false。
javascript 是一种弱类型语言,即没有任何数据类型,例如 C、c++。int、boolean、float 等,因此变量可以保存任何类型的值,这就是为什么这些特殊的比较运算符存在的原因
例如
var i = 20;var j = "20";
如果我们应用比较运算符,这些变量的结果将是
i==j //result is true
或者
j != i//result is false
为此,我们需要一个特殊的比较运算符来检查变量的值和数据类型
如果我们这样做
i===j //result is false
==
运算符只比较值而不是数据类型。
===
运算符将值与其数据类型的比较进行比较。
例如:
1 == "1" //true
1 === "1" //false
此运算符 ( "==="
) 用于执行自动类型转换的语言,例如。PHP, Javascript。"==="
运算符有助于防止由自动类型转换引起的意外比较。
不同的介于
=
,= =
,= = =
=
运算符用于仅分配value
.= =
运算符用于仅比较values
非datatype
= = =
运算符用于比较values
以及datatype
。总是使用' === ',你会避免成千上万的错误。如今,不同的风格指南更倾向于使用三等式,因为它比较考虑了操作数的类型。
==
是的,相等和身份运算符之间存在很大差异===
。
通常身份运算符执行得更快,因为没有进行类型转换。但是,如果这些值属于同一类型,您将看不到任何区别。
查看我的帖子The legend of JavaScript equal operator,其中解释了细节,包括类型转换和比较算法,并附有大量示例。
一个未提及的使用原因===
- 是在您与 / 交叉编译 to/from 共存的情况下coffee-script
。从CoffeeScript 小书...
JavaScript 中的弱相等比较有一些令人困惑的行为,并且通常是令人困惑的错误的根源。
解决方案是改用严格相等运算符,它由三个等号组成:===。它的工作方式与普通的相等运算符完全相同,但没有任何类型强制。建议始终使用严格相等运算符,并在需要时显式转换类型。
如果您经常来回转换coffee-script
,您应该只使用===
. 事实上,coffee-script
编译器会强迫你...
CoffeeScript 通过简单地将所有弱比较替换为严格比较来解决这个问题,换句话说,将所有 == 比较器转换为 ===。您不能在 CoffeeScript 中进行弱相等比较,如果需要,您应该在比较它们之前显式转换类型。
Javascript 是一种松散类型的语言这一事实需要在您使用它时不断出现在您的脑海中。只要数据结构相同,就没有理由不使用严格相等,通过常规相等,您通常会自动进行值的隐式转换,这会对您的代码产生深远的影响。这种转换很容易出现问题,因为它们是自动发生的。
在严格相等的情况下,没有自动隐式转换,因为值必须已经是正确的数据结构。
Javascript 的类型很松散,就像 php 一样,
var x = "20";
var y =20;
if (x===y) // false
这总是会给你一个错误,因为即使变量的值相同,数据类型也不同
一个是字符串,另一个是整数
If(x==y)//true
然而,这只是检查内容是否相同,无论数据类型如何......
我不想说值相等,因为字符串值在逻辑上不能等于 int 值
首先,关于 Javascript 字符串等号的一些术语:双等号正式称为抽象相等比较运算符,而三等号称为严格相等比较运算符。它们之间的区别可以总结如下:抽象相等会在进行比较之前尝试通过类型强制来解析数据类型。如果类型不同,严格相等将返回 false。考虑以下示例:
console.log(3 == "3"); // true
console.log(3 === "3"); // false.
console.log(3 == "3"); // true
console.log(3 === "3"); // false.
使用两个等号返回 true,因为字符串“3”在进行比较之前被转换为数字 3。三个等号看出类型不同,返回false。这是另一个:
console.log(true == '1'); // true
console.log(true === '1'); // false
console.log(true == '1'); // true
console.log(true === '1'); // false
同样,抽象相等比较执行类型转换。在这种情况下,布尔值 true 和字符串 '1' 都被转换为数字 1,结果为 true。严格相等返回 false。
如果您了解您在区分 == 和 === 方面做得很好。但是,在某些情况下,这些运算符的行为是不直观的。让我们再看一些例子:
console.log(undefined == null); // true
console.log(undefined === null); // false. Undefined and null are distinct types and are not interchangeable.
console.log(undefined == null); // true
console.log(undefined === null); // false. Undefined and null are distinct types and are not interchangeable.
console.log(true == 'true'); // false. A string will not be converted to a boolean and vice versa.
console.log(true === 'true'); // false
console.log(true == 'true'); // false. A string will not be converted to a boolean and vice versa.
console.log(true === 'true'); // false
下面的示例很有趣,因为它说明了字符串文字与字符串对象不同。
console.log("This is a string." == new String("This is a string.")); // true
console.log("This is a string." === new String("This is a string.")); // false
console.log("This is a string." == new String("This is a string.")); // true
console.log("This is a string." === new String("This is a string.")); // false
如果===
你想在 JavaScript 中比较一些东西,那就使用它,它被称为严格相等,这意味着如果只有类型和值都相同,这将返回 true ,所以如果你使用,就不会有任何不需要的类型更正==
,您基本上不关心类型,并且在许多情况下您可能会面临松散相等比较的问题。
使用 === 严格相等
严格相等比较两个值是否相等。在比较之前,这两个值都不会隐式转换为其他值。如果值具有不同的类型,则认为这些值不相等。否则,如果值具有相同的类型并且不是数字,则如果它们具有相同的值,则它们被认为是相等的。最后,如果两个值都是数字,如果它们都不是 NaN 并且是相同的值,或者如果一个是 +0 而一个是 -0,则它们被认为是相等的。
var num = 0;
var obj = new String('0');
var str = '0';
console.log(num === num); // true
console.log(obj === obj); // true
console.log(str === str); // true
console.log(num === obj); // false
console.log(num === str); // false
console.log(obj === str); // false
console.log(null === undefined); // false
console.log(obj === null); // false
console.log(obj === undefined); // false
使用 == 的松散相等
在将两个值转换为通用类型之后,松散相等比较两个值是否相等。转换后(一方或双方可能进行转换),最终的相等比较完全按照 === 执行。松散相等是对称的:对于 A 和 B 的任何值,A == B 始终具有与 B == A 相同的语义(应用转换的顺序除外)。
var num = 0;
var obj = new String('0');
var str = '0';
console.log(num == num); // true
console.log(obj == obj); // true
console.log(str == str); // true
console.log(num == obj); // true
console.log(num == str); // true
console.log(obj == str); // true
console.log(null == undefined); // true
// both false, except in rare cases
console.log(obj == null);
console.log(obj == undefined);
它建议替换为的原因==
是===
操作===
符比==
. 在我们的上下文中,可靠的方法===
也适用于类型检查。考虑到最佳编程实践,我们应该始终选择更可靠的功能而不是不太可靠的功能。同样,每当我们在大多数情况下考虑完全等于运算符时,我们默认认为类型应该是相同的。正如===
规定一样,我们应该去争取它。
==
“我应该使用还是在 JavaScript 中比较”的困境===
等于或类似于以下问题:“我应该使用'勺子'还是'叉子'来吃饭?
这个问题唯一合理的答案是
==
用于松散类型比较。===
用于强类型比较。那是因为它们不一样。它们没有相同的目的,也不打算用于相同的目的。
当然,“叉子”和“勺子”都是用来“吃”的,但你会根据你吃的东西来选择使用它们。
含义:您将决定使用“勺子”,即:==
用于喝“汤”,和/或“叉子”,即:===
用于采摘。
询问是否更好地使用“叉子”或“勺子”来“吃” - 等于询问使用静态 [===] 与动态 [==] 等式是否更好,同上。在 JS 中。这两个问题同样是错误的,反映了对所讨论主题的非常狭隘或肤浅的理解。
var a = new String("123");
var b = "123";
alert(a === b); // returns false !! (but they are equal and of the same type)
在其中一个答案中看到了这一点。
a
并且b
在这种情况下并不是真正的同一类型,如果你检查typeof(a)
你会得到'object'和typeof(b)
is 'string'。