JAVA:javascript
传递基本类型是 就是基本的值传递 不会影响值自己。前端
package com.wuqi.p1; public class ValuePassTest { public static void main(String[] args) { int a = 1; //传递基本数据类型,由于是将a的值传递给param,因此即使在pass函数中改变了 //参数的值,a的值仍是不会变。因此咱们认为在传递基本数据类型的时候是值传递 pass(a); System.out.println("a= " + a); //1 不改变 } private static void pass(int param) { param = 2; System.out.println("param= " + param);//2 } }
传递引用类型String时:java
public class Hello { public static void changeInt(String str){ if (str == "blue") { str = "red"; } else{ str = "green"; } System.out.println(str); } public static void main(String[] args) { String str = "blue"; changeInt(str);//red System.out.println(str);//blue } }
能够看出str值在方法里为red,已经被修改。可是在main中依旧是没变 这说明方法里的str只是main中的一个复制或者副本。在change里面对str修改后本质上是改变了str的指针指向,指向了一个新的内存地址 ,但main中的str指向并未发生不改变前端工程师
package com.wuqi.p1; import com.wuqi.p2.User; public class PassTest2 { public static void main(String[] args) { User user = new User(); user.setName("wutianqi"); //传递对象,由于是将指向User的引用user传递给了param, //在函数中param.setName会反应到真实的对象中去。 pass(user); System.out.println("my name is " + user.getName()); } private static void pass(User param) { param.setName("wuqi"); System.out.println("my name is " + param.getName()); } }
然而上图传递对象后 name却发生了变化 缘由在此: 传递对象,由于是将指向User的引用user传递给了param,在函数中param.setName会反应到真实的对象中去函数
对于对象来讲传递的是引用的一个副本给参数,这一点要铭记!学习
所以 在java中所有都是值传递 ,不存在引用传递。 Java 语言的参数传递只有「按值传递」。当一个实例对象做为参数被传递到方法中时,参数的值就是该对象的引用的一个副本。指向同一个对象,对象的内容能够在被调用的方法内改变,但对象的引用(不是引用的副本) 是永远不会改变的。spa
JS:指针
JS的基本类型,是按值传递的。code
var a = 1; function foo(x) { x = 2; } foo(a); console.log(a); // 仍为1, 未受x = 2赋值所影响
而若是是对象的话:对象
var obj = {x : 1}; function foo(o) { o.x = 3; } foo(obj); console.log(obj.x); // 3, 被修改了!
var obj = {x : 1}; function foo(o) { o = 100; } foo(obj); console.log(obj.x); // 仍然是1, obj并未被修改成100.
能够看出,对象的值得传递并非按引用传递。其实,是按共享传递 call by sharing,准确的说,JS中的基本类型按值传递,对象类型按共享传递的(call by sharing,也叫按对象传递、按对象共享传递)。
该策略的重点是:调用函数传参时,函数接受对象实参引用的副本(既不是按值传递的对象副本,也不是按引用传递的隐式引用)。 它和按引用传递的不一样在于:在共享传递中对函数形参的赋值,不会影响实参的值。注意是函数形参总体 而不是函数形参的属性!!!
总之,基本类型是按值传递,而对于对象来讲传入的是对象指向的地址,也能够认为其是特殊的按值传递。若是在函数内对对象的属性进行操做,实际就是对其指向对象的属性进行操做。可是,若是对其总体进行操做(好比:o = 100或者o = []),其实际是新定于了对象,实参的引用地址为新的对象的引用地址,与原来的引用没有任何关系,因此不会对原来的对象形成改变。
最后 再解释一下按共享传递:
var foo = {name:'foo'}; function test(o){ o.name='test'; o={name:'bar'} } test(foo); console.log(foo); //打印结果为: Object {name: "test"}
从上面结果能够得出第一:对象不是按值传递的,若是是按值传递的话打印出来的foo的name属性的值不会为test,由于按值传递的话传递的是对象的一个副本,对副本的修改不会影响元对象,因此能够证实对象不是按值传递的!
也能够证实第二:js中对象也不是彻底按引用传递的,若是是按引用传递的话在执行o={name:'bar'}这行代码的时候,foo打印的结果应该是Obeject {name:'bar'}了,而结果确是Object {name:'test'},因此综上两点js引
用类型在做为参数传递时是按共享传递的,即传递是是原对象引用的一个副本,可是这个副本跟原对象的引用指向的都是内存中的对象!
之前学习中知道对于js中基础类型是按值传递的,引用类型是按引用传递(其实如今看来是按共享传递),而没有彻底理解透彻js中参数传递的方式,因此对js基础知识的理解是很是重要的,必定要掌握牢固,理解透彻,不然浅尝辄止只会让本身是个半桶水,
而成不了一个优秀的前端工程师!