JS基础 按共享传递 Call-by-sharing

来源:互联网 发布:对上知教育的评价 编辑:程序博客网 时间:2024/06/06 09:12

这是类似 Java基础 按数值传递 而写的一篇博文

总论

JavaScript的话,原始型是按数值传递的;对象类型是跟Java一样,拷贝了原来对象的一份引用,对这个引用进行操作。Stack Overflow上的Community Wiki提供的答案将这种对 对象类型的传递机制 称呼为 call-by-sharing. Is JavaScript a pass-by-reference or pass-by-value language?
顺带讲下,JS中,string就是一种原始型而不是对象类型了,参看这里

代码

var _ = require('underscore');/* JS is weak typed so there is no strong typed keyword like int, String, etc. */let setNewInt = function (i) {    i = i + 33;};let setNewString = function (str) {    str += "cool!";};let setNewArray = function (arr1) {    var b = [1, 2];    arr1 = b;};let setNewArrayElement = function (arr2) {    arr2[0] = 105;};let i = -33;let str = "I am ";let arr1 = [-4, -3];let arr2 = [-19, 84];console.log('i is: ' + i + ', str is: ' + str + ', arr1 is: ' + arr1 + ', arr2 is: ' + arr2);/* call those setter functions */setNewInt(i);setNewString(str);setNewArray(arr1);setNewArrayElement(arr2);console.log('Now, i is: ' + i + ', str is: ' + str + ', arr1 is: ' + arr1 + ', arr2 is: ' + arr2);

运行结果

i is: -33, str is: I am , arr1 is: -4,-3, arr2 is: -19,84Now, i is: -33, str is: I am , arr1 is: -4,-3, arr2 is: 105,84

这个运行结果和 博文 Java基础 按数值传递一致,背后的原因参看这篇博文即可。

按共享传递

总的来讲Stack Overflow上Community Wiki的解答,用中文来讲就是,对于传递到函数参数的对象类型,如果直接改变了拷贝的引用,那是不会影响到原来的那个对象;如果是通过拷贝的引用,去进行内部的值的操作,那么就会改变到原来的对象的。
上述的arr2就是个例子,这里再举一个不是数组型的对象类型的例子,参考自博文 JavaScript Fundamentals (2) – Is JS call-by-value or call-by-reference?
代码示例:

function changeStuff(state1, state2){  state1.item = 'changed';  state2 = {item: "changed"};}var obj1 = {item: "unchanged"};var obj2 = {item: "unchanged"};changeStuff(obj1, obj2);console.log(obj1.item);  // obj1.item becomes 'changed'  console.log(obj2.item);  // obj2.item is still 'unchanged'

缘由: 上述的 state1 相当于 obj1’, 然后 obj1’.item = 对原对象 obj1 内部的 item 属性进行了改变,自然就影响到原对象 obj1 啦。类似的,妳看 state2 有对原对象 obj2 内部的属性进行改变吗?没有嘛,只是 state2 它自己指向了一个新对象 {item: “unchanged”} . 所以,obj2 无变化。
对于此现象,stackoverflow community wiki给的答案说的是技术上更为严谨的说法,叫做 call-by sharing, 我给翻成中文叫 “按共享传递” ,但请注意: 我不确定这就是业界通用的翻译。
如有兴趣更多阅读 call-by-sharing, 这里是它的维基百科定义。
欢迎点评此博文,提出您的宝贵意见。