Call by sharing

變數 與 變數的值 的存放方式

變數 v.s 變數的值

1
2
3
const a = 100;
// a -> 變數
// 100 -> 變數的值

存放方式

  • 變數的存在某個記憶體位址, 變數則存該記憶體的位址
1
2
3
const a = 123 ;
const foo = function(){ ... } ;
const obj = { ... } ;

In memory :

1
2
3
4
5
6
0x01 : 123 
0x02 : function() { ... }
0x03 : { ... }
0x04 : 0x01 ( 變數 a , 內容為'123'的addr. )
0x05 : 0x02 ( 變數 foo )
0x06 : 0x03 ( 變數 obj )

更動變數的值

  • 更動變數的值, 會直接將值放在新的記憶體位址, 接著讓變數去指向新的值的記憶體位址
1
2
3
4
5
6
7
8
9
10
11
const func = (str, fobj) => {
str = '123';
fobj = { a: 123 };
};

let s = '456';
let obj = { a: 456 };
func(s, obj);

console.log(s); // '456'
console.log(obj); // { a: 456 }

In memory :

  • Initial

    1
    2
    3
    4
    5
    6
    0x01 : '456' 
    0x02 : { a: 456 }
    0x03 : function() { ... }
    0x04 : 0x01 ( 變數 s )
    0x05 : 0x02 ( 變數 obj )
    0x06 : 0x03 ( 變數 func )
  • When calling function - func(s, obj)

    • Function 的參數變數: (str, fobj) 分別與 s, obj 指向同一個址
      1
      2
      3
      4
      5
      6
      7
      8
      0x01 : '456' 
      0x02 : { a: 456 }
      0x03 : function() { ... }
      0x04 : 0x01 ( 變數 s )
      0x05 : 0x02 ( 變數 obj )
      0x06 : 0x03 ( 變數 func )
      0x07 : 0x01 ( 變數 str -> param in func.)
      0x08 : 0x02 ( 變數 fobj -> param in func.)
  • In function - str = ‘123’; fobj = { a: 123 };

    • 在 function 內直接 re-assign str, fobj, 會建立一個新的值存在新的址, 接著更新 str, fobj 所指向的位址, 但不影響外層 s, obj 所指向的位址
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      0x01 : '456' 
      0x02 : { a: 456 }
      0x03 : function() { ... }
      0x04 : 0x01 ( 變數 s )
      0x05 : 0x02 ( 變數 obj )
      0x06 : 0x03 ( 變數 func )
      0x07 : 0x09 ( 變數 str -> param in func.) --- 變成指向 0x09
      0x08 : 0x0A ( 變數 fobj -> param in func.) --- 變成指向 0x0A
      0x09 : '123'
      0x0A : { a: 123 }

變數的值是 Object, 更動該 Object 的 property

會直接 mutate 該變數值(Object)的 property

1
2
3
4
5
6
7
8
const func = (fobj) => {
fobj.a = 123;
};

let obj = { a: 456 };
func(obj);

console.log(obj); // { a: 123 }

In memory :

  • Initial

    1
    2
    3
    4
    0x01 : { a: 456 }
    0x02 : function() { ... }
    0x03 : 0x01 ( 變數 obj )
    0x04 : 0x02 ( 變數 func )
  • When calling function - func(obj)

    • Function 的參數變數: (fobj) 與 obj 指向同一個址
1
2
3
4
5
0x01 : { a: 456 }
0x02 : function() { ... }
0x03 : 0x01 ( 變數 obj )
0x04 : 0x02 ( 變數 func )
0x05 : 0x01 ( 變數 fobj -> param in func.)
  • In function - fobj.a = 123;
    • 會直接到 fobj 指向的位址去更動他的 property
      1
      2
      3
      4
      5
      0x01 : { a: 123 }  --- mutated !
      0x02 : function() { ... }
      0x03 : 0x01 ( 變數 obj )
      0x04 : 0x02 ( 變數 func )
      0x05 : 0x01 ( 變數 fobj -> param in func.)

參考文獻