本文翻译自:Object comparison in JavaScript [duplicate]

This question already has answers here : 这个问题已经在这里有了答案 :
How to determine equality for two JavaScript objects? 如何确定两个JavaScript对象的相等性? (59 answers) (59个回答)
Closed 3 years ago . 3年前关闭。

What is the best way to compare objects in JavaScript? 在JavaScript中比较对象的最佳方法是什么?

Example: 例:

var user1 = {name : "nerd", org: "dev"};
var user2 = {name : "nerd", org: "dev"};
var eq = user1 == user2;
alert(eq); // gives false

I know that two objects are equal if they refer to the exact same object , but is there a way to check if they have the same attributes' values? 我知道两个对象如果引用完全相同的对象则相等 ,但是有没有办法检查它们是否具有相同的属性值?

The following way works for me, but is it the only possibility? 以下方法对我有用,但这是唯一的可能性吗?

var eq = Object.toJSON(user1) == Object.toJSON(user2);
alert(eq); // gives true

#1楼

参考:https://stackoom.com/question/4U3G/JavaScript中的对象比较-重复


#2楼

Certainly not the only way - you could prototype a method (against Object here but I certainly wouldn't suggest using Object for live code) to replicate C#/Java style comparison methods. 当然不是唯一的方法-您可以对方法进行原型设计(针对Object,但我当然不建议将Object用于实时代码)来复制C#/ Java样式比较方法。

Edit, since a general example seems to be expected: 编辑,因为似乎有一个一般的例子:

Object.prototype.equals = function(x)
{for(p in this){switch(typeof(this[p])){case 'object':if (!this[p].equals(x[p])) { return false }; break;case 'function':if (typeof(x[p])=='undefined' || (p != 'equals' && this[p].toString() != x[p].toString())) { return false; }; break;default:if (this[p] != x[p]) { return false; }}}for(p in x){if(typeof(this[p])=='undefined') {return false;}}return true;
}

Note that testing methods with toString() is absolutely not good enough but a method which would be acceptable is very hard because of the problem of whitespace having meaning or not, never mind synonym methods and methods producing the same result with different implementations. 请注意,使用toString()进行测试的方法绝对不够好,但是由于空白是否有意义,问题是很难接受的,不要说同义词方法和使用不同实现产生相同结果的方法。 And the problems of prototyping against Object in general. 以及一般针对对象的原型问题。


#3楼

如果要显式检查方法,则可以使用method.toSource()或method.toString()方法。


#4楼

Unfortunately there is no perfect way, unless you use _proto_ recursively and access all non-enumerable properties, but this works in Firefox only. 不幸的是,没有完美的方法,除非您递归使用_proto_并访问所有不可枚举的属性,但这仅在Firefox中有效。

So the best I can do is to guess usage scenarios. 因此,我能做的最好是猜测使用情况。


1) Fast and limited. 1)快速且有限。

Works when you have simple JSON-style objects without methods and DOM nodes inside: 当您具有简单的JSON样式的对象,而内部没有方法和DOM节点时,则可以使用:

 JSON.stringify(obj1) === JSON.stringify(obj2)

The ORDER of the properties IS IMPORTANT, so this method will return false for following objects: 属性的ORDER重要,因此对于以下对象,此方法将返回false:

 x = {a: 1, b: 2};y = {b: 2, a: 1};

2) Slow and more generic. 2)速度较慢,通用性更高。

Compares objects without digging into prototypes, then compares properties' projections recursively, and also compares constructors. 在不深入研究原型的情况下比较对象,然后递归比较属性的投影,还比较构造函数。

This is almost correct algorithm: 这几乎是正确的算法:

