js中的arguments是一個好東西

菜頭他哥發表於2018-09-23

今天有空拿出《JavaScript高階程式設計》再仔細看了下,發現js這門語言真是靈活,可以說充滿了黑魔法。

js中的arguments是一個好東西

今兒給大夥講js中黑魔法之一類陣列物件:

arguments

一、什麼是arguments?

在js中,我們在呼叫有引數的函式時,當往這個呼叫的有參函式傳參時,js會把所傳的引數全部存到一個叫arguments的物件裡面。

類如:

function test(a,b,c,d,e,f){
    console.log(arguments)
}
test(1,2,3,4,5,6)
複製程式碼

在Chrome的控制檯執行這段程式碼:

js中的arguments是一個好東西

我們發現arguments的__proto__是Object,證明了arguments是個物件型別,並不是陣列。它的屬性名是按照傳入引數的序列來的,第1個引數的屬性名是"0",第2個引數的屬性名是"1",以此類推,屬性名類似陣列中的索引值。

那麼問題來了,arguments是怎麼產生的呢?

Javascrip中每個函式都會有一個Arguments物件例項arguments,引用著函式的實參。它是寄生在js函式當中的,不能顯式建立,arguments物件只有函式開始時才可用。

那麼,既然arguments是一個物件,除了根據所在函式的實參動態生成的屬性名之外,也有其他的屬性名。

比如:arguments.length為函式實參個數,arguments.callee引用函式自身。

js中的arguments是真的6

有了arguments這個物件之後,我們可以不用給函式預先設定形參了,可以動態地通過arguments為函式加入引數。這也說明JS這門語言是真的皮,並不會驗證傳遞給函式的引數個數是否等於函式定義的引數個數,不像java語言那樣嚴謹。

function add() {  
    if( arguments.length == 2 ){       
        return arguments[0] + arguments[1];   
    }else{  
        return '傳入引數不合法';    
        } 
    
}  
console.log( add(2,3) ); 
console.log( add(1,2,3) );    
複製程式碼

js中的arguments是一個好東西

這在java中就得根據引數不同進行多次過載了,而js中沒有過載機制,多個同名不同參的函式,最js文件最下面的那個函式給直接覆蓋。

所以,面對同名不同參的情況,我們可以利用arguments對引數進行判斷,從而進行不同的運算。

arguments的屬性介紹

arguments.length就不用多講了,指的是函式傳入實參的個數。

arguments.callee是指向當前正在執行函式的指標(引用),直白點來說,就是這個屬性值就是當前函式的程式碼。

function add() {  
    var a =2;
    var b = 3;
    var c = a+b;
    console.log(arguments.callee);
    console.log(c)
} 
add()
複製程式碼

js中的arguments是一個好東西

arguments.callee的使用

在《js高階程式設計》的遞迴章節中,有這樣的一段示例程式碼:

function factorial (num) {
    if (num <= 1){
        return 1;
    } else {
       return num * factorial(num-1);  
    }
}
複製程式碼

arguments.callee可以實現對函式的遞迴使用,上述的程式碼可以寫成這樣:

function factorial (num) {
    if (num <= 1){
        return 1;
    } else {
       return num * arguments.callee(num-1);  
    }
}
複製程式碼

通過使用arguments.callee代替函式名,可以確保無論怎麼樣呼叫函式都不會出現問題。因此,在編寫遞迴時,使用arguments.callee總比使用函式名更保險。 ——《js高程》原話

這裡又出現了一個問題,怎麼說使用函式名不保險呢?

當函式出現這樣的呼叫時,

var anfactorial = factorial;
factorial = null;
console.log(anfactorial(4))
複製程式碼

第一種情況會出現報錯:

js中的arguments是一個好東西
第二種用arguments.callee代替函式名,正常執行:

js中的arguments是一個好東西

但是在ES4中新增的嚴格模式中,arguments.callee這個屬性會導致錯誤。可能自己人都看不慣js這麼皮了,限制了一下。 在沒有使用嚴格模式的情況下,可以使用。對外封裝開源的小外掛,不建議用arguments.callee,但是arguments是基本都會用到的。

arguments是一個好東西。

本文參考了《JavaScript高階程式設計》

js中arguments的用法[www.cnblogs.com/LMJBlogs/p/…]

js的arguments到底是什麼? [blog.csdn.net/qq_16339527… ]

相關文章