理解Javascript_14_函數(shù)形式參數(shù)與arguments
更新時間:2010年10月20日 11:19:56 作者:
在'執(zhí)行模型詳解'的'函數(shù)執(zhí)行環(huán)境'一節(jié)中對arguments有了些許的了解,那么讓我們深入的分析一下函數(shù)的形式參數(shù)與arguments的關(guān)系。
注:在閱讀本博文前請先閱讀《理解javascript_13_執(zhí)行模型詳解》
注:本文的部分內(nèi)容是自已的一些推論,并無官文文檔作依據(jù),如有錯誤之后,還望指正。
生澀的代碼
我們先來看一段比較生澀的代碼:
function say(msg,other,garbage){
alert(arguments[1]);//world
var other = 'nice to meet you!';
var msg;
alert(arguments.length);
alert(msg);//hello
alert(other);//nice to meet you!
alert(arguments[1]);//nice to meet you!
alert(garbage);//undefined
}
say('hello','world');
你能正確的解釋代碼的執(zhí)行結(jié)果嗎?思考一下.
我想代碼運行的結(jié)果,應(yīng)該會和你的想象有很大的出入吧!為什么msg正常輸出為hello,而不是undefined呢?函數(shù)定義的參數(shù)和函數(shù)內(nèi)部定義的變量重復(fù)了會發(fā)生什么呢?arguments和函數(shù)定義時的參數(shù)有什么關(guān)系呢?讓我們來一一解答:
簡單的內(nèi)存圖

注:虛線表示的是曾經(jīng)引用的指向。
解答
首先,我們來了解兩個概念,形式參數(shù)和實際參數(shù)。形式參數(shù)指的是定義方法時所明確指定的參數(shù),由于Javascript語言的靈活性,javascript并不要求方法調(diào)用時,所傳遞的參數(shù)個數(shù)與形式參數(shù)一致.而javascript實際調(diào)用時所傳遞的參數(shù)就是實際參數(shù)。arguments指的就是實際參數(shù)。從say方法中可以看出,say定義了三個形式參數(shù),而實際調(diào)用時只傳遞了兩個值。因此arguments.length的值為2,而不是3.接著我們來看一下arguments的特殊行為,個人感覺arguments會將所有的實際參數(shù)都當(dāng)作對象來看待,對于基本數(shù)據(jù)類型的實際參數(shù)則會轉(zhuǎn)換為其對應(yīng)的對象類型。這是根據(jù)在函數(shù)內(nèi)定義與形式參數(shù)同名的變量并賦值,arguments對應(yīng)的值會跟著改變來判斷的。
接著我們來分析一下構(gòu)建say方法執(zhí)行上下文的過程,由于邏輯比較復(fù)雜,這里我寫一些'偽代碼'來進行說明:
function say(msg,other,garbage){
//先對函數(shù)聲明的變量進行'預(yù)解析',內(nèi)部執(zhí)行流程,它是是不可見的
var msg = undefined;
var other = undefined;
var garbage = undefined;
//再對函數(shù)內(nèi)部定義的變量進行'預(yù)解析'
var other = undefined;//很明顯,此時這個定義已經(jīng)無意義了。
var msg = undefined;//無意義
//對實際參數(shù)進行賦值操作
msg = new String('hello');//arguments的會將所有實際參數(shù)當(dāng)作對象看待
other = new String('world');
//正式進入函數(shù)代碼部分
alert(arguments[1]);//world
other = 'nice to meet you!';
//var msg;這個已經(jīng)被預(yù)解析了,因此不會再執(zhí)行
alert(arguments.length);//2
alert(msg);//hello
alert(other);//nice to meet you!
alert(arguments[1]);//nice to meet you!
alert(garbage);//undefined
}
這段代碼已經(jīng)可以解釋一面的所有的問題了。我就不多說了。
唯一強調(diào)的一點是在內(nèi)部用var定義與形式參數(shù)同名的變量是無意義的,因為在程序'預(yù)解析'后,會將它們看作為同一個變量。
其它
關(guān)于arguments還有很多特性,我在《偽數(shù)組》一文中提到也提到了arguments,有興趣的讀者可以去看一下。arguments的實際應(yīng)用你還可以參考一下這一篇文章 :
http://www.gracecode.com/archives/2551/
好了,也就這么多了。希望大家能多多指正,多提意見吧。
注:本文的部分內(nèi)容是自已的一些推論,并無官文文檔作依據(jù),如有錯誤之后,還望指正。
生澀的代碼
我們先來看一段比較生澀的代碼:
復(fù)制代碼 代碼如下:
function say(msg,other,garbage){
alert(arguments[1]);//world
var other = 'nice to meet you!';
var msg;
alert(arguments.length);
alert(msg);//hello
alert(other);//nice to meet you!
alert(arguments[1]);//nice to meet you!
alert(garbage);//undefined
}
say('hello','world');
你能正確的解釋代碼的執(zhí)行結(jié)果嗎?思考一下.
我想代碼運行的結(jié)果,應(yīng)該會和你的想象有很大的出入吧!為什么msg正常輸出為hello,而不是undefined呢?函數(shù)定義的參數(shù)和函數(shù)內(nèi)部定義的變量重復(fù)了會發(fā)生什么呢?arguments和函數(shù)定義時的參數(shù)有什么關(guān)系呢?讓我們來一一解答:
簡單的內(nèi)存圖

