从一道易错题说起
- 题目
var a={name:'A'}
function fn(obj){
obj={name:'B'}
}
fn(a)
console.log(a.name)
- 答案
A
- 解析
定义变量:
a为变量,{name:‘A’}为数据,数据类型为对象;
fn为函数声明(命名),fn()为函数执行。
执行过程:
(1)a变量赋值。将{name:‘A’}这个对象保存到堆内存中,并将这个堆内存的地址(如0x111)赋值到栈内存a变量中——a:0x111
(2)fn执行前,fn不占用内存;fn执行时,形参生成一新的变量obj,传入实参a后,即执行obj=a,将a的内容传给obj——obj:0x111
(3)执行函数内语句obj={name:‘B’}。即再次将(1)的赋值过程执行一遍,将{name:‘B’}的地址(如0x222)保存到obj中——obj:0x222
(4)执行a.name语句。根据a的值(0x111)去查找对应的堆内存{name:‘A’},得到值A。
(5)fn执行后,局部变量obj自动释放,obj指向的堆内存{name:‘B’}会变成垃圾对象,并被垃圾回收期回收,以释放内存。而a作为全局变量会一直存在。
4. 引申
var a={name:'A'}
function fn(obj){
obj.name='B'
}
fn(a)
console.log(a.name)
答案为B
简单分析,obj和a的内容相同(即地址相同),指向同一堆内存,该堆内存改变的话(变为B),a.name也变为B