標籤:函數 關鍵點 共用 運算 傳遞方式 cti 分布 參數 UNC
在《JavaScript進階程式設計》第三版 4.1.3,講到傳遞參數:
ECMAscript中所有函數的參數都是按值傳遞
按值傳遞
也就是,把函數外部的值複製給函數內部的參數,就和把值從一個變數複製到另一個變數一樣
var value = 1;function foo(v) { v = 2; console.log(v); //2}foo(value);console.log(value) // 1
當傳遞value給函數foo的時候,相當於拷貝一份value給foo假設拷貝的那份叫v,函數中修改的都是v,不會一項原來的value值
引用傳遞
按值傳遞裡面的拷貝雖然好理解 但是當值是一個複雜的資料結構的時候,拷貝就會產生效能問題
所以還有另外的傳遞方式叫做按引用傳遞
所謂按引用傳遞,就是傳遞對象的引用,函數內部對參數的任何改變都會影響該對象的值,因為兩者引用的是同一個對象
var obj = { value : 1 }; let foo = (o)=> { o.value = 2; console.log(o.value); } foo(obj) console.log(obj.value);
這裡產生了一個疑問?
紅寶書都說了 ECMAScript 中所有函數的參數都是按值傳遞的,這怎麼能按"引用傳遞"成功呢?
我們看第三個例子
var obj = { value: 1};function foo(o) { o = 2; console.log(o); //2}foo(obj);console.log(obj.value) // 1
如果 JavaScript 採用的是引用傳遞,外層的值也會被修改呐,這怎麼又沒被改呢?所以真的不是引用傳遞嗎?
這就要講到其實還有第三種傳遞方式,叫按共用傳遞。
而共用傳遞是指,在傳遞對象的時候,傳遞對象的引用的副本。
關鍵點:
運算子=就是建立或修改變數在記憶體中的指向.
初始設定變數時為建立,重新賦值即為修改.
為瞭解釋上面的共用傳遞 這裡在看一個例子摸清楚記憶體中的分布
var a = {b: 1};// a = {b: 1}var c = a;// c = {b: 1}a = 2;// 重新賦值aconsole.log(c);// {b: 1}
- 建立變數a指向對象{b:1}
- 建立變數c指向對象{b:1}
- a又重新指向常量2
但是這時候c依舊指向對象{b:1}
這樣我們回頭看第一個例子
var value = 1;function foo() { var v = value; // 建立變數v指向value所指向的值 v = 2;// v重新指向另外的值 console.log(v); //2}foo(value);console.log(value) // 1,value從始至終都未改變指向.
現在吧第一個例子修改成對象
var a = {b: 1};// a = {b: 1}var c = a;// c = {b: 1}a.b = 2;// 重新賦值對象a中的屬性bconsole.log(c);// {b: 2}
執行完a.b = 2後:
a,c從始至終都沒有改變指向,變的是b而已
現在再看第二個例子
var obj = { value: 1};function foo() { var o = obj; o.value = 2;// 變數value改變了指向,而o並未改變 console.log(o.value); //2}foo(obj);console.log(obj.value) // 2
所以 js始終是按值傳遞,在這裡稱他為共用傳遞
JavaScript深入之參數按值傳遞