Java中的變量傳遞機制以及JS中的參數傳遞機制

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基礎知識的理解是很是重要的,必定要掌握牢固,理解透徹,不然淺嘗輒止只會讓本身是個半桶水,

而成不了一個優秀的前端工程師!

相關文章
相關標籤/搜索