JavaScript裏面的arguments究竟是個啥?

類數組對象:arguments

總所周知,js是一門至關靈活的語言。當咱們在js中在調用一個函數的時候,咱們常常會給這個函數傳遞一些參數,js把傳入到這個函數的所有參數存儲在一個叫作arguments的東西里面,那麼這究竟是什麼東西?

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

慢着,剛剛不是說數組也是對象嗎,如今這個類數組對象又是什麼? 沒辦法,js就是這麼的靈活。這個類數組對象不只存儲給函數傳入的參數,也具備一些其餘的屬性,等下會一一道來。

由於類數組對象和數組有不少的共性,因此咱們常常能夠用call方法,讓類數組對象也使用的數組的一些方法,就是讓這個弟弟去玩哥哥的玩具,好比……,仍是不扯遠了,這篇文章只是說什麼是arguments,想知道更多關於對象如何借調數組方法的話,請參考這篇文章。前端


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

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對象來實現一個參數相加的函數,不論傳入多少參數都行,將傳入的參數相加後返回。spa

 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實現遞歸

先來看看以前咱們是怎麼實現遞歸的,這是一個結算階乘的函數3d

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

可是當這個函數變成了一個匿名函數時,咱們就能夠利用callee來遞歸這個函數。code

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的新語法吧。

對象

相關文章
相關標籤/搜索