Javascript 中 == 和 === 区别是什么?

首页 发现 话题
登录加入知乎
前端开发
JavaScript
前端工程师
原生 JavaScript

Javascript 中 == 和 === 区别是什么?

这个问题的答案网上随处可见,总结下答案无外乎就是:
双等号会造成类型转换,推荐一律使用三等号
寻寻觅觅一直没有遇到能说服我放弃双等号的答案,还请大家赐教

我的理解:在变量赋值时内存会存储值的类型;做双等号比较操作时,会先做 临时类型转换再做比较,内存中存储的值还是原来的不会改变: Javascript 中 == 和 === 区别是什么?_第1张图片
不知道我理解是否有误,请赐教

-----------------------------------------------------------------------
感谢回答,我问题没描述清楚,特修改了一下问题
js中使用==会造成类型转换,对后续代码会不会造成意外的影响?
关注者
432
被浏览
69,501

28 个回答

默认排序
55 人赞同了该回答

JavaScript 中应该用 "==" 还是 "==="? - 贺师俊的回答

对后续代码会不会造成意外的影响”?答案是:会。

意外的影响不是指程序执行上的“副作用”,而是指代码意图的实现。


@邹润阳
提到的 You don't know JS 是本好书,但是不代表作者的所有观点都是对的。

如果对你来说编程是一项工作,而不仅仅是兴趣爱好,就需要用工程标准进行衡量。而以工程标准衡量,“==”带来的便利性抵不上其带来的成本。

举个简单的例子,团队协作中你肯定需要读别人的代码。而当你看到“==”时,要判断清楚作者的代码意图是确实需要转型,还是无所谓要不要转型只是随手写了,还是不应该转型但是写错了……所花费的脑力和时间比明确的“===”(加上可能需要的明确转型)要多得多。要记得团队中的每个人(包括原作者自己)都需要付出这理解和维护成本。
编辑于 2015-12-22
55 4 条评论
分享
收藏 感谢
577 人赞同了该回答
谁告诉你 == 不会有副作用的
var x = 1;
var obj = {valueOf: function(){ x = 2; return 0 }}
console.log(obj == 0, x) // true, 2
甚至还会产生异常呢
var x = 1;
var obj = {valueOf: function(){ return {} }, toString: function(){ return {}}}
console.log(obj == 0) // Error: Cannot convert object to primitive value

————————————————————————————————————————————
这是 == Javascript 中 == 和 === 区别是什么?_第2张图片这是 === Javascript 中 == 和 === 区别是什么?_第3张图片完整比较图:
  • 红色:===
  • 橙色:==
  • 黄色:<= 和 >= 同时成立,== 不成立
  • 蓝色:只有 >=
  • 绿色:只有 <=

Javascript 中 == 和 === 区别是什么?_第4张图片(参: JS Comparison Table, Edit fiddle - JSFiddle)

顺便,有人说这图像现代艺术,感觉旋转完更像,删减重排换成 S1 配色之后做成头像了。
不免费帮人做头像(也就是换个顺序的事情)
Javascript 中 == 和 === 区别是什么?_第5张图片
编辑于 2015-12-23
577 33 条评论
分享
收藏 感谢 收起
59 人赞同了该回答
"==="叫做严格运算符,"=="叫做相等运算符。

严格运算符的运算规则如下,
(1)不同类型值
如果两个值的类型不同,直接返回false。
(2)同一类的原始类型值

同一类型的原始类型的值(数值、字符串、布尔值)比较时,值相同就返回true,值不同就返回false。

(3)同一类的复合类型值

两个复合类型(对象、数组、函数)的数据比较时,不是比较它们的值是否相等,而是比较它们是否指向同一个对象。

(4)undefined和null

undefined 和 null 与自身严格相等。

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

相等运算符在比较相同类型的数据时,与严格相等运算符完全一样。

在比较不同类型的数据时,相等运算符会先将数据进行类型转换,然后再用严格相等运算符比较。类型转换规则如下:

(1)原始类型的值

原始类型的数据会转换成数值类型再进行比较。字符串和布尔值都会转换成数值,所以题主的问题中会有第二个string输出。

(2)对象与原始类型值比较

对象(这里指广义的对象,包括数值和函数)与原始类型的值比较时,对象转化成原始类型的值,再进行比较。

(3)undefined和null

undefined和null与其他类型的值比较时,结果都为false,它们互相比较时结果为true。

(4)相等运算符的缺点

相等运算符隐藏的类型转换,会带来一些违反直觉的结果。

'' == '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
这就是为什么 建议尽量不要使用相等运算符

至于使用相等运算符会不会对后续代码造成意外影响,答案是有可能会。
var a = undefined;
if(!a){
    console.log("1"); //1
}
var a = undefined;
if(a == null){
    console.log("1"); //1
}
var a = undefined;
if(a === null){
    console.log("1"); //无输出
}
也就是说当a为undefined时,输出的值会有变化,而在编程中对象变成undefined实在是太常见了。

推荐一篇文章 运算符 -- JavaScript 标准参考教程(alpha)
编辑于 2017-09-08
59 5 条评论
分享
收藏 感谢 收起
33 人赞同了该回答
场景一:你向女神表白,女神说:0点见;
场景二:你向女神表白,女神说不,转身离开了。
使用 == 的时候,JS 告诉你这两个场景结果是一样的。
这不是坑爹吗?
发布于 2015-12-22
33 收起评论
分享
收藏 感谢

1 条评论

切换为时间排序
啪啪啪小生手
啪啪啪小生手 16 天前

很好啊!0点见不是就想耍小白嘛!多亏==

33 人赞同了该回答

题主,我非常推荐你看看这个系列: You Don't Know JS

关于"=="和"===",作者在第一本书的第二章是这样说的:YDKJS | Equality

截取一小段:
Many developers feel that === is more predictable, so they advocate always using that form and staying away from ==. I think this view is very shortsighted. I believe == is a powerful tool that helps your program, if you take the time to learn how it works.
简单翻译一下:
许多开发者认为 === 的行为更加容易预测,所以他们总是主张使用 === 而劝人们远离 ==,我认为这种看法是非常短视的。 如果你花点时间来搞清楚它是如何工作的话,== 绝对是一个能够帮助你程序的强大工具。

关于 == 是如何工作的,可以看看链接中的文章,或者直接去看 == 的 ECMAScript Language Specification 的 11.9.3

因为你是一个有质疑精神的人,在JS领域有很多所谓 The Good Part 的部分;大家都推荐你使用JS的这个子集,抛弃一些“奇怪”的特性。在YDKJS这个系列的文章中,作者认为 The Good Part 往往是 The Safe Part;但事实上JS的另一部分同样有趣而值得研究,这个系列就致力于为你展示另一个视角。

我觉得你应该看看。

-------------------------
UPDATE (2015-7-1):

关于你的问题:“js中使用==会造成类型转换,对后续代码会不会造成意外的影响?”

我的答案是不会。
==, >, <, +, -, ...
这些操作符所造成的隐式类型转换都是无副作用的,它不会改变变量本身保存的值。

而递增操作符、递减操作符:
a++ / a--
会有副作用,即表达式执行完后递增/递减1

要解除类似的困惑,简单的方法是自己直接在控制台测一下,想要更全面的了解就直接读相关的标准。

--------------------------
UPDATE (2015-12-23):

经过

@Belleve
提醒,更正一下:“== 是能产生副作用的,如果你覆写某个对象的 valueOf/toString 的话。”

没错,== 的隐式类型变换正是调用了这两个方法,如果在覆盖的方法里写了带有副作用的代码,确实也会导致 == 带来副作用。

例子:
Array.prototype.valueOf = function() {
  this[0]++;
  return this;
}
var x = [1, 2, 3];
x == 0;
console.log(x);   // [2, 2, 3]

这也侧面印证了, 在搞不清后果的情况下,不应该随便修改预定义对象的 prototype 上的方法。
如果不存在例子中这种带有副作用代码的情况,还是可以放心地使用 ==
编辑于 2015-12-23
33 10 条评论
分享
收藏 感谢 收起
2 人赞同了该回答

一般来说是比较推荐 x==null的做法
没有人说一定使用=== 就好, 至少很多FrameWork 和 Lib 都是用 == 居多

使用==有效避免如下代码:
var a = new String(1)
undefined
a
String {0: "1", length: 1, [[PrimitiveValue]]: "1"}
a=="1"
true
a==="1"
false
很明显 a 就是个货真价实的字符串
编辑于 2015-06-30
2 6 条评论
分享
收藏 感谢
3 人赞同了该回答

不会。不会对比较变量本身产生形象(除非toString或valueOf方法被覆写成特定用途了)。

不推荐的原因是其逻辑比较难懂,容易疏忽出错。

——

括号的例子:
a={};
a.toString=function(){alert(0);};
a.valueOf=function(){alert(1);a=1;};
a==0;//自动依次触发了以上两个函数
alert(a);//已经是1
发布于 2015-12-21
3 添加评论
分享
收藏 感谢
1 人赞同了该回答

== :相等运算符

=== :我更愿意叫它全等运算符


两者区别

第一点:前者仅判断数据的值,而后者是先判断数据的类型,相同的前提下在判断数据的值。

第二点:也就是评论中所说的“操作数类型不同时它们的处理方式不同”


先来说一下"=="的情况:

1. 两个不同的基本数据类型 :如果两个基本数据类型不同,会将它们转化为数据类型,再进行比较。

var a = 1;
var b = '1';
var c = true;
alert(a == b); //true
alert(a == c); //true
alert(b == c); //true

2. 一个基本数据类型与一个引用数据类型 :会将对象转化为它的原始值,在与基本数据类型进行比较。

var arr = [1,2];
var str = "1,2";
alert(arr == str);  //内部执行valueOf(),将arr值转化为原始值,但是arr并没有变化,显示true

将对象转化为它的原始值,也就是说后台会自动调用Object.prototype.valueOf()方法:

var arr = [1,2];
var str = "1,2";

alert(arr.__proto__.hasOwnProperty("valueOf")); //false
alert(Object.prototype.hasOwnProperty("valueOf")); //true

Object.prototype.valueOf = function(){
	alert("valueOf"); //valueOf 
};

alert(arr == str);  // 因为自己写的valueOf()重新覆盖了Object.prototype.valueOf()方法,所以不能实现原始值的转化,具体请百度valueOf()内部实现机制,所以此处显示false

3. 两个引用类型:判断两者之间的引用地址

var arr1 = [1,2]; //引用地址1
var arr2 = [1,2]; //引用地址2
alert(arr1 == arr2); //两者引用地址不同,显示false

再来说一下"==="的情况:

相对于"=="来说,只要类型不一致,它就直接返回false,并不会像"=="那样去转换类型再比较的情况。


不过还是建议尽量使用"===",因为"=="不严谨,可能会带来一些违反直觉的后果。比如我们常使用的对象,有时获取不到而被赋值为undefine的情况。

var obj = undefined;

if(obj == null){
  console.log("1");  //执行
}

if(obj === null){
  console.log("2");  //不执行
}
发布于 2017-06-25
1 4 条评论
分享
收藏 感谢 收起
7 人赞同了该回答
哈哈题主说还没有一个充分的理由,那就让我来给你。问题主一个问题:JavaScript 里各种比较坑你踩过吗?比如下面这些表达式,你猜猜答案是什么:
undefined == null
false == " \t     "
"" == 0
123 == "123"
"1" == true
上面的答案都是true。
虽然你可以说,既然语言这样设计,肯定有它自己的道理啊。但是别忘了,JavaScript 是一个动态类型语言啊,假如你写了这样的代码:
function fix(n) {
if (n == 0) return x + 1;
return x + 2;
}

如果输入n为字符串值"0"的话,恭喜你,你的程序爆炸啦!
你将会得到字符串"01"作为返回值,而不是你想要的数字1。
所以一句话概括:没有类型限制,类型转换的后果将是不可预料的。
而且你写的程序很大的话,你可能在这上面浪费好几个小时找 bug。
所以在自己需求明确的情况下,为什么不写===来避免可能的 bug 呢?

---------平反分割线---------
那么这种不严格比较确实就一无是处吗?不,比如你想判断一个字符串看起来是不是空白的(由空白字符组成),可以这样写:
if (typeof str === "string" && str == false)
console.log("The string is full of white spaces!");
编辑于 2017-01-08
7 3 条评论
分享
收藏 感谢
1 人赞同了该回答
上面各位大神已经把原理/不同点说的一清二楚了。 我就说一句


珍爱生命, 远离 ==
发布于 2015-12-22
1 2 条评论
分享
收藏 感谢

1. 不会对比较逻辑以外的代码造成影响。
2. 还是推荐使用 === ,除了( x == null )以外。优点是逻辑/语义清晰,可以防止意外的错误。比如 `'1' == 1` 为 true,但这真的是题主期待的行为吗?

另外,如果题主真的想透彻了解 == 和 === 的区别,请阅读ES规范——真的一步一步交代了比较的整个流程。
发布于 2015-12-21
0 添加评论
分享
收藏 感谢
3 人赞同了该回答

“双等号会造成类型转换,推荐一律使用三等号”
这明显是不对的吧!
1、对于string,number等基础类型,==和===是有区别的
1)不同类型间比较,==之比较“转化成同一类型后的值”看“值”是否相等,===如果类型不同,其结果就是不等
2)同类型比较,直接进行“值”比较,两者结果一样

2、对于Array,Object等高级类型,==和===是没有区别的
进行“指针地址”比较
发布于 2015-06-19
3 2 条评论
分享
收藏 感谢
5 人赞同了该回答

首先,== equality 等同,=== identity 恒等。

==, 两边值类型不同的时候,要先进行类型转换,再比较。

===,不做类型转换,类型不同的一定不等。


==操作符:
如果两个值具有相同类型,会进行===比较,返回===的比较值
如果两个值不具有相同类型,也有可能返回true
如果一个值是null另一个值是undefined,返回true
如果一个值是string另个是number,会把string转换成number再进行比较
如果一个值是true,会把它转成1再比较,false会转成0
如果一个值是Object,另一个是number或者string,会把Object利用 valueOf()或者toString()转换成原始类型再进行比较
===操作符:
要是两个值类型不同,返回false
要是两个值都是number类型,并且数值相同,返回true
要是两个值都是stirng,并且两个值的String内容相同,返回true
要是两个值都是true或者都是false,返回true
要是两个值都是指向相同的Object,Arraya或者function,返回true
要是两个值都是null或者都是undefined,返回true
发布于 2015-06-19
5 添加评论
分享
收藏 感谢
5 人赞同了该回答
爹==干爹 true
爹===干爹 false
发布于 2015-12-24
5 添加评论
分享
收藏 感谢
2 人赞同了该回答

我知道的除了忽略类型外还有就是双等号不具有传递型,有时候a==b, a==c, 但是b!=c,具体是什么值记不得了,这种情况在《JavaScript语言精粹》中提到过,所以书的作者推荐使用三等号。

-------
放个图:
编辑于 2016-05-12
2 添加评论
分享
收藏 感谢
1 人赞同了该回答

==其实很好用啊,有一夫当关万夫莫开的快感

发布于 2017-09-16
1 添加评论
分享
收藏 感谢
1 人赞同了该回答

严格相等运算符“===”首先计算其操作数的值,然后比较这两个值,比较过程没有任何类型转换:
1·如果两个值类型不相同,则它们不相等。
2·如果两个值都是null或者都是undefined,则它们不相等。
3·如果两个值都是布尔值true或都是布尔值false,则它们相等。
4·如果其中一个值是NaN,或者两个值都是NaN,则它们不相等。NaN和其他任何值都是不相等 的,包括它本身!通过x!==x来判断x是否为NaN,只有在x为NaN的时候,这个表达式的值才为 true。
5·如果两个值为数字且数值相等,则它们相等。如果一个值为0,另一个值为-0,则它们同样相 等。
6·如果两个值为字符串,且所含的对应位上的16位数(参照3.2节)完全相等,则它们相等。如果 它们的长度或内容不同,则它们不等。两个字符串可能含义完全一样且所显示出的字符也一 样,但具有不同编码的16位值。JavaScript并不对Unicode进行标准化的转换,因此像这样的字 符串通过“===”和“==”运算符的比较结果也不相等。第三部分的String.localeCompare()提供了另 外一种比较字符串的方法。
7·如果两个引用值指向同一个对象、数组或函数,则它们是相等的。如果指向不同的对象,则它 们是不等的,尽管两个对象具有完全一样的属性。

