JavaScript裡面的arguments到底是個啥?

来源:https://www.cnblogs.com/lcr-smg/archive/2018/12/04/10065877.html
-Advertisement-
Play Games

類數組對象:arguments總所周知,js是一門相當靈活的語言。當我們在js中在調用一個函數的時候,我們經常會給這個函數傳遞一些參數,js把傳入到這個函數的全部參數存儲在一個叫做arguments的東西裡面,那麼這到底是什麼東西?在js中萬物皆對象,甚至數組字元串函數都是對象。所以這個叫做argu ...


類數組對象:arguments

總所周知,js是一門相當靈活的語言。當我們在js中在調用一個函數的時候,我們經常會給這個函數傳遞一些參數,js把傳入到這個函數的全部參數存儲在一個叫做arguments的東西裡面,那麼這到底是什麼東西?

在js中萬物皆對象,甚至數組字元串函數都是對象。所以這個叫做arguments的東西也是個對象,而且是一個特殊的對象,它的屬性名是按照傳入參數的序列來的,第1個參數的屬性名是’0’,第2個參數的屬性名是’1’,以此類推,並且它還有length屬性,存儲的是當前傳入函數參數的個數,很多時候我們把這種對象叫做類數組對象。類數組對象和數組都是對象這個媽生的,但是數組是大哥比類數組對象多了很多其他的玩具(方法),類數組對象只是長得很像數組的弟弟而已。

慢著,剛剛不是說數組也是對象嗎,現在這個類數組對象又是什麼? 沒辦法,js就是這麼的靈活。這個類數組對象不僅存儲給函數傳入的參數,也具有一些其他的屬性,等下會一一道來。

因為類數組對象和數組有很多的共性,所以我們經常可以用call方法,讓類數組對象也使用的數組的一些方法,就是讓這個弟弟去玩哥哥的玩具,比如……,還是不扯遠了,這篇文章只是說什麼是arguments,想知道更多關於對象如何借調數組方法的話,請參考這篇文章。


arguments的屬性
接下來我們來看看arguments對象裡面到底有些什麼東西,是騾子是馬拉出來溜溜。

1 function showargs() {
2     console.log( arguments );
3 }
4 
5 showargs(1,2,3,4,5);

下麵我們用console.log的方式,將arguments對象輸出到控制台,這裡不得不說一句,chrome的console工具好用得不得了(我不是來打廣告的)。



這裡我們可以看到arguments對象將我傳入的五個參數以數組的形式保存在裡面,還有保存了我傳入函數的實參的個數(length)。而且我們可以看到arguments對象的 ==_ proto _== 是指向object的,這也說明瞭他是個類數組對象,而不是一個數組。

有了這個對象我們以後寫函數的時候,就不用給所有的形參指定參數名,然後通過參數名的方式獲取參數了,我們可以直接使用arguments對象來獲取實參,這樣是不是方便了很多呢。
有些語言在我們給函數指定了參數名之後,當調用函數時,會判斷當前傳入的參數是否與函數定義的參數個數相等,不相等就會報錯,但是靈活的js(不是我說,js是真的靈活)並不會驗證傳遞給函數的參數個數是否等於函數定義的參數個數。所以為了裝逼(代碼的簡潔度),我們使用arguments調用參數可以不混淆不同函數之間的參數名。另外為了裝逼(代碼的嚴整度),我們也能用arguments來判斷當前傳入參數的個數是否與我們需要的數量一致。

下麵舉個慄子:

 1 function add() {
 2     if( arguments.length == 2 ){
 3         return arguments[0] + arguments[1];
 4     }else{
 5         return '傳入參數不合法';
 6     }
 7 }
 8 
 9 console.log( add(2,3) );
10 console.log( add(1,2,3) );

看看結果:


最後我們還可以看到arguments還有一個叫做callee的屬性,這個屬性是表示的是當前函數的一個引用,簡單點說,這個屬性裡面存儲的我們調用的這個函數的代碼,實在無法理解的時候,又到了console.log大顯身手的時候了。

 1 function showcallee() {
 2     var a = '這裡是代碼';
 3     var b = '這是另一段代碼';
 4     var c = a + b;
 5 
 6     console.log(arguments.callee);
 7 
 8     return c;
 9 }
10 showcallee();

結果



看到結果的你是不是和我一樣驚呆了呢,這不就是我寫的代碼嗎,arguments.callee完完整整的把這個函數的這段代碼返回了。
arguments的一些妙用

1.利用arguments實現方法的重載

