javascript 判断对像是否相等
在Javascript中相等运算包括"==","==="全等,两者不同之处,不必多数,本篇文章我们将来讲述如何判断两个对象是否相等? 你可能会认为,如果两个对象有相同的属性,以及它们的属性有相同的值,那么这两个对象就相等。那么下面我们通过一个实例来论证下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
var obj1 = { name: "Benjamin", sex : "male"}var obj2 = { name: "Benjamin", sex : "male"}//Outputs: falseconsole.log(obj1 == obj2);//Outputs: falseconsole.log(obj1 === obj2); |
通过上面的例子可以看到,无论使用"=="还是"===",都返回false。主要原因是基本类型string,number通过值来比较,而对象(Date,Array)及普通对象通过指针指向的内存中的地址来做比较。看下面一个例子:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
var obj1 = { name: "Benjamin", sex : "male"};var obj2 = { name: "Benjamin", sex : "male"};var obj3 = obj1;//Outputs: trueconsole.log(obj1 == obj3);//Outputs: trueconsole.log(obj1 === obj3);//Outputs: falseconsole.log(obj2 == obj3);//Outputs: falseconsole.log(obj2 === obj3); |
上例返回true,是因为obj1和ob3的指针指向了内存中的同一个地址。和面向对象的语言(Java/C++)中值传递和引用传递的概念相似。 因为,如果你想判断两个对象是否相等,你必须清晰,你是想判断两个对象的属性是否相同,还是属性对应的值是否相同,还是怎样?如果你判断两个对象的值是否相等,可以像下面这样:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
function isObjectValueEqual(a, b) { // Of course, we can do it use for in // Create arrays of property names var aProps = Object.getOwnPropertyNames(a); var bProps = Object.getOwnPropertyNames(b); // If number of properties is different, // objects are not equivalent if (aProps.length != bProps.length) { return false; } for (var i = 0; i < aProps.length; i++) { var propName = aProps[i]; // If values of same property are not equal, // objects are not equivalent if (a[propName] !== b[propName]) { return false; } } // If we made it this far, objects // are considered equivalent return true;}var obj1 = { name: "Benjamin", sex : "male"};var obj2 = { name: "Benjamin", sex : "male"};//Outputs: trueconsole.log(isObjectValueEqual(obj1, obj2)); |
正如你所看到的,检查对象的“值相等”我们基本上是要遍历的对象的每个属性,看看它们是否相等。虽然这个简单的实现适用于我们的例子中,有很多情况下,它是不能处理。例如: 1) 如果该属性值之一本身就是一个对象吗? 2) 如果属性值中的一个是NaN(在JavaScript中,是不是等于自己唯一的价值?) 3) 如果一个属性的值为undefined,而另一个对象没有这个属性(因而计算结果为不确定?) 检查对象的“值相等”的一个强大的方法,最好是依靠完善的测试库,涵盖了各种边界情况。Underscore和Lo-Dash有一个名为_.isEqual()方法,用来比较好的处理深度对象的比较。您可以使用它们像这样:
|
1
2
|
// Outputs: trueconsole.log(_.isEqual(obj1, obj2)); |
最后附上Underscore中isEqual的部分源码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
// Internal recursive comparison function for `isEqual`.var eq = function(a, b, aStack, bStack) { // Identical objects are equal. `0 === -0`, but they aren't identical. // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). if (a === b) return a !== 0 || 1 / a === 1 / b; // A strict comparison is necessary because `null == undefined`. if (a == null || b == null) return a === b; // Unwrap any wrapped objects. if (a instanceof _) a = a._wrapped; if (b instanceof _) b = b._wrapped; // Compare `[[Class]]` names. var className = toString.call(a); if (className !== toString.call(b)) return false; switch (className) { // Strings, numbers, regular expressions, dates, and booleans are compared by value. case '[object RegExp]': // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') case '[object String]': // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is // equivalent to `new String("5")`. return '' + a === '' + b; case '[object Number]': // `NaN`s are equivalent, but non-reflexive. // Object(NaN) is equivalent to NaN if (+a !== +a) return +b !== +b; // An `egal` comparison is performed for other numeric values. return +a === 0 ? 1 / +a === 1 / b : +a === +b; case '[object Date]': case '[object Boolean]': // Coerce dates and booleans to numeric primitive values. Dates are compared by their // millisecond representations. Note that invalid dates with millisecond representations // of `NaN` are not equivalent. return +a === +b; } if (typeof a != 'object' || typeof b != 'object') return false; // Assume equality for cyclic structures. The algorithm for detecting cyclic // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. var length = aStack.length; while (length--) { // Linear search. Performance is inversely proportional to the number of // unique nested structures. if (aStack[length] === a) return bStack[length] === b; } // Objects with different constructors are not equivalent, but `Object`s // from different frames are. var aCtor = a.constructor, bCtor = b.constructor; if ( aCtor !== bCtor && // Handle Object.create(x) cases 'constructor' in a && 'constructor' in b && !(_.isFunction(aCtor) && aCtor instanceof aCtor && _.isFunction(bCtor) && bCtor instanceof bCtor) ) { return false; } // Add the first object to the stack of traversed objects. aStack.push(a); bStack.push(b); var size, result; // Recursively compare objects and arrays. if (className === '[object Array]') { // Compare array lengths to determine if a deep comparison is necessary. size = a.length; result = size === b.length; if (result) { // Deep compare the contents, ignoring non-numeric properties. while (size--) { if (!(result = eq(a[size], b[size], aStack, bStack))) break; } } } else { // Deep compare objects. var keys = _.keys(a), key; size = keys.length; // Ensure that both objects contain the same number of properties before comparing deep equality. result = _.keys(b).length === size; if (result) { while (size--) { // Deep compare each member key = keys[size]; if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; } } } // Remove the first object from the stack of traversed objects. aStack.pop(); bStack.pop(); return result;};// Perform a deep comparison to check if two objects are equal._.isEqual = function(a, b) { return eq(a, b, [], []);}; |
感谢您的阅读,希望此篇文章对您有所帮助,文中不足之处欢迎批评斧正。
转载声明:
本文标题:Javascript 判断对象是否相等
本文链接:http://www.zuojj.com/archives/775.html,转载请注明转自Benjamin-专注前端开发和用户体验
javascript 判断对像是否相等的更多相关文章
- 《如何使用Javascript判断浏览器终端设备》
WEB开发中如何通过Javascript来判断终端为PC.IOS(iphone).Android呢? 可以通过判断浏览器的userAgent,用正则来判断手机是否是ios和Android客户端. va ...
- JavaScript判断移动端及pc端访问不同的网站
JavaScript判断移动端及pc端访问不同的网站 现在很多网站都是分为两个版本,一个pc端的一个移动端的(响应式除外),针对这两个版本,就需要对访问的设备进行判断,如果是pc,就直接访问pc网站, ...
- 如何使用Javascript判断浏览器终端设备
WEB开发中如何通过Javascript来判断终端为PC.IOS(iphone).Android呢? 可以通过判断浏览器的userAgent,用正则来判断手机是否是ios和Android客户端 var ...
- javascript判断手机旋转横屏竖屏
javascript判断手机旋转横屏竖屏 // 横屏竖屏函数 function orientationChange(){ switch(window.orientation) { case 0: // ...
- JavaScript判断图片是否加载完成的三种方式
JavaScript判断图片是否加载完成的三种方式 有时需要获取图片的尺寸,这需要在图片加载完成以后才可以.有三种方式实现,下面一一介绍. 一.load事件 1 2 3 4 5 6 7 8 9 10 ...
- JavaScript判断是否是手机mobile登录
在页面代码中加入以下js,即可利用JavaScript判断是否是手机mobile登录! <script type="text/javascript" src="${ ...
- Javascript 判断一个数字是否含有小数点
JavaScript 判断一个数字是否含有小数点,如果含有,则返回该数字:如果不含小数点,则小数点后保留两位有效数字: function hasDot(num){ if(!isNaN(num)){ r ...
- JavaScript判断鼠标滑轮是向下还是向上滚动
我们常用的就是鼠标,鼠标中键一般都用于滑动网页,但是网页中很多很炫的效果,使用鼠标滑轮操作更好. 当然对于手机就没有这个设备了,所以就不用考虑手机端的实现方法,手机端有触摸滑动事件. 使用JavaSc ...
- JavaScript判断浏览器类型及版本
JavaScript是前端开发的主要语言,我们可以通过编写JavaScript程序来判断浏览器的类型及版本.JavaScript判断浏览器类型一般有两种办法,一种是根据各种浏览器独有的属性来分辨,另一 ...
- Javascript判断是否是ipad的浏览器
ipad用的是Safari Mobile浏览器,访问的UA为: Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/5 ...
随机推荐
- 过河(状态压缩,dp)
描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上 ...
- 一个简单的js时钟
演示地址 代码 <html> <head> <title> Nonove js clock 时钟 </title> <script type=&q ...
- 编写Java程序,模拟网上商城购物,当用户选好物品提交订单时,每笔订单会自动生成一个唯一的订单编号。
查看本章节 查看作业目录 需求说明: 模拟网上商城购物,当用户选好物品提交订单时,每笔订单会自动生成一个唯一的订单编号.而部分电子商务网站在数据高峰期时,一毫秒可能需要处理近千笔的订单 现在简单模拟 ...
- Gradle sync failed (3 s 402 ms) - Android Studio问题解决方法
问题:Gradle同步失败 解决方法: 删除gradle-wrpper.jar中的 implementation 'com.android.support:design:30.+' 最后在Build中 ...
- 使用.NET 6开发TodoList应用(22)——实现缓存
系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 有的时候为了减少客户端请求相同资源的逻辑重复执行,我们会考虑使用一些缓存的方式,在.NET 6中,我们可以借助框架提供的中间件 ...
- C/C++避免头文件重复包含的方法
C/C++避免头文件重复包含的方法 1. #ifndef 2. #pragma once 3. 混合使用 在实际的编程过程中,因为会使用多个文件,所以在文件中不可避免的要引入一些头文件,这样就可能会出 ...
- 新增访客数量MR统计之Reduce和Runner相关准备
关注公众号:分享电脑学习回复"百度云盘" 可以免费获取所有学习文档的代码(不定期更新)云盘目录说明:tools目录是安装包res 目录是每一个课件对应的代码和资源等doc 目录是一 ...
- Android官方文档翻译 九 2.2Adding Action Buttons
Adding Action Buttons 增加动作按钮 This lesson teaches you to 这节课教给你 Specify the Actions in XML 在XML中指定动作 ...
- day 8 求平均数
fun()函数的功能:计算形参x所指数组中N个数的平均值,(这里全部取浮点数) 并输出,在将大于平均值的数放在形参y所指的数组中,在主函数输出. 效果还不错: 还存在需要优化的分析:其实存到y数组中的 ...
- redis 入门使用
一.Redis 数据类型及结构特点 Redis 最常见的5中数据结构有 String(字符串),List(列表),Set(集合),Hash(散列),Sorted Sets (有序集合),下表简单总结 ...