为什么 [] ==[] 为 false,[] == ![] 为 true,什么是基本类型值和引用类型值
阅读:7922 次 编辑日期:2016-12-05
目录:
概述:
最近被问到一个问题,[] ==[] 为 false;[] == ![] 为 true,这是为什么?看似相等的却不相等,看似不相等的却相等,这主要跟引用类型的值有关,今天我们来说说~
[] == [] 为 false:
[]相当于声明了两个不同的数组,而数组是引用类型的值,引用的是地址,比较的是内存中存的是否是同一个对象,虽然都是两个空数组,但是引用地址不一样,结果当然为false。
基本类型值、引用类型值:
ECMAScript变量包含两种不同类型的值:基本类型值、引用类型值。
基本类型值包括:String,Number,Boolean,undefined,null。那么其他就属于引用类型的值,上面的数组[]自然就是引用类型。
最常用到的引用类型包括Object,Array,Function等等...
两种类型访问方式的区别:
1.基本类型的比较是值,值相等就相等。变量是存在栈里面的,举个栗子:
var name = "uw3c";
var age = 3;
那么它的储存结构是这样的:
栈里包括了变量名称与变量的值。
2.引用类型可以添加属性,也可以删除属性。对象和数组就是最典型的栗子:
//对象
var uw3cObj = {};
uw3cObj.name = "uw3c";
uw3cObj.age = "3";
//数组
var uw3vArr = [];
uw3cArr.push("name");
uw3cArr.push("age");
引用类型的值是同时保存在栈内存和堆内存中的,那么它的储存结构是这样的:
引用类型时按引用访问的,也就是比较两个对象的堆内存中的地址是否相同,从上图可以看出来,地址不相同。
所以,为什么 [] == [] 为 false,就能理解了,因为数组是引用类型的值,是按引用访问的,但是两个对象看似相等,但引用类型要比较堆内存中的地址是否相同。
[] == ![] 为 true:
这个就要说到 == 的比较规则,最后都是转换成 Number 来比较的。
左侧[]:
1.数组不是基本类型,需要先 ToPrimitive([])转换成原始类型, 即 ""。
2.接下来 ToNumber(""), 即 0。
右侧![]:
1.![], 即 false。
2.接下来 ToNumber(false), 即 0。
所以 0 == 0,[] == ![] 为 true。