JavaScript中函数是按值传递还是按引用传递?
JavaScript中函数的参数传递:按值传递的本质
首先明确结论:在JavaScript里,所有参数传递都是按值传递,函数也不例外。咱们来拆解你给出的两个例子,就能明白背后的逻辑了。
第一个例子:重新赋值形参不影响外部函数
先看你写的这段代码:
function sayHello() { console.log("Hello") } function changeSayHello(func) { func = function() { console.log("Good Bye"); } func(); } sayHello(); // >> Hello changeSayHello(sayHello); // >> Good Bye sayHello(); // >> Hello
当你把sayHello作为参数传给changeSayHello时,传递的是函数引用的副本。在changeSayHello里,你把func重新赋值成了一个新函数——这只是修改了这个局部的引用副本,完全不会影响外部原来的sayHello引用。所以外部调用sayHello()还是输出"Hello",这完全符合按值传递的特征:参数传递的是值的副本,修改副本不影响原值。
第二个例子:修改函数对象的属性会生效
再看你补充的这个例子:
var Obj = function() { this.a = 5; } var change = function(func) { func.prototype.b = 8; } var first = new Obj(); console.log(first.b); //undefined change(Obj); console.log(first.b);// 8
这里容易让人误以为是按引用传递,但本质还是按值传递。你传递给change的是Obj函数引用的副本,这个副本和原Obj引用指向同一个函数对象。所以当你通过这个副本修改函数对象的prototype属性时,其实是在修改同一个对象的内容——这就像你传递一个普通对象给函数,修改对象的属性会影响外部对象,但这不是按引用传递,只是因为引用的副本指向了同一个对象。如果在change里尝试把func重新赋值成一个新函数,外部的Obj依然不会被改变,这和第一个例子的逻辑一致。
总结一下
JavaScript里没有真正的按引用传递,所有参数都是按值传递:
- 对于原始值,传递的是值的副本;
- 对于对象(包括函数),传递的是对象引用的副本——你可以通过这个副本修改对象内部的属性,但无法通过重新赋值形参来改变外部的原引用。
内容的提问来源于stack exchange,提问作者Hairi
相关产品推荐
相关产品推荐