function deepCompare () {var i, l, leftChain, rightChain;function compare2Objects (x, y) {var p;// remember that NaN === NaN returns false// and isNaN(undefined) returns trueif (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {return true;}// Compare primitives and functions.     // Check if both arguments link to the same object.// Especially useful on the step where we compare prototypesif (x === y) {return true;}// Works in case when functions are created in constructor.// Comparing dates is a common scenario. Another built-ins?// We can even handle functions passed across iframesif ((typeof x === 'function' && typeof y === 'function') ||(x instanceof Date && y instanceof Date) ||(x instanceof RegExp && y instanceof RegExp) ||(x instanceof String && y instanceof String) ||(x instanceof Number && y instanceof Number)) {return x.toString() === y.toString();}// At last checking prototypes as good as we canif (!(x instanceof Object && y instanceof Object)) {return false;}if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {return false;}if (x.constructor !== y.constructor) {return false;}if (x.prototype !== y.prototype) {return false;}// Check for infinitive linking loopsif (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {return false;}// Quick checking of one object being a subset of another.// todo: cache the structure of arguments[0] for performancefor (p in y) {if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {return false;}else if (typeof y[p] !== typeof x[p]) {return false;}}for (p in x) {if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {return false;}else if (typeof y[p] !== typeof x[p]) {return false;}switch (typeof (x[p])) {case 'object':case 'function':leftChain.push(x);rightChain.push(y);if (!compare2Objects (x[p], y[p])) {return false;}leftChain.pop();rightChain.pop();break;default:if (x[p] !== y[p]) {return false;}break;}}return true;}if (arguments.length < 1) {return true; //Die silently? Don't know how to handle such case, please help...// throw "Need two or more arguments to compare";}for (i = 1, l = arguments.length; i < l; i++) {leftChain = []; //Todo: this can be cachedrightChain = [];if (!compare2Objects(arguments[0], arguments[i])) {return false;}}return true;
}

Known issues (well, they have very low priority, probably you'll never notice them): 已知问题(嗯,它们的优先级很低,可能您永远不会注意到它们):

  • objects with different prototype structure but same projection 具有不同原型结构但投影相同的对象
  • functions may have identical text but refer to different closures 函数可能具有相同的文本,但是引用了不同的闭包

Tests: passes tests are from How to determine equality for two JavaScript objects? 测试:通过测试来自于如何确定两个JavaScript对象的相等性? .


#5楼

If you work without the JSON library, maybe this will help you out: 如果您不使用JSON库,则可能会为您提供帮助:

Object.prototype.equals = function(b) {var a = this;for(i in a) {if(typeof b[i] == 'undefined') {return false;}if(typeof b[i] == 'object') {if(!b[i].equals(a[i])) {return false;}}if(b[i] != a[i]) {return false;}}for(i in b) {if(typeof a[i] == 'undefined') {return false;}if(typeof a[i] == 'object') {if(!a[i].equals(b[i])) {return false;}}if(a[i] != b[i]) {return false;}}return true;
}var a = {foo:'bar', bar: {blub:'bla'}};
var b = {foo:'bar', bar: {blub:'blob'}};
alert(a.equals(b)); // alert's a false

#6楼

I have modified a bit the code above. 我已经修改了上面的代码。 for me 0 !== false and null !== undefined . 对我来说0!== falsenull!== undefined If you do not need such strict check remove one " = " sign in " this[p] !== x[p] " inside the code. 如果您不需要这样严格的检查,请在代码中删除一个“ = ”登录“ this [p]!== x [p] ”。

Object.prototype.equals = function(x){for (var p in this) {if(typeof(this[p]) !== typeof(x[p])) return false;if((this[p]===null) !== (x[p]===null)) return false;switch (typeof(this[p])) {case 'undefined':if (typeof(x[p]) != 'undefined') return false;break;case 'object':if(this[p]!==null && x[p]!==null && (this[p].constructor.toString() !== x[p].constructor.toString() || !this[p].equals(x[p]))) return false;break;case 'function':if (p != 'equals' && this[p].toString() != x[p].toString()) return false;break;default:if (this[p] !== x[p]) return false;}}return true;
}

Then I have tested it with next objects: 然后,我用下一个对象对其进行了测试:

var a = {a: 'text', b:[0,1]};
var b = {a: 'text', b:[0,1]};
var c = {a: 'text', b: 0};
var d = {a: 'text', b: false};
var e = {a: 'text', b:[1,0]};
var f = {a: 'text', b:[1,0], f: function(){ this.f = this.b; }};
var g = {a: 'text', b:[1,0], f: function(){ this.f = this.b; }};
var h = {a: 'text', b:[1,0], f: function(){ this.a = this.b; }};
var i = {a: 'text',c: {b: [1, 0],f: function(){this.a = this.b;}}
};
var j = {a: 'text',c: {b: [1, 0],f: function(){this.a = this.b;}}
};
var k = {a: 'text', b: null};
var l = {a: 'text', b: undefined};

a==b expected true; a == b预期为true; returned true 返回真

a==c expected false; a == c预期为false; returned false 返回假

c==d expected false; c == d预期为假; returned false 返回假

a==e expected false; a == e预期为假; returned false 返回假

f==g expected true; f == g预期为真; returned true 返回真

h==g expected false; h == g预期为假; returned false 返回假

i==j expected true; i == j预期为真; returned true 返回真

d==k expected false; d == k预期为假; returned false 返回假

k==l expected false; k == l预期为假; returned false 返回假

JavaScript中的对象比较[重复]相关推荐

  1. 如何从JavaScript中的对象数组中获得不同的值?

    本文翻译自:How to get distinct values from an array of objects in JavaScript? Assuming I have the followi ...

  2. 在JavaScript中解析查询字符串[重复]

    本文翻译自:Parse query string in JavaScript [duplicate] Possible Duplicate: 可能重复: How can I get query str ...

  3. 创建健壮的isArray()函数(JavaScript中判断对象类型的种种方法)

    我们知道,JavaScript中检测对象类型的运算符有:typeof.instanceof,还有对象的constructor属性: 1) typeof 运算符 typeof 是一元运算符,返回结果是一 ...

  4. 在JavaScript中删除对象

    本文翻译自:Deleting Objects in JavaScript I'm a bit confused with JavaScript's delete operator. 我对JavaScr ...

  5. 如何在Javascript中访问对象的第一个属性?

    本文翻译自:How to access the first property of an object in Javascript? Is there an elegant way to access ...

  6. 检查值是否是JavaScript中的对象

    如何检查值是否是JavaScript中的Object? #1楼 尝试这个 if (objectName instanceof Object == false) {alert('Not an objec ...

  7. Javascript中的对象和原型(一)(转载)

    面向对象的语言(如Java)中有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.但是,JavaScript 没有类的概念,因此它的对象也与基于类的语言中的对象有所不同. 要了解面向对象,首 ...

  8. name optimize is not defined 怎么解决_Web前端:怎么在JavaScript中比较对象?

    大家好,我来了,本期为大家带来的前端开发知识是"Web前端:怎么在JavaScript中比较对象?",有兴趣做前端的朋友,一起来看看吧! 比较JavaScript中的原始值很简单. ...

  9. Javascript中的对象查找【转】

    编辑点评:本文作者为大家介绍Javascript中的对象查找一些问题,希望有所帮助. 近期群里常有人提一些简单的问题,比如发一段代码乱七八糟的代码,然后说里面某个变量是什么,比如这里就有个很好的例子: ...

最新文章

  1. 限时删!一套目标检测、卷积神经网络和OpenCV学习资料(教程/PPT/代码)
  2. lable、ul、ol、dl和table、fieldset标签
  3. MSF(一):MSF基础
  4. C++ string容器
  5. sql server 2005安装需求
  6. 我的知识管理工具列表
  7. 2018年4月蓝桥杯省赛经历
  8. 【论文阅读】去偏、缓解数据稀疏的多任务因果推荐CVR优化
  9. php蘑菇街商城源码,php源码:dedecms精仿蘑菇街(mogujie.com)源码,时尚购物社区源码...
  10. Thinkpad禁用触摸板
  11. wow Warlock shushia PVP DZ
  12. Spring的ioc控制反转
  13. 完美解决Idea unable to access git 错误
  14. 二维码生成与解析代码实现
  15. pandas 玩转 Excel 操作总结
  16. Python中的错误和异常
  17. xshell 传文件的常用两种方案rz(小于4G)和sftp(大于4G)
  18. 算法工程师面试题八之交叉验证
  19. 单片机反相器_基于AT89S52单片机的新型智能家居安防系统
  20. IBM T61 8889-A91 XP完整版安装说明

热门文章

  1. js实现字符串的加密与解密
  2. @protocol 和 category 中如何使用 @property
  3. 三月活动之“桃花朵朵开 求爱上上签”
  4. JavaScript 开发进阶:理解 JavaScript 作用域和作用域链
  5. mysql修改默认的存储引擎
  6. Linux Shell编程(2)——第一个shell程序
  7. 计算数字1至10的总和
  8. 好东西真多,如何让自己学的能跟上技术的发展呢
  9. Linux性能调优集合
  10. sftp配置导致ssh连接闪断