首先说下,在js中有两大类数据类型: 基本类型和引用类型. 其次,基本类型有5种: Undefined,Null,Boolean,Number、String, 引用类型有一种: Object(Function 和 Array都属于对象,在js中,一切皆对象);
基础类型的赋值
var a = 1; var b = a; b = 2; console.log(a); // 1
分析以上代码,初始化变量a为1,然后将a赋值给变量b,再将2赋值给变量b,变量a和变量b属于简单类型,存储在桟中,分别存着1和2,相互之间没有影响.
引用类型的赋值
var a = [1,2,3]; var b = a; b.push(4,5,6); console.log(a); // [1,2,3,4,5,6]
分析以上代码,初始化变量a为[1,2,3],然后将a赋值给变量b,变量a和变量b属于引用类型,存储在堆中,他们存着相同的值(0x****),他们的值其实一个指针地址(指向堆中存放的[1,2,3]), 然后将[4,5,6]添加到变量b,b所指的那个对象现在变为[1,2,3,4,5,6],因为a和b指向同一个对象,因此a的值也为[1,2,3,4,5,6]
函数按值传参
function setName(obj){ obj.name="nick"; obj=new Object(); obj.name="greg"; } var person=new Object(); setName(person); alert(person.name); //"nick"
书中给的例子是以上代码.用反证法证明,假设person是按引用传递的参数,则在函数中name属性已经被赋值“greg”,所以结果应该为greg才对.
正是因为person是按值传递,才出现以上结果.person传进函数的是指向person对象的地址(0x****),将这个地址值赋值给形参obj(函数实参和形参都指向同一个对象), obj.name="nick"; 执行完后形参和实参person所指的那个对象中的name属性被修改为nick,此操作会影响到全局的person,obj=new Object();执行完后形参指向一个新的堆内存地址,跟实参没有任何关系了,也就跟全局的person所指向的对象没有任何关系了,obj.name="greg";将形参所指的局部对象的name属性修改为greg,此操作对全局的person对象不会再有影响,形参所指向的对象在函数执行完被销毁.全局打印person.name为nick.