JavaScript 按值傳遞 按引用傳遞

2021-09-06 22:19:20 字數 2306 閱讀 2025

(1)值的比較--引用的比較

首先,原始值的比較是值的比較:只有在它們值相等的時候它們才相等

比如簡單的

var a1 = 10;

var a2 = 10;

console.log(a1 === a2); //

true

其次,物件的比較並非值的比較:物件的比較均是引用的比較,當且僅當它們引用同乙個基物件時,它們才相等。

即使兩個物件包含同樣的屬性和相同的值,它們也是不相等的。各個索引元素完全相等的兩個陣列也不相等

比如

var o = ,p=;

console.log(o === p); //

false 兩個單獨的物件不相等

var a = ['you'],b = ['you'];

console.log(a === b); //

false 兩個單獨的陣列不相等

var a =;

var b = a; //

b 引用了同乙個陣列a

b[0] = "you";

console.log(a[0]); //

you 這是a也會修改

console.log(a === b); //

true

所以,如果我們要得到乙個物件或者陣列的副本,或者是要比較兩個單獨物件或陣列相等情況,就要比較它們的屬性元素等,通過迴圈遍歷陣列來實現

(2)按值傳遞 -- 按引用傳遞

按值傳遞(call by value)是最常用的求值策略:函式的形參是被呼叫時所傳實參的副本。修改形參的值並不會影響實參。

按引用傳遞(call by reference)時,函式的形參接收實參的隱式引用,而不再是副本。這意味著函式形參的值如果被修改,實參也會被修改。同時兩者指向相同的值

1. js的基本型別是按值傳遞的

比如

var a = 1;

function

foo(a)

foo(a);

console.log(a);

//仍為1, 未受a = 2賦值所影響

2.但是物件或者陣列之類呢?先看個例子

比如

var obj = ;

function

foo(o)

foo(obj);

console.log(obj.x);

//3, 也被修改了!

說明o和obj是同乙個物件,o不是obj的副本。所以不是按值傳遞。 但這樣是否說明js的物件是按引用傳遞的呢?我們再看下面的例子:

比如

var obj = ;

function

foo(o)

foo(obj);

console.log(obj.x);

//仍然是1, obj並未被修改為100.

如果是按引用傳遞,修改形參o的值,應該影響到實參才對。但這裡修改o的值並未影響obj。

因此js中的物件並不是按引用傳遞。那麼究竟物件的值在js中如何傳遞的呢?

按共享傳遞 call by sharing

準確的說,js中的基本型別按值傳遞,物件型別按共享傳遞的(call by sharing,也叫按物件傳遞、按物件共享傳遞)

該策略的重點是:呼叫函式傳參時,函式接受物件實參引用的副本(既不是按值傳遞的物件副本,也不是按引用傳遞的隱式引用)。

它和按引用傳遞的不同在於:在共享傳遞中對函式形參的賦值,不會影響實參的值。如上面例子中,不可以通過修改形參o的值,來修改obj的值。

然而,雖然引用是副本,引用的物件是相同的。它們共享相同的物件,所以修改形參物件的屬性值o.x=3,也會影響到實參的屬性值。

另外乙個例子

var obj = ;

obj.x = 100;

var o =obj;

o.x = 1;

obj.x;

//1, 被修改

o = true

;obj.x;

//1, 不會因o = true改變

對於物件型別,由於物件是可變(mutable)的,修改物件本身會影響到共享這個物件的引用和引用副本。

而對於基本型別,由於它們都是不可變的(immutable),按共享傳遞與按值傳遞(call by value)沒有任何區別,所以說js基本型別既符合按值傳遞,也符合按共享傳遞。

按值傳遞和按引用傳遞

對於基本型別而言,是按值傳遞的 基本型別儲存在棧中 基本型別引數的傳遞和基本型別的複製一樣,傳遞的是值本身 var a 1 function test x test a console.log a 1按值傳遞的意思就是形參是實參的複製,形參實參互不干擾 so,雖然在函式test中a被修改,但是並沒有...

按值傳遞 vs 按指標傳遞

變數賦值有兩種方式 按值傳遞 按 指標 傳遞 指標也常稱為 引用 不同的程式語言賦值的方式不一樣,例如python是按 指標 傳遞的,go是按值傳遞的。注意,指標 加了引號,因為它不是真正的按指標拷貝,見下文分析。引數傳值其實也是變數賦值的過程,只不過引數是函式的本地變數而已。按值傳遞的意思是每次賦...

scala 引數傳遞 按值傳遞 按名傳遞

package leetcode import scala.util.random object function args def getrandom call by name 按名傳遞,傳入引數變數名,如果runbyname內部用到,再去求值 f string int long表示 該無參函式的...