在书本中大家都学到的参数传递有两种: 按值传递和按址传递, 下面我们就来说一下 JavaScript 中的传递
按值传递非常好理解, 就不说了, 我们说一下 JavaScript 中对象的传递
前两天做了一道前端面试题, 感觉比较有趣, 特分享一下
var setPerson = function(person){
person.name = "kevin";
person = {name:"rick"};
};
var person = {name:"alan"};
setPerson(person);
console.log(person.name);
//输出 kevin
我在做这道题时知道 person.name = 'kevin'
是可以改变外面 person
对象的值, 所以当时也认为 person = {name: 'rick'}
是可以改变的, 后来知道答案后感觉非常不可思议, 废了些功夫去理解一番
先来看个例子
var a = {
name: '小王'
}
var b = a;
b = null;
console.log(a);
//输出 {name:'小王'}
我们知道 JavaScript 中的对象是引用对象, 所以 a
中存储的是对象的内存地址, 而对象存储在堆中, var b = a;
实际是将 b
的值设置为 a
对象中存储的地址, 再将 b
设置为空对象 null
, 也是将 b
的值改为空对象的栈内存地址, 所以说 b
的改变影响不到 a
通过上面的分析, 我们再回到题中, 向 setPerson()
函数中传递了一个对象, 可以看作是用外面的 person
对象赋值给 setPerson()
中的 person
局部对象, setPerson()
中的 person
对象只是指向了外面 person
对象的地址, 当执行 person.name = "kevin"
时会根据对象地址访问对象, 然后修改 name
的值, 外面的person
也就改变了, 但当执行 person = {name:"rick"};
时, 是拿 setPerson()
中指向新的对象地址, 不会修改原来的对象
到此, 我们也就明白了对象的参数传递, 暂时没弄清这是按址传递还是按值传递, 也有人说是共享传递, 不过, 我们明白原理就好, 另外, Java 中也存在这种情况