在js中,我们知道对象是引用类型,我们使用时定义的变量都是指向其内存地址。一个内存地址只对应一个对象,
内存地址不一样,两个对象就是内容再相同也是不相等的。
有时候我们指的两个对象相等指的是内容相同,那么此时我们应该如何去比较两个对象内容相同呢,underscore.js
给出了两个主要函数:eq和deepEq函数。
eq主要是进行基本的判断,比如+0和-0,NaN和NaN deepEq主要对不同的基本类型进行判,(不同的基本类型对应不同的判断方法),其中数组是一个比较麻烦的对象,
如要比较数组里面的内容是否相同。
下面是两个函数的具体代码和注释
var eq,deepEq; //eq是第一层比较,主要进行简单的筛别 eq = function(a,b,aStack,bStack){ if(a === b){ //0这个情况要特殊对待,因为我们认为+0不等于-0 return a !==0 || 1/a === 1/b; } if(a === null || b === null){ return false; } //用来判断NaN的情况 if(a !== a){ return b!==b; } var type = typeof a; if(type !== 'function' && type !== 'object' && typeof b != 'object'){ return false; } //开始深度递归 return deepEq(a,b,aStack,bStack); }; deepEq = function(a,b,aStack,bStack){ //如果a,b是_的一个实例 if(a instanceof _){ a = a._wrapped; } if(b instanceof _){ b = b._wrapped; } //通过对象所属的类进行第一步比较,类不相同直接pass掉 var className = toString.call(a); if(className !== toString.call(b)){ return false; } //Strings, numbers, regular RegExp, dates, and booleans可以直接通过值来比较 switch(className){ case '[object RegExp]' : case '[object String]' : //字符串和正则可以看作是同一类,转化成字符串直接比较 return '' + a === '' + b; case '[object Number]' : if(+a !== +a){//判断NaN return +b !== +b; } //正负0特别判断 return +a === 0 ? 1 / +a === 1 / b : +a === +b; case '[object Date]' : case '[object Boolean]' : //Date和Boolean可以看作一类比较 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'){//a,b有一个不是对象 return false; } //此时得到的a,b都是对象 var aCtor = a.constructor,bCtor = b.constructor;//得到a,b两个的构造函数 if(aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && _.isFunction(bCtor) && bCtor instanceof bCtor) && ('constructor' in a && 'constructor' in b)){ return false; } } aStack = aStack || []; bStack = bStack || []; var length = aStack.length; while(length--){ if(aStack[length] === a){ return bStack[length] === b; } } //将a,b两个对象入栈 aStack.push(a); bStack.push(b); if(areArrays){//数组情况 length = a.length;//获取数组a的长度 if(length !== b.length){//长度不一致pass掉 return false; } while(length--){ if(!eq(a[length],b[length],aStack,bStack)){//判断数组内容是否相同 return false; } } }else{ //不是数组是对象的情况 var keys = _.keys(a),key; //得到a的所有键 length = keys.length; if(_.keys(b).length !== length){//如果a,b的键数组的长度不一致,pass掉。 return false; } //a,b的键数组长度一致 while(length--){ key = keys[length];//从键数组中获取键 if(!(_.has(b,key) && eq(a[key],b[key],aStack,bStack))){ //b里面没有该键名pass掉, &&后的这个条件用来判断键值是否相等,(键值也可能是对象什么的) return false; } } } //出栈操作 aStack.pop(); bStack.pop(); return true; }; _.isEqual = function(a,b){ return eq(a,b); };
Original url: Access
Created at: 2019-11-26 22:19:56
Category: default
Tags: none
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论