[ JavaScript 06 ] function 傳參數的運作機制


Posted by tzutzu858 on 2020-06-23

一篇我需要好好消化的筆記文章,後面會提到一點點 Java 和 JavaScript 底層的東西


先上例子

function swap(a,b){
      var temp = a 
      a = b
      b = temp
      console.log('a,b=',a,b)
}
var number1 = 10
var number2 = 20
console.log('1',number1,number2)

swap(number1,number2)

console.log('2',number1,number2)
  • 解說function swap裡面發生的事,為何console.log('2',number1,number2)的值不會改變 :
    var a = number1
    var b = number2
    a 和 b 是複製來的
    它的記憶體跟 number1,number2 的位置是不一樣
    傳進去後,a 和 b 的確變了,但不會影響到外面 number1,number2 的值
    值(value)一樣,但是完全兩個不一樣的變數

value 改變的例子
有人把這種方式叫做 call by sharing,但其實是 pass by value 的分支
後面深入探討文章裡有講到

function addValue(obj){
   obj.number++
   return 1
}

var a = {
  number:10
}

addValue(a)
console.log(a)
{number: 11}

a 印出來是 11 而不是 10

  • 不會改變 (主要的原始資料類型)
    數字(Number)
    字串(String)
    布林(Boolean)

  • 會改變 (複合型(composite)或參考型(reference)的資料類型)
    陣列(Array)
    物件(Object)

補充說明 :
所謂的"原始資料類型",指的是在程式語言中,最低階的一種資料類型,不屬於物件也沒有方法。它也具有不可改變的 ( immutable ) 特性。不過, JavaScript 語言中也存在名稱為 String、Number、Boolean 的物件,用來對應原始資料類型,它們是一種包裝物件 ( wrapper object ) ,提供了原始資料類型可以使用的一些延申的屬性與方法。
註: JavaScript 的確是一個物件導向的程式語言。不過, JavaScript 中的物件導向特性與其他目前所流行的物件導向語言例如 Java 、 C++ 等有很大的不同。參考文章

value 又不會改變的例子 我跳出去,我又跳進來 (~ ̄▽ ̄)~~ .... ~( ̄▽ ̄~)

function addValue(obj){
   obj={
   number : 100
   }
   return 1
}

var a = {
  number:10
}

addValue(a)
console.log(a)
{number: 10}

value 改變的例子說明:
兩者都是指向同一個物件(Object),因此裡面改變值,就是兩個都一起改到。
因此印出 a 會是 11 而不是 10

value 不會改變的例子說明:
等號後面給它一個新的物件(Object),那它就會指向一個新的記憶體
而不會改到原本那個物件(Object)
因此 console.log(a) 會是 10

複習 [ JavaScript 02 ] 變數,看裡面的 == 與 ===
a 是物件(Object),要小心寫的時候,裡面多打什麼就會什麼印出來

function addValue(obj){
   obj.test=1
   return 1
}

var a = {
  number:10
}

addValue(a)
console.log(a)
{number: 10, test: 1}

三種不同形式

  • pass by value
  • pass by reference
  • pass by sharing

在 JavaScript 裡只有 pass by value 和 pass by sharing
pass by sharing 屬於在 pass by value 底下
中間有點錯綜複雜 (๑ↀᆺↀ๑)✧
深入參考文 :
深入探討 JavaScript 中的參數傳遞:call by value 還是 reference?
裡面文章提起以前卡住的東西,Java 到底是 pass-by-value(傳值)還是 pass-by-reference(傳址/傳參考),結果......已經有共識啦~以前查了老半天,還是沒有一個答案。複習 Java 時間到啦。

以前在寫 Java 的時候也有碰過這個問題,而且跟 JavaScript 的其實一模一樣,就是你傳一般的值進去是 by value,可是你傳 object 進去的時候又表現的像 call by reference,但是賦值的時候又不會改變外面的 object。
但看起來 Java 永遠都是 pass by value 已經是個共識了,可參考 Is Java “pass-by-reference” or “pass-by-value”?Java is Pass-by-Value, Dammit!

引用文章裡面的引用 Call by value?

Java 中 Call by value,指的是傳遞參數時,一律傳遞變數所儲存的值,無論是基本型態或是類別宣告的型態都一樣,Java 中不允許處理記憶體位址,所以用了「參考」這個名稱來作為解釋類別型態所宣告的變數之行為,但這邊的「參考」與 C++ 中所稱之「參考」,是完全不相同的行為,更不會有 C++ 中參數的傳值、傳參考、return 的傳值、傳參考的 Call by reference 行為。

又是引用再引用 技術名詞紛爭多

程式開發的世界中,名詞的創造經常是隨意的,曾經在 Java 中爭執不斷的考古題之一是:「Java 中有沒有 Pass by reference」,就現今來說,大家公認的答案是沒有,Java 只有 Pass by value,不過還是有人面對 Java 文件中經常出現 reference,而搞不清楚。

說穿了,這個名詞與 C++ 中的 reference 定義不同,只不過 Java 最初不知道為什麼,也用了 reference 一詞,重點也不在搞清楚 Pass by value,重點是搞清楚透過參數操作物件時,會有什麼樣的行為。

複習 Java 時間結束。

搞清楚到底參數在操作的時候會有怎樣的行為。你要知道 JavaScript 傳 object 進去的時候,可以更改原本物件的值,但重新賦值並不會影響到外部的 object。只要知道這一點,其他的我覺得都沒那麼重要了。

恩恩......so嘎 (手托下巴
結束這頭昏眼花的一篇文章。

    


#javascript







Related Posts

React hook form(4) - useFormContext & useFormState & useWatch

React hook form(4) - useFormContext & useFormState & useWatch

AI輔導室|配出延伸系列色

AI輔導室|配出延伸系列色

CS50 TCP (Transmission Control Protocol)

CS50 TCP (Transmission Control Protocol)


Comments