(第2讲)javascript中的参数传递和java中的参数传递

 1、javascript中的参数传递:值传递

(1)在js函数传递中,当基本类型(number, string, boolean, null, undefined, symbol)变量作为参数传递时,函数内部对参数的任何操作都不会改变变量的值。 

(2)当object类型变量作为参数传递时,函数内部对参数的操作会影响变量的值,除非函数内部对参数重新赋值(任何类型的值)。   


<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta  charset="utf-8"/>
</head>
<body>
    <p>welcome </p>
    <script language="JavaScript">
        var obj = {};
        obj.inner = 10;
        var num = 10;
        var str = 'Hello';
        var boo = true;
        var oth = null;
        var und = undefined;
        var sym = Symbol('foo');
        function passingobject(myobj){
            myobj.inner = 1+myobj.inner;
        }
        function passingvalue(myValue){
            switch (typeof myValue){
                case 'number':
                    myValue = myValue+1;
                    break;
                case 'string':
                    myValue = 'I am a new string now!';
                    break;
                case 'boolean':
                    myValue = false;
                    break;
                default :
                case 'number':
                    myValue = 'Null,Undefined,or Symbol';
            }
        }
        console.log("before num"+num);//10
        passingvalue(num);
        console.log("after num"+num);//10
        console.log("before str = " + str); // before str = Hello  
        passingvalue(str); 
        console.log("after str = " + str);  // after str = Hello   
        console.log("before boo = " + boo); // before boo = true   
         passingvalue(boo); 
        console.log("after boo = " + boo);  // after boo = true   
         console.log("before oth = " + oth); // before oth = null   
          passingvalue(oth); 
        console.log("after oth = " + oth);  // after oth = null   
         console.log("before und = " + und); // before und = undefined   
          passingvalue(und); 
        console.log("after und = " + und);  // after und = undefined   
         console.log(sym); // Symbol(foo)   
          passingvalue(sym);
        console.log(sym); // Symbol(foo) 
        console.log("before obj.inner = " + obj.inner); //www.baiyuewang.net before obj.inner = 10 
        passingobject(obj); // after obj.inner = 11   
         console.log("after obj.inner = " + obj.inner);
        function changeStuff(a, b, c) 
         {
              a = a * 10;
              b.item = "changed";  
              c = {item: "changed"};  
          } 
        var num = 10;
        var obj1 = {item: "unchanged"}; 
         var obj2 = {item: "unchanged"};
        console.log(obj1.item);//unchanged  
        console.log(obj2.item); // unchanged 
        console.log(num);//10
        changeStuff(num, obj1, obj2);
        console.log(num);//10
         console.log(obj1.item); // changed 
         console.log(obj2.item); // unchanged
    </script>
</body>
</html>

2、java中的参数传递:值传递

(1)对于基本类型变量作为参数传递时,java是传递值的副本,函数内部对参数的任何操作都不会改变变量的值。 

(2)对于一切对象型变量,java都是传递引用的副本,函数内部对参数的操作会影响变量的值,除非函数内部对参数重新赋值(任何类型的值)。  要注意String类型,因为属于final类型,所以总是不会被影响

package com.shenzhoufu;
import java.util.*;
public class Reference {
public static void main(String[] args){
//————————boolean——————————————————————————————
boolean b = true;
System.out.println("unchanged:"+b);//true
testBoo(b);//false
System.out.println("changed:"+b);//true
//————————String——————————————————————————————
String str = ",world!";
System.out.println("unchanged:"+str);//,world!
testString(str);//Hello
System.out.println("changed:"+str);//,world!
//————————————StringBuffer——————————————————————
StringBuffer strb = new StringBuffer(",world!");
System.out.println("unchanged:"+strb);//,world!
testStringBuffer(strb);//,world!hello
System.out.println("changed:"+strb);//,world!hello
}
//基本类型
public static void testBoo(boolean b){
b = !b;
System.out.println("changing(in test):"+b);
}
//String类型
public static void testString(String s){
String string = "Hello";
System.out.println("newString:"+string);
}
//StringBuffer 对象
public static void testStringBuffer(StringBuffer s){
s.append("hello");
System.out.println("changing(in test)StringBuffer:"+s);
}
}

1、对象是按引用传递的
2、Java 应用程序有且仅有的一种参数传递机制,即按值传递
3、按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本
4、按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本

class Test01
  {
  public static void main(String[] args)
  {
  StringBuffer s= new StringBuffer("good");
  StringBuffer s2=s;
  s2.append(" afternoon.");
  System.out.println(s);
  }
  }
  对象s和s2指向的是内存中的同一个地址因此指向的也是同一个对象。
  如何解释“对象是按引用传递的”的呢?
  这里的意思是进行对象赋值操作是传递的是对象的引用,因此对象是按引用传递的,有问题吗?
  程序运行的输出是:
  good afternoon.
  这说明s2和s是同一个对象。
  这里有一点要澄清的是,这里的传对象其实也是传值,因为对象就是一个指针,这个赋值是指针之间的赋值,因此在java中就将它说成了传引用。(引用是什么?不就是地址吗?地址是什么,不过就是一个整数值)

     class Test2
  {
  public static void main(String[] args)
  {   StringBuffer s= new StringBuffer("good");
StringBuffer s2=new StringBuffer("bad"); 
test(s,s2);
System.out.println(s);// goodhah
System.out.println(s2);//bad为什么呢????有大神能解释么

  }
public static void test(StringBuffer s,StringBuffer s2) {
System.out.println(s);//good
System.out.println(s2);//bad
s2=s; 
s=new StringBuffer("new"); 
System.out.println(s);//new
System.out.println(s2);//good
s.append("hah"); 
s2.append("hah"); 
System.out.println(s);//newhah
System.out.println(s2);//goodhah
}

}

——————————————————————————————————————————————————

不同的操作系统不太一样,但一般内存都分为4个区域:

1)heap(堆):存放new出来的对象

2)stack(栈):存放局部变量

3)data segment(数据区):静态变量 和 字符串常量

4)code segment(代码区):存放代码 

Java中进行方法调用的时候传递参数时,遵循值传递的原则:

1)基本数据类型,传递的是数据的拷贝

2)引用数据类型,传递的是传递的引用地址的拷贝,而不是该对象本身

例子:public class Test {

     void f(int j) {

           System.out.println(j);

     }

    void ff(String ss) {

           System.out.println(ss);

    }

    public static void main(Stirng[] args) {

             int i = 100;

             String s = "hello";

            Test t = new Test();

             t.f(i);

             t.ff(s);

        }

}

内存中的执行过程:

当mian方法开始执行的时候  

(1)int i = 100;  栈中分配一块空间,存放变量i,值为100,基本数据类型只占一块空间;

(2)String s = "hello"; "hello"是字符串常量,分配在data区,字符串常量为String类的一个对象,s指向了这个"hello"对象,这就是引用数据类型,在内存中占两块空间;有点形象思维:一提引用类型,就是一块内存指向另一块内存s可以被叫做:引用、引用变量、引用地址,其实s就是一个指针,在这里不用钻牛角尖,你就知道s是一个引用,s的值是一个地址,根据这个地址就可以找到一个对象就ok了

(3)Test t = new Test(); 同理,栈中的引用t指向了堆中new出来的这个Test对象;

(4)t.f(i);  方法的形参属于局部变量,所以在调用f方法的时候,栈内存分配一个int型的变量j,将i的值当做实参传递过去,i的值是100,现在将100拷贝给了j,那么j的值就是100,这就是楼主说的“值传递”,接着打印,最后方法结束,为该方法分配的局部变量立刻全部清空,那么Stack中这个j消失了;

(5)t.ff(s);  调用ff方法的时候,栈内存分配一个String型的变量ss,将s的值当做实参传递过去,s指向了"hello"对象,s的值是一个地址,现在将这个地址拷贝给了ss,那么ss也就指向这个"hello"了这就是楼主说的"引用传递",现在s 和 ss 两个引用 同时指向了"hello"对象,然后打印ss,最后方法结束,栈中这个ss被清除;

现在main方法执行结束,为main方法分类的局部变量清除,i,s,t全部消失,data区的符串常量"hello"和堆内存的Test对象,由于没有任何引用指向他们了,就会被垃圾收集器回收

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值