注:虛線表示的是曾經(jīng)引用的指向。
解答
首先,我們來了解兩個概念,形式參數(shù)和實際參數(shù)。形式參數(shù)指的是定義方法時所明確指定的參數(shù),由于Javascript語言的靈活性,javascript并不要求方法調(diào)用時,所傳遞的參數(shù)個數(shù)與形式參數(shù)一致.而javascript實際調(diào)用時所傳遞的參數(shù)就是實際參數(shù)。arguments指的就是實際參數(shù)。從say方法中可以看出,say定義了三個形式參數(shù),而實際調(diào)用時只傳遞了兩個值。因此arguments.length的值為2,而不是3.接著我們來看一下arguments的特殊行為,個人感覺arguments會將所有的實際參數(shù)都當(dāng)作對象來看待,對于基本數(shù)據(jù)類型的實際參數(shù)則會轉(zhuǎn)換為其對應(yīng)的對象類型。這是根據(jù)在函數(shù)內(nèi)定義與形式參數(shù)同名的變量并賦值,arguments對應(yīng)的值會跟著改變來判斷的。
接著我們來分析一下構(gòu)建say方法執(zhí)行上下文的過程,由于邏輯比較復(fù)雜,這里我寫一些'偽代碼'來進行說明:
復(fù)制代碼 代碼如下:
function say(msg,other,garbage){
//先對函數(shù)聲明的變量進行'預(yù)解析',內(nèi)部執(zhí)行流程,它是是不可見的
var msg = undefined;
var other = undefined;
var garbage = undefined;
//再對函數(shù)內(nèi)部定義的變量進行'預(yù)解析'
var other = undefined;//很明顯,此時這個定義已經(jīng)無意義了。
var msg = undefined;//無意義
//對實際參數(shù)進行賦值操作
msg = new String('hello');//arguments的會將所有實際參數(shù)當(dāng)作對象看待
other = new String('world');
//正式進入函數(shù)代碼部分
alert(arguments[1]);//world
other = 'nice to meet you!';
//var msg;這個已經(jīng)被預(yù)解析了,因此不會再執(zhí)行
alert(arguments.length);//2
alert(msg);//hello
alert(other);//nice to meet you!
alert(arguments[1]);//nice to meet you!
alert(garbage);//undefined
}
這段代碼已經(jīng)可以解釋一面的所有的問題了。我就不多說了。
唯一強調(diào)的一點是在內(nèi)部用var定義與形式參數(shù)同名的變量是無意義的,因為在程序'預(yù)解析'后,會將它們看作為同一個變量。
其它
關(guān)于arguments還有很多特性,我在《偽數(shù)組》一文中提到也提到了arguments,有興趣的讀者可以去看一下。arguments的實際應(yīng)用你還可以參考一下這一篇文章 :
http://www.gracecode.com/archives/2551/
好了,也就這么多了。希望大家能多多指正,多提意見吧。
您可能感興趣的文章:
- js的隱含參數(shù)(arguments,callee,caller)使用方法
- javascript arguments 傳遞給函數(shù)的隱含參數(shù)
- javascript 利用arguments實現(xiàn)可變長參數(shù)
- 深入理解JS函數(shù)的參數(shù)(arguments)的使用
- JS函數(shù)arguments數(shù)組獲得實際傳參數(shù)個數(shù)的實現(xiàn)方法
- javascript函數(shù)中的arguments參數(shù)
- javascript中通過arguments參數(shù)偽裝方法重載
- JavaScript中使用arguments獲得函數(shù)傳參個數(shù)實例
- JavaScript arguments 多參傳值函數(shù)
- JS函數(shù)動態(tài)傳遞參數(shù)的方法分析【基于arguments對象】
相關(guān)文章
bootstrap datetimepicker2.3.11時間插件使用
這篇文章主要為大家詳細介紹了bootstrap datetimepicker2.3.11時間插件使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11解決JS請求路徑控制臺報錯?Failed?to?launch'xxx'?because?t
這篇文章主要介紹了JS請求路徑控制臺報錯?Failed?to?launch?‘xxx‘?because?the?scheme?does?not?have?a?registered?handler的問題,本文給大家分享最新完美解決方法,需要的朋友可以參考下2023-03-03使用JS將字符串保存成文件到本地(.txt、.json、.md)
工作中有時需要通過JavaScript保存文件到本地,下面這篇文章主要給大家介紹了關(guān)于使用JS將字符串保存成文件到本地的相關(guān)資料,分別包括生成.txt、.json、.md等文件,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-06-06關(guān)于JavaScript 數(shù)組你應(yīng)該知道的事情(推薦)
這篇文章主要介紹了JavaScript 數(shù)組,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04JavaScript+html實現(xiàn)前端頁面隨機二維碼驗證
這篇文章主要為大家詳細介紹了JavaScript+html實現(xiàn)前端頁面隨機二維碼驗證,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-06-06