Javascript Array.prototype.includes函数如何比较对象

Javascript Array.prototype.includes函数如何比较对象,javascript,arrays,javascript-objects,Javascript,Arrays,Javascript Objects,在ECMA规范中,我们读到,当比较数组是否包含给定元素时,使用算法。 此算法,当元素为对象时,它使用的算法基本上检查比较元素的类型是否匹配,最后在算法的最后一点检查: 如果x和y是相同的对象值,则返回true。否则,返回false 我的问题: samevaluennonnumeric算法如何执行对象比较步骤?它如何确定“x和y是相同的对象值”?我在规格中找不到这个 从和问题来看,对象比较在JS中似乎不是那么简单。我猜它使用了抽象等式比较算法来确定对象值是否相同 算法规范。数组.prototype

在ECMA规范中,我们读到,当比较数组是否包含给定元素时,使用算法。 此算法,当元素为对象时,它使用的算法基本上检查比较元素的类型是否匹配,最后在算法的最后一点检查:

如果x和y是相同的对象值,则返回true。否则,返回false

我的问题:

samevaluennonnumeric
算法如何执行对象比较步骤?它如何确定“x和y是相同的对象值”?我在规格中找不到这个


从和问题来看,对象比较在JS中似乎不是那么简单。

我猜它使用了
抽象等式比较算法来确定对象值是否相同


算法规范。

数组.prototype.includes
不应为对象检查提供正确的结果,而是设计用于布尔值、字符串值和数值

对于一个对象,它基本上只是执行一个引用检查,因此如果该对象包含与数组中的引用相同的引用,它将返回true,否则无论对象中的值如何,它都将返回false

var-arr=[{x:1,y:2},{x:2,y:'as'},{x:'in',y:'po'}];
log(arr.includes({x:2,y:'as'}));
控制台日志(arr.includes(arr[1]))如果它们引用相同的内存块,则它们是“相同的对象值”(如果您愿意)

您发现的非直截了当的问题和答案都是关于如何以有意义的方式比较对象内容

用“常规”方式比较对象非常简单,即比较引用,这也是
包含的
在这里所做的。我同意
SameValueNonNumber
中的文本在这一点上有点不清楚,其他算法更清楚地规定了这一点,如步骤1f:

如果x和y引用同一对象,则返回true。否则,返回false

因此:

const a={hello:'world'}
常数b=a
常量c={hello:'world'}
//现在,a和b引用同一个对象,但a/b和c不引用。
console.log([a].includes(a))//true
console.log([a].includes(b))//true
console.log([a].includes(c))//false

通过引用比较对象和符号

我们知道
{}==={}
Symbol()===Symbol()
都返回
false
。快速示例:

console.log([{}]。包含({}));

log([Symbol()])。包括(Symbol())
数组。原型。包括使用
=
运算符进行有效比较。因此,对象通过引用进行比较,基本体通过值进行比较

下面是一个将
包含的
结果与
==
结果进行比较的示例:

const object={'a':'b'};
const copyOfObject=JSON.parse(JSON.stringify(object));
常量数组=[object'a',1];
控制台([
{
“比较”:“对象与对象”,
“Array.prototype.includes的结果”:Array.includes(对象),
'result for==运算符':对象===数组[0]
},
{
“比较”:“对象与copyOfObject”,
“Array.prototype.includes的结果”:Array.includes(copyOfObject),
'result for==运算符':对象===copyOfObject
},
{
'比较':'string“a”vs string“a”,
“Array.prototype.includes的结果”:Array.includes('a'),
'result for==运算符':'a'==数组[1]
},
{
'比较':'字符串“a”与字符串“b”',
“Array.prototype.includes的结果”:Array.includes('b'),
'result for==运算符':'b'==数组[1]
},
{
“比较”:“1号与1号”,
“Array.prototype.includes的结果”:Array.includes(1),
'result for==运算符':1===数组[2]
},
{
“比较”:“1号对2号”,
“Array.prototype.includes的结果”:Array.includes(2),
'result for==运算符':2===数组[2]
},

])
这基本上是
a===b
——它们实际上是不是同一个对象。这对每种情况来说都不重要。一般来说,你如何与物体进行比较?如果两个对象指向同一实例,或者它们具有相同的属性?没有一般性的答案。所以更好的问题应该是你为什么需要它?我觉得比较对象总是表明方法不好。“这只是我个人的意见。@Aaron谢谢你的评论,我想你说得对。我想使用此函数来确定文档(对象)列表中是否已经存在具有相同内容的对象。似乎这是一种不好的方法,通过某个唯一id查找对象会更好。起初,我认为“包含”会让每个属性进行如此“深入”的比较。有时,你必须听取其他人的意见才能重新思考你的设计。很高兴它为您指出了正确的方向:)布尔、字符串和数字简而言之,是基本体。但是布尔、字符串和数字的类型是一个函数而不是基本体,您是指布尔、数字和字符串吗?是的,我指的是布尔值,而不是布尔构造函数