相等运算符“==”和恒等运算符相似,但相等运算符的比较并不严格。如果两个操作数不是同一类型,那么相等运算符会尝试进行一些类型转换,然后进行比较:
1·如果两个操作数的类型相同,则和上文所述的严格相等的比较规则一样。如果严格相等,那 么比较结果为相等。如果它们不严格相等,则比较结果为不相等。
2·如果两个操作数类型不同,“==”相等操作符也可能会认为它们相等。检测相等将会遵守如下 规则和类型转换:
—如果一个值是null,另一个是undefined,则它们相等。
—如果一个值是数字,另一个是字符串,先将字符串转换为数字,然后使用转换后的值 进行比较。
—如果其中一个值是true,则将其转换为1再进行比较。如果其中一个值是false,则将 其转换为0再进行比较。
—如果一个值是对象,另一个值是数字或字符串,则使用3.8.3节所提到的转换规则将 对象转换为原始值,然后再进行比较。对象通过toString()方法或者valueOf()方法转 换为原始值。JavaScript语言核心的内置类首先尝试使用valueOf(),再尝试使用 toString(),除了日期类,日期类只使用toString()转换。那些不是JavaScript语言核心 中的对象则通过各自的实现中定义的方法转换为原始值。
—其他不同类型之间的比较均不相等。
这里有一个判断相等的小例子:
"1"==true
这个表达式的结果是true,这表明完全不同类型的值比较结果为相等。布尔值true首先转换为数字1,然后再执行比较。接下来,字符串“1”也转换为了数字1,因为两个数字的值相等,因此比较结果为true。
摘自:《JavaScript权威指南(第六版)》
发布于 2016-01-13
1 添加评论
分享
收藏 感谢 收起
1 人赞同了该回答
对于明确数据类型的用===更为可靠,JavaScript是一门弱类型语言表达式运算赋值等操作都会导致类型转换
发布于 2015-12-27
1 添加评论
分享
收藏 感谢

来源:《你不知道的javascript》中卷
根源:ES5规范文档
“区别在于操作数类型不同时它们的处理方式不同”
对于不同的操作类型 它们的处理方式有哪些不同 请看文档
如es5 11.9.3.4-5 定义
1.如果Type(x)是数字 Type(y)是字符串 则返回x == ToNumber(y)的结果
2.如果Type(x)是字符串 Type(y)是数字 则返回 ToNumber(x) == y的结果
eg:
var a = 42;
var b = "42"

a === b ;//检查类型 类型不一致 不允许进行强制类型转换 所以为 false
a == b;//检查类型 类型不一致 Type(y) 为字符串 进行 ToNumber操作 "42"强制转换为42 再进行比较结果为 true

对于操作数为其他类型 比如操作数中有布尔值的 也有规范说明

先通读下规范吧 不要用想当然的运行处理逻辑来思考 人家都写着规范呢

书中对其他非常规 和 极端情况 都做了说明和总结

ps:非常规和极端情况 多数也是由规范引导的
发布于 2016-09-18
0 添加评论
分享
收藏 感谢
==只比较值 不比较类型
===即比较值 也比较类型
发布于 2016-05-13
0 添加评论
分享
收藏 感谢
下载知乎客户端
与世界分享知识、经验和见解
相关问题
关于JavaScript new 的一些疑问? 7 个回答
JavaScript的学习难点在哪? 19 个回答
JavaScript 中有可能模拟出类的私有变量吗? 11 个回答
怎么样去学习才能把JavaScript学好? 8个回答
说说你遇到的Javascript操作DOM的一些坑? 13 个回答
相关推荐
Javascript 中 == 和 === 区别是什么?_第7张图片
人人都用得上的艺术课
翁昕
共 13 节课
试听
Javascript 中 == 和 === 区别是什么?_第8张图片
前端工程师如何不断自我提升
17434 人参与
live
HTML5 应用开发实践指南
Zachary Kessin
2,361 人读过 阅读
刘看山 知乎指南 知乎协议 应用 工作
申请开通知乎机构号
侵权举报 网上有害信息举报专区
违法和不良信息举报:010-82716601
儿童色情信息举报专区
联系我们 © 2018 知乎

你可能感兴趣的:(Javascript 中 == 和 === 区别是什么?)