简体   繁体   English

为什么 2 个空 JavaScript 函数或普通对象不相等

[英]Why are 2 empty JavaScript functions or plain objects not equal

In this snippet of code I'm defining two functions, outputting them and their string representations to console, and also comparing them:在这段代码中,我定义了两个函数,将它们及其字符串表示输出到控制台,并比较它们:

var a = function func() {},
    b = function func() {};

// string representations are equal
console.log(a.toString());
console.log(b.toString());
console.log(a.toString() == b.toString());
console.log(a.toString() === b.toString());

// functions seem to be equal
console.log(a);
console.log(b);

// but they're not really as this prints false
console.log(a == b);
console.log(a === b);

Why are they not equal?为什么它们不相等?

Same happens of course to empty plain objects, ie {} .当然,空的普通对象也会发生同样的情况,即{}

Funny thing though is that lodash isEqual returns true in this case: _.isEqual({}, {});有趣的是 lodash isEqual在这种情况下返回true_.isEqual({}, {}); and false in this: _.isEqual(function () {}, function () {}) .在此为false_.isEqual(function () {}, function () {}) But of course it's not any proof, it's just the way of implementation of equality.但当然这不是任何证明,这只是实现平等的方式。

Functions are nothing else than objects, so it all comes back to the comparison of 2 objects, and then according to MDN :函数只不过是对象,所以这一切都回到了 2 个对象的比较,然后根据MDN

The equality operator converts the operands if they are not of the same type, then applies strict comparison.如果操作数的类型不同,则相等运算符会对其进行转换,然后应用严格比较。 If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.如果两个操作数都是对象,那么当操作数引用内存中的同一个对象时,JavaScript 会比较内部引用是否相等。

Also the full equality comparison algorithm is described in ECMAScript® Language Specification , and 1.f is obvious: ECMAScript® 语言规范中也描述了完整的相等比较算法,1.f 很明显:

Return true if x and y refer to the same object.如果 x 和 y 引用同一个对象,则返回 true。 Otherwise, return false.否则,返回false。

So by design objects are always compared using reference, which is kind of a pointer to the address in memory.因此,按照设计,对象总是使用引用进行比较,引用是一种指向内存中地址的指针。 If it points to the same, it will return true , if not false is produced.如果它指向相同,它将返回true ,如果不是false则产生。

This is because functions are objects .这是因为函数是对象 In javascript, you cannot test objects for equality like在 javascript 中,您不能测试对象的相等性,例如

obj1 == obj2
obj1 === obj2

See Object comparison in JavaScript for how to correctly compare objects有关如何正确比较对象的信息,请参阅JavaScript 中的对象比较

Just like how Two empty boxes aren't equal and how two twins aren't the same person.就像两个空盒子不相等,两个双胞胎不是同一个人一样。

Sure the functionality of two functions is equal but you can't test that with equal operators alone.确定两个函数的功能是相等的,但你不能单独用相等的运算符来测试它。

Functions are objects, just like two human twins are different things.函数是对象,就像两个人类双胞胎是不同的东西。 Each function is a different thing.每个功能都是不同的东西。

You meant to compare their value but you are measuring their existence.您打算比较它们的价值,但您正在衡量它们的存在。 If that makes sense.如果这是有道理的。

For numbers its simple, their value is their existence.对于数字来说很简单,它们的价值就是它们的存在。 But for ordinary objects.但对于普通对象。 It's not decided what their value is.还没有决定它们的价值是什么。 You could compare all properties of an object against other and see if they all match.您可以将一个对象的所有属性与其他属性进行比较,看看它们是否都匹配。 Then you could say they are identical objects but still can't say they are the same.那么你可以说它们是相同的对象,但仍然不能说它们是相同的。

Same thing with strings, their value is definite.字符串也是一样,它们的价值是确定的。 String value is implied to be the text that it's holding.字符串值被暗示为它所持有的文本。 And when comparing two string compiler goes over every character.当比较两个字符串时,编译器会检查每个字符。 Even though string may have other properties, they dont matter to js compiler.尽管 string 可能有其他属性,但它们对 js 编译器无关紧要。 And it's a good design decision.这是一个很好的设计决策。

so when you convert function's definition to string.所以当你将函数的定义转换为字符串时。 It happens to be equal to definition of the 2nd function if compared character by character, and this is what == operator will do when dealing with strings, will result in truthy value.如果逐个字符进行比较,它恰好等于第二个函数的定义,这就是 == 运算符在处理字符串时所做的事情,将导致真实值。

when you compare 2 function , object , it'll compare the reference (address) of variables, not the value.当您比较 2 function , object ,它将比较变量的引用(地址),而不是值。

var a = function() {}, b = function() {};
(typeof a === typeof b) // true both are 'function'
(a() === b()); // true, both are undefined
(a === b) // false, different reference( address in memory).

/* more info */
var a = b = function() {};
(a === b) // true, they've same reference

 var objA = objB = { hi : 'hello'};
 objA === objB // true;
 objA.hi; // 'hello'
 objB.hi; // 'hello'
 objA.hi = 'aloha';
 objB.hi; // 'aloha';

 objB = null;
 objA === objB ; // false, objB was set new value and no longer hold the reference as objA anymore
console.log('now you got it!');

Hope it could help :).希望它可以帮助:)。

Functions are considered as objects.函数被视为对象。 They may be identical when you try to log当您尝试登录时,它们可能是相同的

const a = (c) => c
const b = (c) => c

console.log(typeof a) // returns "function"
console.log(typeof b) // returns "function"

Their types both returns "function".它们的类型都返回“函数”。 Another example is this另一个例子是这个

console.log(a(7)===b(7)) // returns true

Both types and returns are the same.类型和返回都是相同的。 However, it returns false when you equate it with double equals但是,当您将其与 double equals 等同时,它会返回 false

console.log(a == b) // returns false

because every function has different id or instance.因为每个函数都有不同的 id 或实例。

函数是 JavaScript 世界中的一等对象公民。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM