zoukankan      html  css  js  c++  java
  • Java中的变量传递机制以及JS中的参数传递机制

    JAVA:

    传递基本类型是 就是基本的值传递 不会影响值本身。

    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时:

    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 语言的参数传递只有「按值传递」。当一个实例对象作为参数被传递到方法中时,参数的值就是该对象的引用的一个副本。指向同一个对象,对象的内容可以在被调用的方法内改变,但对象的引用(不是引用的副本) 是永远不会改变的。

    JS:

    JS的基本类型,是按值传递的。

    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基础知识的理解是非常重要的,一定要掌握牢固,理解透彻,否则浅尝辄止只会让自己是个半桶水,

    而成不了一个优秀的前端工程师!

  • 相关阅读:
    java之redis篇(spring-data-redis整合) (转)
    web.xml
    点击类名方法名如何连接到相应的Android源代码
    eclipse能够自动提示变量名.
    Android自定义ActionBar
    Android 自定义View
    android 自定义titlebar
    Android SharedPreferences登录记住密码
    Android 正则表达式验证手机和邮箱格式是否正确
    Android 首次进入应用时加载引导界面
  • 原文地址:https://www.cnblogs.com/ttty/p/10430807.html
Copyright © 2011-2022 走看看