/*
我们要来判断两个对象是否相等:
首先特殊的是+0和-0,我们知道这两个值是等同的,结果是true
*/
console.log(+0==-0)//true
// 表现2
//(-0).toString() // '0'
//(+0).toString() // '0'
// 表现3
-0 < +0 // false
+0 < -0 // false
/*
但是也有其特殊的差异性
1/+0=+lnfinit 正无穷大
1/-0=-lnfinity 负无穷大
这是因为 JavaScript 采用了IEEE_754 浮点数表示法(几乎所有现代编程语言所采用),这是一种二进制表示法,
按照这个标准,最高位是符号位(0 代表正,1 代表负),剩下的用于表示大小。而对于零这个边界值 ,
1000(-0) 和 0000(0)都是表示 0 ,这才有了正负零的区别。
我们再使用 math.round(-0.1)四舍五入的时候得到这个-0
那么我们如何去区分呢
*/
function kio(a,b){
if(a===b){
//首先a和b是相等的 然后走进这里,如果a不等于0,那么a和b就不能判断,或者b不等于零也不能判读,,
//而1/a和1/b的判断是核心,因为1/+0得到是正无穷大+lnfinity 而1/b得到是负无穷大 是不成里相等的,所有就区分了
//+0和-0的区别
return a!==0 || 1/a==1/b
}
return false
}
kio(0,-0)
console.log( kio(-0,+0))
/*
上面说了+0和-0的区别 还有一个nan这个值 ,这个值有个特点就是nan不等于他自己nan
*/
function kop(a,b){
/*if(a!==b){
return true
}else{
return false
}*/
if(a!==a){
return b!==b
}
}
kop(NaN,NaN)
console.log(kop(NaN,NaN))
/*
根据上面的代码,我们写出来了+0和-0,NaN之间怎么去判断区别的,那么我们下面可以写一个总结的版本的
*/
function kio(a,b){
//首先我们先来区别+0和-0
if(a===b) return a!==0 || 1/a==1/b;
//然后我们阿里判断当a等于null和b等于null的情况
if(a==null||b==null) return false;
//这里是判断NaN的情况
if(a!==a) return b!==b;
//判断参数a的类型,如果是基本类型,这里可以直接返回false
/*
也许你会好奇是不是少了一个 `typeof b !== function`?
试想如果我们添加上了这句,当 a 是基本类型,而 b 是函数的时候,就会进入 deepEq 函数,而去掉这一句,
就会进入直接进入 false,实际上 基本类型和函数肯定是不会相等的,所以这样做代码又少,又可以让一种情况更早退出。
*/
var type=typeof a
if(type!="function" && type!=="object" && typeof b!=="object" ) return false
// 更复杂的对象使用 deepEq 函数进行深度比较
return deepEq(a, b);
}
/*
下面我们如何比较:
"cur"和new String("cur") 据我们知道typeof是不能获得对象形式的数据类型的,因为最后都会的大object,而我们学的还有一种办法
,就是object.prototype.tostring,call()如果是data,match会获得“【object data】”,这种字符串,但是"cur"和new String("cur")返回
的都是[object string] ,所以就没办法去比较了,其实还是有的,用隐式类型转换
+" "这个是可以转换为字符串的方式的
字符串的比较规则是,如果两边都是字符串,那么就一一对比字符编码,来判断是否相等
*/
console.log("cur"+" "===new String("cur") +" ")
/*
那么下面可以封装一个判断函数
*/
var tostrign=Object.prototype.toString()
function jio(a,b){
var classaa=Object.prototype.toString.call(a)
if(classaa!==Object.prototype.toString.call(b)) return false;
switch(classaa){
//case:'[Object object]':
//return "aaaa"
case '[Object string]':
return " "+a===" "+b;
case '[object Number]':
if (" "+a !== " "+a) return " "+b !== " "+b;
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
//case '[object Date]':
//return "aaaa"
case '[object Boolean]':
return " "+a === " "+b;
}
}
jio(true,false)
console.log(jio(NaN,NaN))
console.log(jio(true,new Boolean(true)))
/*
判断两个函数是否相等呢?
function Person() {
this.name = name;
}
function Animal() {
this.name = name
}
var person = new Person('Kevin');
var animal = new Animal('Kevin');
eq(person, animal)
我们要判断,这两个函数,是否相等,我们能判断么???他俩相等么?
虽然 `person` 和 `animal` 都是 `{name: 'Kevin'}`,但是 `person` 和 `animal` 属于不同构造函数的实例,
为了做出区分,我们认为是不同的对象。
```js
//Object.create() 方法会使用指定的原型对象及其属性去创建一个新的对象。
var attrs = Object.create(null);
attrs.name = "Bob";
eq(attrs, {name: "Bob"}); // ???
```
尽管 `attrs` 没有原型,`{name: "Bob"}` 的构造函数是 `Object`,但是在实际应用中,只要他们有着相同的键值对,
我们依然认为是相等。
从函数设计的角度来看,我们不应该让他们相等,但是从实践的角度,我们让他们相等,
所以相等就是一件如此随意的事情吗?!对啊,我也在想:undersocre,你怎么能如此随意呢!!!
哎,吐槽完了,我们还是要接着写这个相等函数,我们可以先做个判断,对于不同构造函数下的实例直接返回 false。
*/
function isFunction(obj) {
return toString.call(obj) === '[object Function]'
}
function deepEq(a, b) {
// 接着上面的内容
var areArrays = className === '[object Array]';
// 不是数组
if (!areArrays) {
// 过滤掉两个函数的情况
if (typeof a != 'object' || typeof b != 'object') return false;
var aCtor = a.constructor, bCtor = b.constructor;
// aCtor 和 bCtor 必须都存在并且都不是 Object 构造函数的情况下,aCtor 不等于 bCtor,
// 那这两个对象就真的不相等啦
if (aCtor == bCtor && !(isFunction(aCtor) && aCtor instanceof aCtor && isFunction(bCtor)
&& bCtor instanceof bCtor) && ('constructor' in a && 'constructor' in b)) {
return false;
}
}
// 下面还有好多判断
}