下麵我們利用arguments對象來實現一個參數相加的函數,不論傳入多少參數都行,將傳入的參數相加後返回。

 1 function add() {
 2     var len = arguments.length,
 3         sum = 0;
 4     for(;len--;){
 5         sum += arguments[len];
 6     }
 7     return sum;
 8 }
 9 console.log( add(1,2,3) );   //6
10 console.log( add(1,3) );     //4
11 console.log( add(1,2,3,5,6,2,7) );   //26

由於js是一種弱類型的語言,沒有重載機制,當我們重寫函數時,會將原來的函數直接覆蓋,這裡我們能利用arguments,來判斷傳入的實參類型與數量進行不同的操作,然後返回不同的數值。

2.利用arguments.callee實現遞歸

先來看看之前我們是怎麼實現遞歸的,這是一個結算階乘的函數

1 function factorial(num) {
2     if(num<=1) {
3         return 1;
4     }else {
5         return num * factorial(num-1);
6     }
7 } 

但是當這個函數變成了一個匿名函數時,我們就可以利用callee來遞歸這個函數。

1 function factorial(num) {
2     if(num<=1) {
3         return 1;
4     }else {
5         return num * arguments.callee(num-1);
6     }
7 } 


這個方法雖然好用,但是有一點值得註意,ECMAScript4中為了限制js的靈活度,讓js變得嚴格,新增了嚴格模式,在嚴格模式中我們被禁止不使用var來直接聲明一個全局變數,當然這不是重點,重點是arguments.callee這個屬性也被禁止了。不過這都不是事兒,ES6為我們新增了很多好用的變數聲明方式和新的語法糖,作為一個時髦的前端,我們趕緊學習一些ES6的新語法吧。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一,效果圖。 二,代碼。 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>javascript 對象</title> </head> <body> <p>創建javascript對易縣.</p> <p id="demo"></p ...
  • 1.爬蟲:爬蟲,是一種按照一定的規則,自動地抓取網頁信息的程式或者腳本;利用NodeJS實現一個簡單的爬蟲案例,爬取Boss直聘網站的web前端相關的招聘信息,以廣州地區為例; 2.腳本所用到的nodejs模塊 express 用來搭建一個服務,將結果渲染到頁面 swig 模板引擎 cheerio ...
  • 一、項目需求 最近公司有終端桌面系統需求,需要支持本地離線運行(本地數據為主,雲端數據同步),同時支持Window XP,最好跨平臺。要求安裝配置簡單(一次性打包安裝),安裝包要小,安裝時間短,可離線安裝。技術要求使用主流技術,有利於擴展,升級,便於遷移到其它各種終端和平臺應用。 二、需求分析和選擇 ...
  • 一、問題 今天在寫jsp頁面時,發現加上某段代碼後,頁面的其它js就失效了,死活出不來,然後打開谷歌瀏覽器發現,頁面js報如下錯誤: Uncaught SyntaxError: Unexpected string 二、解決 1. jQuery有問題?引用的jQuery有衝突? 然後就去首頁和分頁面檢 ...
  • 什麼是Aurelia? Aurelia 是一個新的開源的,基於web標準的mvvm框架,是一個現代化的js模塊的集合。 Aurelia提供了豐富的plugin,例如國際化,驗證,模態框,UI可視化等。 其強大的binding模塊和template模塊,能夠幫助你更專註於你的業務邏輯,寫出清晰高效的代 ...
  • 使用的是Node.js作為後端 統一下單: appid:這裡的appid是調起微信支付的appid mch_id:商戶號,需要註意的是商戶號要與appid對應 nonce_str:Math.random().toString(36).substr(2)這是我的隨機字元串的生成演算法 sign:這裡的簽 ...
  • ①為什麼要使用原型:為了實現繼承。 ②利用constructor屬性可以讓實例化對象輕鬆訪問原型,實現實例化對象對原型對象的修改,但是原型對象是全局對象,一般不能隨意修改原型對象的成員。該屬性多用於調試。 ③原型是構造函數的屬性,原型是實例化對象的原型對象。 ④實例化對象如何訪問原型對象: func ...
  • html : 1、相當於沒有穿衣服的人,一套瀏覽器認識的規則, 2、開發者: 學習html規則 開發後臺程式: -寫html文件(充當模板) -資料庫獲取數據,然後替換到html文件的指定位置(web框架) 3、本地測試 -找到文件路徑,直接用瀏覽器打開 -用pycharm打開測試 4、編寫html ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...