Javascript中有'=='和'==='两种相等比较,后者是全等,会判断数据类型,前者是相等,在比较时,会发生隐式转换。

如果将两个对象做'=='比较,结果会如何呢?

比如有如下两个对象:

var obj1 = {
name: "Nicole",
sex : "female"
} var obj2 = {
name: "Nicole",
sex : "female"
} //Outputs: false
console.log(obj1 == obj2); //Outputs: false
console.log(obj1 === obj2);

可以看到,哪怕两个对象的属性完全一样,无论是'=='或者'===',返回都是false。

原因:对象通过指针指向的内存地址来做比较。

继续上面的例子:

 var obj3 = obj1;

 //Outputs: true
console.log(obj1 == obj3); //Outputs: true
console.log(obj1 === obj3);

如果想根据两个对象的属性是否相等,来判断对象是否相等,可以参考underscore:isEqual(obj1, obj2):

// Internal recursive comparison function for `isEqual`.
var eq, deepEq;
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;
// `null` or `undefined` only equal to itself (strict comparison).
if (a == null || b == null) return false;
// `NaN`s are equivalent, but non-reflexive.
if (a !== a) return b !== b;
// Exhaust primitive checks
var type = typeof a;
if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;
return deepEq(a, b, aStack, bStack);
}; // Internal recursive comparison function for `isEqual`.
deepEq = function(a, b, aStack, bStack) {
// 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;
case '[object Symbol]':
return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);
} var areArrays = className === '[object Array]';
if (!areArrays) {
if (typeof a != 'object' || typeof b != 'object') return false; // Objects with different constructors are not equivalent, but `Object`s or `Array`s
// from different frames are.
var aCtor = a.constructor, bCtor = b.constructor;
if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
_.isFunction(bCtor) && bCtor instanceof bCtor)
&& ('constructor' in a && 'constructor' in b)) {
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`. // Initializing stack of traversed objects.
// It's done here since we only need them for objects and arrays comparison.
aStack = aStack || [];
bStack = bStack || [];
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;
} // Add the first object to the stack of traversed objects.
aStack.push(a);
bStack.push(b); // Recursively compare objects and arrays.
if (areArrays) {
// Compare array lengths to determine if a deep comparison is necessary.
length = a.length;
if (length !== b.length) return false;
// Deep compare the contents, ignoring non-numeric properties.
while (length--) {
if (!eq(a[length], b[length], aStack, bStack)) return false;
}
} else {
// Deep compare objects.
var keys = _.keys(a), key;
length = keys.length;
// Ensure that both objects contain the same number of properties before comparing deep equality.
if (_.keys(b).length !== length) return false;
while (length--) {
// Deep compare each member
key = keys[length];
if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
}
}
// Remove the first object from the stack of traversed objects.
aStack.pop();
bStack.pop();
return true;
}; // Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
return eq(a, b);
};

JavaScript中对象的比较的更多相关文章

  1. javascript中对象字面量的理解

    javascript中对象字面量与数组字面量 第一部分 我们知道JavaScript中的数据类型有基本数据类型和引用类型,其中Object类型就是非常常用的类型.那么如果创建一个Object类型的实例 ...

  2. 关于JavaScript中对象的继承实现的学习总结

    一.原型链 JavaScript 中原型链是实现继承的主要方法.其主要的思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.实现原型链有一种基本模式,其代码如下. function Super ...

  3. javascript中对象的深度克隆

    记录一个常见的面试题,javascript中对象的深度克隆,转载自:http://www.2cto.com/kf/201409/332955.html 今天就聊一下一个常见的笔试.面试题,js中对象的 ...

  4. JavaScript中对象的属性

    在JavaScript中,属性决定了一个对象的状态,本文详细的研究了它们是如何工作的. 属性类型 JavaScript中有三种不同类型的属性:命名数据属性(named data properties) ...

  5. JavaScript中对象转换为原始值的规则

    JavaScript中对象转换为原始值遵循哪些原则? P52 对象到布尔值对象到布尔值的转换非常简单:所有的对象(包括数字和函数)都转换为true.对于包装对象亦是如此:new Boolean(fal ...

  6. 【你不知道的javaScript 上卷 笔记7】javaScript中对象的[[Prototype]]机制

    [[Prototype]]机制 [[Prototype]]是对象内部的隐试属性,指向一个内部的链接,这个链接的作用是:如果在对象上没有找到需要的属性或者方法引用,引擎就 会继续在 [[Prototyp ...

  7. JavaScript中对象的含义与this的指向

    JavaScript中的对象:无序属性的集合 -其属性可以包含基本值.对象或函数.对象就是一组没有顺序的值.我们可以吧JavaScript中的对象想象成键值对,其中值可以是数据和函数.对象的行为和特征 ...

  8. Javascript中对象的Obeject.defineProperty()方法-------------(ES5/个人理解)

    在讲到Obeject.defineProperty()方法之前先得说明一下ECMAScript中有两种属性:数据属性和访问器属性. 两种属性存在的意义:描述对象属性(key)的一些特性,因为这些属性是 ...

  9. javascript中对象的不同创建方法

    javascript中的对象与一般的面向对象的程序设计语言(c++,Java等)不同,甚至很少有人说它是面向对象的程序设计语言,因为它没有类.javaScript只有对象,不是类的实例.javascr ...

  10. javascript中对象字面量与数组字面量

    第一部分 我们知道JavaScript中的数据类型有基本数据类型和引用类型,其中Object类型就是非常常用的类型.那么如果创建一个Object类型的实例呢?下面我介绍两种方法: 第一:构造函数法. ...

随机推荐

  1. JavaScript的学习--生成二维码

    有一些耗cpu的计算,完全可以在客户端上计算,比如生成二维码. qrcode其实是通过计算,然后使用jquery实现图形渲染和画图.支持canvas和table两种方式生成我们所需的二维码. 具体用法 ...

  2. php基础教程-变量

    变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念.变量可以通过变量名访问.在指令式语言中,变量通常是可变的:但在纯函数式语言(如Haskell)中,变量可能是不可变(immutable) ...

  3. HTML5移动Web开发(一)——HTML5和移动网站基本概念以及一些模拟器

    当前,手机设备发展迅猛.屏幕尺寸各不相同.存储和性能仍有局限性,如何结合HTML5的功能,在多平台上创建高性能.响应式的移动网站,是Web开发者所要面对的首要挑战.HTML5以及移动网站都是很有前景的 ...

  4. 15款免费的 HTML5/CSS3 响应式网页模板

    如果你想快速制作出一个优秀的网站,网站模板一定是必不可少的.网页设计师和开发人员也可以从网站模板入手,学习先进的布局方式和编码风格.下面这个列表为大家挑选了15款免费的 HTML5/CSS3 响应式网 ...

  5. 推荐15款最好的 Twitter Bootstrap 开发工具

    Twitter Bootstrap 自从2011年最初发布到网上后,迅速成为 Web 领域最流行的响应式前端开发框架之一,是网页设计的优秀实践.Twitter Bootstrap 框架包含了众多的预定 ...

  6. 【知识积累】爬虫之网页乱码解决方法(gb2312 -> utf-8)

    前言 今天在测试爬虫项目时,发现了一个很严肃的问题,当爬取的网页编码格式为gb2312时,按照一般的办法转化为utf-8编码时总是乱码,PS:爬取的所有网页无论何种编码格式,都转化为utf-8格式进行 ...

  7. matlab 读取excel

    clear;clc; tic;%启动计时器,计算程序运行时间 a=xlsread('C:\Documents and Settings\Administrator\桌面\data.xls');b=a( ...

  8. SQL Server数字辅助表的实现

        数字辅助表是一个连续整数的数列,通常用来实现多种不同的查询任务.大多分两类:足够大物理数字表和表函数,前者可以称为静态的,后者可以称为动态且按需生产. 物理数字表     物理数字表通常存在一 ...

  9. 【原创】Kakfa common包源代码分析

    初一看common包的代码吓了一跳,这么多scala文件!后面仔细一看大部分都是Kafka自定义的Exception类,简直可以改称为kafka.exceptions包了.由于那些异常类的名称通常都定 ...

  10. 使用ASP.NET MVC局部视图避免JS拼接HTML,编写易于维护的HTML页面

    以前使用ASP.NET WebForm开发时,喜欢使用Repeater控件嵌套的方式开发前台页面,这样就不用JS拼接HTML或者后台拼接HTML了,写出的HTML页面美观.简捷.易于维护,由于不用JS ...