深入學習js系列是自己階段性成長的見證,希望通過文章的形式更加嚴謹、客觀地梳理js的相關知識,也希望能夠幫助更多的前端開發的朋友解決問題,期待我們的共同進步。
如果覺得本系列不錯,歡迎點贊、評論、轉發,您的支援就是我堅持的最大動力。
定義:
在《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,假設拷貝的這份叫做 _value
,函式中修改的
都是_value
的值,而不會影響到原來的 value 值。
上述程式碼中 在執行 foo 函式的時候傳遞的是 全域性的變數 value 當這個 value 被當做實參傳遞時候,在內部重新賦值變成了 2 因此在函式內部列印的就是 2,接下來 在函式執行完畢之後 再次列印全域性變數 value 的值還是 1,說明在函式內部修改的 value 值並沒有對全域性的 value 造成影響。
引用傳遞?
拷貝雖然很好理解,但是當值是一個複雜的資料結構的時候,拷貝就會產生效能上的問題。所以還有另外一種傳遞資料的方式叫做引用傳遞。
所謂按照引用傳遞,就是傳遞物件的引用,函式內部對引數的任何改變都會影響該物件的值,因為兩者引用的 是用一個物件。
舉個例子:
var obj = {
value: 1
};
function foo(o) {
o.value = 2;
console.log(o.value); // 2
}
foo(obj);
console.log(obj.value); // 2
複製程式碼
嗯哼,我們的紅包書中明明已經說了啊,js 中的所有函式的引數都是按照值進行傳遞的,這怎麼能按照"引用傳遞"成功 了呢?
那這究竟是不是按照引用傳遞呢?
第三種傳遞方式
不著急,讓我們在看個例子:
var obj = {
value: 1
};
function foo(o){
o = 2;
console.log(o); // 2
}
foo(obj);
console.log(obj.value);// 1
複製程式碼
如果js 是按照引用傳遞在上述程式碼中 外層的值也會被修改啊,這怎麼在最後列印的時候又沒有進行修改呢?
所以這裡要講的還有第三種傳遞方式——共享傳遞。
而共享傳遞是指,在傳遞物件的時候,傳遞物件引用的副本。
注意:按引用傳遞是傳遞物件的引用,而按共享傳遞是傳遞物件的引用的副本!
所以修改了o.value 可以通過引用找到原值,但是直接修改 o 並不會修改原值,所以第二個和第三個 例子其實都是共享傳遞。
最後,你可以這樣理解:
引數如果是基本型別是按照值傳遞,如果是引用型別按共享傳遞。 但是因為拷貝副本也是一種值的拷貝,所以在高程中也是直接認為是按照值傳遞了。
##參考:
深入學習JavaScript系列目錄
- #1 【深入學習js之——原型和原型鏈】
- #2 【深入學習js之——詞法作用域和動態作用域】
- #3 【深入學習js之——執行山下文棧】
- #4 【深入學習js之——變數物件】
- #5 【深入學習js之——作用域鏈】
- #6 【深入學習js之——實際開發場景中的this指向】
- #7 【深入學習js之——執行上下文】
- #8 【深入學習js之——閉包】
- #9 【深入學習js之——引數按值傳遞】
- #10 【深入學習js之——call和apply】
歡迎新增我的個人微信討論技術和個體成長。
歡迎關注我的個人微信公眾號——指尖的宇宙,更多優質思考乾貨