天天看點

js中arguments詳解

在js中一切都是對象,連函數也是對象,函數名其實是引用函數定義對象的變量。

什麼是arguments?

這個函數體内的arguments非常特殊,實際上是所在函數的一個内置類數組對象,可以用數組的[i]和.length。

每個函數都有一個arguments屬性,表示函數的實參集合,這裡的實參是重點,就是執行函數時實際傳入的參數的集合。arguments不是數組而是一個對象,但它和數組很相似,是以通常稱為類數組對象,以後看到類數組其實就表示arguments。arguments對象不能顯式的建立,它隻有在函數開始時才可用。

arguments有length屬性,arguments.length 為函數實參個數,可以用arguments[length]顯示調用參數:

function func(){

       for(var i=0;i<arguments.length;i++){

       console.log(arguments[i]);

   }     

}

arguments的應用

1. arguments.callee為引用函數自身。我們可以借用arguments.length可以來檢視實參和形參的個數是否一緻

function add(a, b) { 

  var realLen = arguments.length; 

  console.log("realLen:", arguments.length); 

  var len = add.length; 

  console.log("len:", add.length); 

  if (realLen == len) { 

    console.log('實參和形參個數一緻'); 

  } else { 

    console.log('實參和形參個數不一緻'); 

  } 

}; 

add(1,2,3,6,8);

2.我們可以借用arguments.callee來讓匿名函數實作遞歸

var sum = function(n) { 

    if(n == 1) { 

        return 1; 

    return n + arguments.callee(n-1); 

 } 

console.log("sum =", sum(5)); 

3.編寫一個函數求傳入的若幹個數字(不能用數組顯示傳入)的和

function add() { 

    //console.log("length", arguments.length); 

    var len = arguments.length; 

    var sum = 0; 

    for (var i = 0; i < len; ++i) { 

        sum += arguments[i]; 

    } 

    return sum; 

4.如何将arguments轉成了一個實實在在的數組

Array.prototype.slice.call(arguments)能将具有length屬性的對象轉成數組,

首先我們看看call是幹啥的,舉個例子:

ar obj1={

      name:"java"

  }

  window.name="javascript";

  var func=function(){

      console.log(this.name);

func();  //javasript

func.call(obj1); //java

我們可以很清楚的看到,call的一個作用是可以改變函數運作的作用域,func中的this指向了obj1。

那Array.prototype.slice.call(arguments)是幹啥的呢,首先我們猜測Array.prototype.slice是一個方法,将它call(arguments)之後,Array.prototype.slice中的this就指向了arguments對象了。

其實Array.slice是一個數組複制函數,它接受兩個參數(strat,[end]);從下标為start複制到下标為end,舉個栗子:

var numArr=[1,2,3,4,5];

console.log(numArr.slice(0,4)); //[1,2,3,4]

console.log(numArr.slice()); //[1,2,3,4,5]

console.log(numArr.slice(1)) //[2,3,4,5]

我們可以大膽的猜測一下slice函數的内部實作:

Array.prototype.slice = function(start,end){

      var result = new Array();

      start = start || 0;

      end = end || this.length; //this指向調用的對象,當用了call後,能夠改變this的指向,也就是指向傳進來的對象,這是關鍵

      for(var i = start; i < end; i++){

           result.push(this[i]);

      }

      return result;

 注意當中的result.push(this[i]),當Array.prototype.slice.call(arguments)後,就變成了result.push(arguments[i]),這樣就将arguments轉成了一個實實在在的數組了。