js變量傳給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());

}

}

e67afc43a868d7af8e3006fda786401d.png

然而上圖傳遞對象後 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基礎知識的理解是非常重要的,一定要掌握牢固,理解透徹,否則淺嘗輒止只會讓自己是個半桶水,

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