JS中函数参数值传递和引用传递
写作意图:写这篇文章,我觉得呢,以前对Java中的值传递和引用传递可能有些缺漏,感觉有点乱糟糟的感觉,东一片知识,西一片知识,直到遇到了一个js的面试题:
var a={a:1,b:2};
var b=a.a;
var c=a;
c.a=3;
b++;
console.log(a.a);
console.log(b);
看到上面的代码,你的答案是什么呢,答案是3,2。
看到这个答案的时候,我是有点疑惑的,对象是引用类型,引用类型是将引用的对象指向一块内存,可是,改变了一个对象里面的值,为啥另外一个对象的值也改变了,难道不是两个对象分别指向两块不同的内存嘛。
带着上面的疑惑,我去问了一下,我师父,他是这么说的,对象只有new了以后,才会另外指向一块内存,好,就是这句话,ok所有疑惑都完美解决了。
代码如下:
var person=new Object();
var obj = person; // 赋值
obj.name="ABC";
obj=new Object();
obj.name="BCD";
console.log(person.name);// ABC 并没有影响person的指向
然后我又有疑惑,所有的引用类型都是“赋值”的时候,都是直接指向一块地址而不是赋值嘛,也许这句话存在语法错误,以后有更好的理解,再来指正。
这个时候我就想到了Java中的String类型,是一个引用类型,不是基本类型,那么就不是赋值了咯,之前听说,String类型是不可变类型。这边先提出疑惑,下篇文章得整理一些Java得基本类型和引用类型,以及String类型,这个有点特殊得东西。
然后我就去针对这个String写了一段代码:
public class test{
String str = new String("hello");
char[] ch = {'a', 'b'};
public static void main(String[] args) {
test ex = new test();
ex.change(ex.str, ex.ch);
System.out.println(ex.str + " and");
System.out.println(ex.ch);
}
public void change(String str, char[] ch) {
str = "ok";
ch[0] = 'c';
}
}
上面是Java的代码,java的值传递和引用传递,我感觉这篇文章,讲的是引用传递,没有讲到值传递,(String, Integer, Double等immutable的类型特殊处理,可以理解为传值,最后的操作不会修改实参对象。)这句话算是对哪个String类型的解释,看到这里,我感觉我还是有点花非花雾非雾。
这里不说Java了,打算另外开一篇文章写,现在继续回到js中。
继续说js的值传递和引用传递,这里我还看到了一个文章,感觉解释的也挺到位。js值传递和引用传递
这里张贴两部分代码:
function setName(obj) {
obj.name = "Nicholas";
obj = new Object(); //改变obj的指向,此时obj指向一个新的内存地址,不再和person指向同一个
obj.name = "Greg";
}
var person = new Object();
setName(person); //你看看下面,相信我也是按值传递的了吧
alert(person.name); //"Nicholas"
上面得代码我其实是这么理解的,再哪个setName(obj)这个函数中,将person对象传递过来了,这个里面我觉得是进行了这样的操作:
1.obj=person;
2.obj.name="Nicholas"
所以person最后得name值是Nicholas,因为第一步操作,obj这个对象已经和person指向同一块内存了,obj对内存里面得值进行了修改,那么person也同步到了修改。就好比是用编辑器打开d盘一个文件,编辑器上面修改完毕以后保存,d盘得那个文件也进行了改变。
这里还有一个用堆和栈进行解释得:堆和栈之js数据类型
这里我就不写了,因为下一篇文章准备把Java中得堆和栈写一下,感觉上面那个链接中js讲的堆和栈没有Java那么细,但是说的也是对的。
JS分两种数据类型:
- 基本数据类型:Number、String、Boolean、Null、Undefined、Symbol(ES6),这些类型可以直接操作保存在变量中的实际值。
- 引用数据类型:Object(在JS中除了基本数据类型以外的都是对象,数据是对象,函数是对象,正则表达式是对象)