js語法中的傳遞引數,對於初學者是乙個非常重要的概念。很多小夥伴在學習「值傳遞」和「引用傳遞」時,會有不少煩惱。今天我們就來通過各種姿勢全方位剖析js中的值傳遞。
本文章將會用10分鐘時間無死角的解析js的傳參方式,希望能對您有所幫助。
先說結論,js只有值傳遞,沒有引用傳遞。這句話可能會顛覆一些小夥伴的認知,但請先別急,馬上你將會贊同我。
1. 值傳遞是什麼?
在函式傳參的過程中,實參將數值傳遞給形參。
exp:
function fun(x) {
console.log(x);
let a = 123;
fun(a);
執行結果;
在fun(a)這個函式呼叫語句中,實參為a、形參為x,從輸出結果來看,可以證明實參a將數值123傳給了形參x。
疑問:是否可以通過形參x數值的修改,來改變實參a的值?
exp:
function fun(x) {
x = 666;
let a = 123;
fun(a);
console.log(a);
執行結果:
可以看到實參a的數值並沒有因為x的改變而發生變化。是因為值傳遞的特點決定,咱們接著往下看。
2、值傳遞的特點:
單向傳遞,只能將實參的數值傳遞給形參,不能將形參的值傳遞給實參。
exp:
我們希望編寫乙個交換兩個變數數值的函式swap。
function swap(x, y) {
let t;
t = x;
x = y;
y = t;
let a = 123;
let b = 456;
swap(a, b);
console.log(a, b);
執行結果:
雖然swap(a, b)被調,但是實參a,b的值並未發生改變。是因為實參a,b與形參x,y在記憶體中是不同的空間。這裡我們引入乙個位址的概念。
位址就是記憶體中的乙個編號,等價於我們常說的引用id(引用id是優化後的位址)。
可以將記憶體想象成一棟高樓,那麼位址號就是樓房中的某個房間號。
咱們來通過記憶體模擬一下實參與形參的交換過程。(如下圖)假設實參a的位址18,實參b的位址為19。而形參x的位址為20,形參y的位址為21。
那麼在swap函式執行完後。形參x和y的值確實進行了交換,但是由於形參與實參是不同的空間,所以形參x,y的改變,是無法影響到實參a,b的。
疑問:有沒有其他辦法可以通過形參改變實參的數值呢?
有,當傳遞的實參為引用型別時,可以通過形參改變實參所指向空間的數值。
這句話比較難以理解。別急,下面咱們來討究這個問題。
1. 內建基本型別與引用型別作為實參的區別:
首先無論實參是什麼型別的資料,實參傳遞給形參的一定是實參的數值本身。
通過剛才的swap函式,其實我們已經得出了乙個結論:
當傳遞的實參為內建基本型別時,形參是無法改變實參的數值。
而當實參為引用型別資料時,又會又怎樣的結果呢?
exp:
我們依然希望編寫乙個具有交換功能的swap函式,只不過這次swap函式的引數是乙個引用型別資料陣列。通過swap函式實現陣列內部元素的交換。
let arr = [1, 2];
function swap(arr1) {
let t;
t = arr1[0];
arr1[0] = arr1[1];
arr1[1] = t;
swap(arr);
console.log(arr[0], arr[1]);
執行結果:
這次確實交換了arr陣列中的arr[0],arr[1]兩個元素的值。
原因是引用型別在記憶體中是由兩塊空間構成的:
咱們依然用記憶體模擬應用型別資料在記憶體中的儲存方式,20代表一塊空間,18代表一塊空間。如圖所示,18的空間是真正儲存資料的空間(new出來的堆空間),20是儲存真正資料所在空間的位址。
而在swap函式呼叫時,實參arr將數值18(也就是new出來空間的位址)傳值給形參arr1。也就意味著他們都指向同一塊空間,那麼在swap函式中操作arr1就等價於操作arr本身。就好比乙個房子,有兩把鑰匙,任意一把鑰匙都能開啟房子。所以arr陣列的數值就會發生交換。
總結:1. js的傳參只有值傳遞,所謂的引用傳遞本質就是值傳遞。
2. 值傳遞是單向的。
3. 內建基本型別做為實參時,不能通過形參改變實參的數值。
4. 引用型別做為實參時,可以通過形參改變實參所指向空間的值。
思考:(如果有問題,歡迎私聊討論)
let arr1 = [1, 2];
let arr2 = [3, 4];
function swap(arr1, arr2) {
let t;
t = arr1;
arr1 = arr2;
arr2 = t;
swap(arr1, arr2);
console.log(arr1, arr2);千鋒html5學院:如何講清楚函式防抖?zhuanlan.zhihu.com千鋒html5學院:如何講清楚函式節流?zhuanlan.zhihu.com千鋒html5學院:如何講清楚閉包?zhuanlan.zhihu.com
js 閉包傳遞引數 JS中的引數傳遞詳解
js語法中的傳遞引數,對於初學者是乙個非常重要的概念。很多小夥伴在學習 值傳遞 和 引用傳遞 時,會有不少煩惱。今天我們就來通過各種姿勢全方位剖析js中的值傳遞。本文章將會用10分鐘時間無死角的解析js的傳參方式,希望能對您有所幫助。先說結論,js只有值傳遞,沒有引用傳遞。這句話可能會顛覆一些小夥伴...
js 中的閉包
先理解 js 中的執行環境 閉包按中文的意思就是關上乙個包的意思。如果我們把函式的變數物件當做是乙個包的話,那這個詞很形象體現了它的作用 函式被呼叫時會建立它的執行環境,函式語句執行完後程式會自動銷毀這個函式的執行環境,但是當乙個函式中宣告了另乙個函式 子函式 並且如果存在對這個子函式引用,就會形成...
js中的閉包
閉包 英文 closure 1.閉包是乙個函式與作用域環境 即詞法環境 形成的閉包 2.閉包的理解 廣義的閉包 1.函式 2.這個函式能訪問到函式外部的狀態 也稱函式外部的變數 並不是我們平時理解的閉包 函式巢狀函式,並且內部函式通過return返回到外部,外部可以訪問內部函式的變數 總結 閉包 函...