js数据类型(非常透彻,简单明了){} == {} 结果为什么是false?
var a = function(){console.log(11);}
var b = function(){console.log(11);}
console.log(a == b); // false
console.log({} == {}) // false
console.log([]==[]) // false
相信很多人碰到这种情况,想我这种基本功不扎实的小白,看得一脸懵逼,别急,这个博客会给你讲透,非常容易理解,以后遇到数据类型的问题,都可以迎刃而解。
首先跟大家先说两个概念,stack 栈,heap 堆。
stack 栈
先进后出,自动分配内存空间,有系统自动释放;使用的是一级缓存,他们通常都是被调用时处于存储空间中,调用完立即释放。
heap 堆
队列优先,先进后出;动态分配内存,大小不定也不会自动释放;存放在二级缓存中,生命周期有虚拟机的垃圾回收算法来决定;一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收
js中基本数据类型和引用数据类型
基本数据类型:存在在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配
Undefined / Null / Boolean / Number / String ,他们都是按值存放的,可以直接访问
引用类型: 存放在队内存中的对象;每个空间大小不一样,根据情况进行特定的分配
当我们访问引用数据类型(对象 / 数组 / 函数)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据
所以可以解释var a = function(){console.log(11);},var b = function(){console.log(11);}; a==b 为false了;
变量a实际保存的是指向堆栈中的一个指针,而b保存的是指向堆内存中的另一个对象的指针,虽然这两个对象的值是一样的,但它们是独立的两个对象,占了2份内存空间,所以 a == b
如若 var a = {};var b = a;这时b复制了变量a保存的指针,它们都指向堆内存中同一个对象,所以 a==b 会是true
传值和传址
基本数据类型和引用数据类型最大的区别实际就是传值和传址的区别
var a = [1,2,3,4,5]
var b = a;
var c = a[0];
console.log(b); // [1,2,3,4]
console.log(c) // 1
b[4] = 6;
c = 7
console.log(a[4]); // 6
console.log(a[0]); // 1
从上面代码可以得知,当改变b中的数据时,a也发生了变化,但是当我们改变c值时,a却没有发生变化。这就是传值和传址的区别,因为a是数组,属于引用类型,所以a给b传的是栈中的地址,而不是堆内存中对象。而c仅仅是从a堆内存中获取的一个数值,并保存在栈中,所以b修改的时,会根据地址回到a堆内存中修改;c是直接在栈中修改,并且不能指向a堆内存中。