一. 基础类型
A. 基础类型有 5 种, Number,String,Boolean,Null,Undefined
B. 基础类型没有堆的概念, 堆只针对引用类型.
所有基础类型都是以 key-value 形式存放在栈中, 其中, 基础类型的值不可变, 除非是重新赋值,
比如:
- var a = "1234";
- a[0] = "k";// 对值本身修改, 无效
- console.log(a)//1234
- a = "k";// 重新赋值
- console.log(a)//k
二. 引用类型
引用类型, 如 Array,Object,Function,Date,RegExp 等
所有引用类型都是以 key-value 形式存放在栈中, 其中, 引用类型的 key-value 存放的 value 是指针地址, 地址指向所在的堆的某个空间 , 这个空间存放着引用类型数据的值.
注意:
引用数据的值为 "堆值", 设堆值为 value1 , 堆值对象内部的的 key-value 形式的 value 值为值中值 , 设此堆值为 "value2" , 在当前例子中, value1 是可改变的, value2 是不可改变的, 除非是重新赋值.
比如:
- // 堆值, 即 value1, 可改变
- var a = {
- "name":"jack"
- };
- a = [];// 重新赋值
- console.log(a)// []
- // 堆值中值, 即 value2, 与基本数据类型一样不可改变
- var a = {
- "name":"jack"
- };
- a.name[0] = "0";
- console.log(a)// {
- "name":"jack"
- }
三. 传值与传址
3.1 传值, 如下图所示
image.PNG
基础类型传值. A 代码块执行, a 和 b 都会在栈区开辟一个空间用来存放值 10, 并且以 key-value 形式存放.
3.2 传址, 如下图所示
image.PNG
引用类型传址. 上图示例代码块执行, a 会开辟一个空间用来存放指针地址, 然后 a 的指针地址会赋值给 b, 即 b 同样会开辟一个空间用来放指针地址, 而 a,b 指针地址指向的都是堆区的 "堆值", 即 value1.
四. 比较
4.1 基础类型的比较是值的比较
比如:
- var a = 1;
- var b = 1;
- console.log(a == b);//true
4.2 引用类型的比较是引用的比较
同一个引用比较是可以相等, 因为指向同一个地方的地址可能是一样的; 不同引用的比较不等, 因为指向两个不同地方的地址是不一样的.
比如:
- // 不同引用的比较
- var p1 = {
- };
- var p2 = {
- };
- console.log(p1 == p2) //false
- // 不同引用的比较
- var p3 = {
- "name":{
- },"age":30
- };
- var p4 = {
- "name":{
- },"age":30
- };
- console.log(p3.name == p4.name);//false(这个是引用比较)
- console.log(p3.age == p4.age);//true(这个是值比较)
- // 同引用的比较
- var p5 = {
- };
- var p6 = p5;
- console.log(p5 == p6)//true
如果引用被赋值别的类型, 那么当前引用会被切断和值的联系, 也就是指针地址.
如下图:
image.PNG
当 a1 重新赋值的时候, a1 和 "堆值 --> {}" 的联系被替换成新的指针地址, 即 "堆值 --> []"
五. 总结
基本数据类型赋值仅限于栈内传递并且传递的是值, 引用数据类型的栈内传递的是栈和堆的联系地址, 值是放在堆里面不动.
年初整理了一批 web 前端教程, 帮助想要成为 Web 前端程序员的人. 从零基础到各种框架的教程都有. 只需要加入到 Web 前端学习 qun:296,212,562. 即可免费领取, 学习过程中有任何问题可以在里面问. 种一颗树最好的时间是十年前, 其次是现在. 只要想学习, 不存在早晚.
来源: http://www.jianshu.com/p/7b600b7c193e