js 閉包傳參 JS中的引數傳遞詳解

2021-10-16 15:08:11 字數 2596 閱讀 9062

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返回到外部,外部可以訪問內部函式的變數 總結 閉包 函...