js傳參是按值傳遞還是按引用傳遞?


  今天遇到個題目是有關js傳遞的,做對了一般,另一半錯了,這在做選擇題的時候那就是錯了,沒分的!所以大家如果基礎不扎實的話就很容易出錯,而且做題的時候心里沒底,模棱兩可,

所以還是要實時不斷去復習基礎知識,這樣才能成長更快!

  什么是按值傳遞?什么是按引用傳遞?

  按值傳遞(call by value)是最常用的求值策略:函數的形參是被調用時所傳實參的副本。修改形參的值並不會影響實參。
 
  按引用傳遞(call by reference)時,函數的形參接收實參的隱式引用,而不再是副本。這意味着函數形參的值如果被修改,實參也會被修改。同時兩者指向相同的值。

  按值傳遞由於每次都需要克隆副本,對一些復雜類型,性能較低;按引用傳遞會使函數調用的追蹤更加困難,有時也會引起一些微妙的BUG。

  探究JS值的傳遞方式

  JS的基本類型,是按值傳遞的,如下代碼可以證明:

1 var a = 1;
2 function foo(x) {
3     x = 2;
4 }
5 foo(a);
6 console.log(a); // 仍為1, 未受x = 2賦值所影響

  而對於引用類型來看如下代碼:

1 var obj = {x : 1};
2 function foo(o) {
3     o.x = 3;
4 }
5 foo(obj);
6 console.log(obj.x); // 3, 被修改了!

說明o跟obj指向的是同一個對象,所以不是按值傳遞的,但是這就能證明js中對象是按引用傳遞的嗎??少年們可以看如下這個例子:

1 var foo = {name:'foo'};
2 function test(o){
3    o = {name:'bar'};  
4 }
5 test(foo);
6 console.log(foo.name);

打印foo.name的值確還是'foo',這就說明js中對象的傳遞也不是不是按引用傳遞。好凌亂啊...那js中對象究竟是按什么傳遞呢?

  按共享傳遞 call by sharing

  嚴格的說,JS中的基本類型按值傳遞,對象類型按共享傳遞的(call by sharing,也叫按對象傳遞、按對象共享傳遞)。最早由Barbara Liskov. 在1974年的GLU語言中提出。該求值策略被用於Python、Java、Ruby、JS等多種語言。

該策略的重點是:調用函數傳參時,函數接受對象實參引用的副本(既不是按值傳遞的對象副本,也不是按引用傳遞的隱式引用)。 它和按引用傳遞的不同在於:在共享傳遞中對函數形參的賦值,不會影響實參的值。實質大家可以這么理解:

在調用函數傳遞引用類型的參數時,傳遞是是對象引用的副本,但是這個對象引用的副本跟原對象引用指向的是同一個地方(也就是該對象在內存中存放的地址),大家要認真理解這句話!!!!

  大家看如下這個例子就印證了按共享傳遞的觀點

1 var foo = {name:'foo'};
2 function test(o){
3   o.name='test';
4   o={name:'bar'}    
5 }
6 test(foo);
7 console.log(foo);
8 //打印結果為:
9 Object {name: "test"}

從上面結果可以得出第一:對象不是按值傳遞的,如果是按值傳遞的話打印出來的foo的name屬性的值不會為test,因為按值傳遞的話傳遞的是對象的一個副本,對副本的修改不會影響元對象,所以可以證明對象不是按值傳遞的!

也可以證明第二:js中對象也不是完全按引用傳遞的,如果是按引用傳遞的話在執行o={name:'bar'}這行代碼的時候,foo打印的結果應該是Obeject {name:'bar'}了,而結果確是Object {name:'test'},所以綜上兩點js引

用類型在作為參數傳遞時是按共享傳遞的,即傳遞是是原對象引用的一個副本,但是這個副本跟原對象的引用指向的都是內存中的對象!

  以前學習中知道對於js中基礎類型是按值傳遞的,引用類型是按引用傳遞,而沒有完全理解透徹js中參數傳遞的方式,所以對js基礎知識的理解是非常重要的,一定要掌握牢固,理解透徹,否則淺嘗輒止只會讓自己是個半桶水,

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM