这几天遇到js参数传递方式的问题,深切探究一番,将所得结果总结于此segmentfault
在传值调用中实际参数被求值,其值被绑定到函数中对应的变量上(一般是把值复制到新内存区域)。在函数返回后调用者做用域里的曾传给函数的任何东西都不会变。
在“传引用调用”求值中,传递给函数的是它的 实际参数的隐式引用(即实际参数的地址)而不是实参的拷贝。一般函数可以修改这些参数(好比赋值),并且改变对于调用者是可见的。
在传共享对象调用中,传递给函数的是实参所指向引用对象的地址,而不是实参的地址,即传递共享对象。故在函数中修改引用对象时,实参的值也会跟着变化,而若是是从新给新参赋值后,再进行任何修改都不会影响到外面的实参了。
let a = 1; function add(val) { val += 1; console.log(`val=${val}`); // 2 } add(a); console.log(`a=${a}`); // 1
let a = 'hahaha'; function change(val) { val = 'heiheihei'; console.log(`val=${val}`); // heiheihei } change(a); console.log(`a=${a}`); // hahaha
let a = Symbol('prop'); function change(val) { val = Symbol(2); console.log(`val=${val.toString()}`); // Symbol(2) } change(a); console.log(`a=${a.toString()}`); // Symbol(prop)
let obj = { a: 1 } function change(obj) { obj.a = 2; console.log(obj); // {a: 2} obj = { a: 3 } console.log(obj); // {a: 3} } change(obj); console.log(obj); // {a: 2}
从上面的代码能够看出,在函数中对参数所指向的对象进行修改时会影响到外面的实参,但对函数参数从新赋值时,不会影响到实参,故js引用类型的传值方式为call by sharing函数
在C#
中类型有两种:值类型和引用类型,它们之间的却别在于实际数据存储的位置(如上图)。值类型的变量和实际数据都存储在堆栈中;而引用类型则只有变量存储在堆栈中,变量存储着实际数据的地址,实际数据存储在与地址相对应的托管堆中。学习
综上所述(证实题2333),值传递和引用传递的参数类型既能够是值类型又能够是引用类型,可是call by sharing的参数类型只能是引用类型。spa
我的理解:JS中,null赋值的变量时对象,可是,变量指向的引用地址为空,故在函数中修改参数的值,对实参不会又任何影响,因此是按值传递。string类型应该跟C#按值传递的缘由一致。
参考:
维基百科
JS中的值是按值传递,仍是按引用传递呢
《Learning hard C#学习笔记》第10章code