javascript中最有意思的就是函數,函數也是對象。本文主要講解函數對象中的三個在屬性:javascript
沒錯,length
屬性並不是數組專有,函數也有。在函數中length
屬性描述的是參數的數量,若是沒有參數則長度等於0。java
arguments
是一個類數組對象,包含着傳入函數的全部參數,以及他自身的一些屬性。arguments
不是一個 Array
。它相似於Array
,但除了length屬性和索引元素以外沒有任何Array
屬性。例如,它沒有 pop
方法。可是它能夠被轉換爲一個真正的Array
:es6
function sum (num1, num2) {
console.log(arguments) // Arguments(2) [10, 15, callee: ƒ, Symbol(Symbol.iterator): ƒ]
// 轉化數組①
console.log([].slice.call(arguments))// [10, 15]
// 轉化數組②
console.log(Array.prototype.slice.call(arguments)) // [10, 15]
// 轉化數組③ es6
console.log(Array.from(arguments)) // [10, 15]
return num1 + num2
}
sum(10, 15)
複製代碼
上面涉及的call
方法先理解爲參數傳遞,會再寫一篇文章來說解。查看一下在函數內打印arguments
對象都是些啥:算法
arguments
對象還有一個名叫
callee
的屬性,該屬性其實就是一個指針,指向擁有這個
arguments
對象的函數。那麼
arguments.callee()
等於
sum()
。這在函數的名稱是未知時頗有用,例如在沒有名稱的函數表達式 (也稱爲
匿名函數)。那
callee
這玩意有啥用呢?來看一下《
javascript高級程序設計》的描述的經典階乘函數:
function factorial(num) {
return num <= 1 ? 1 : (num * factorial(num - 1))
}
複製代碼
定義階乘通常都須要用到遞歸算法,遞歸的時候須要明確遞歸的函數,這樣帶來的問題就是函數的執行便與函數名僅僅的耦合在了一塊兒。爲了消除這種耦合,則可使用arguments.callee
:數組
function factorial(num) {
return num <= 1 ? 1 : (num * arguments.callee(num - 1))
}
複製代碼
在什麼狀況下須要使用這種匿名函數呢?傳送門bash
若是一個函數f
是在全局做用域內被調用的,則f.caller
爲null
,相反,若是一個函數是在另一個函數做用域內被調用的,則f.caller
指向調用它的那個函數。函數
function outer () {
inner()
}
function inner () {
console.log(inner.caller)
}
outer()
複製代碼
控制檯:ui
ƒ outer () {
inner()
}
複製代碼
在控制檯中顯示了
outer()
函數的源碼。由於outer()
調用了inner()
,因此inner.caller
就指向了outer()
。爲了實現更鬆散的耦合,也可使用arguments.callee.caller
代替inner.caller
。spa
本文目的在於本身的知識梳理與增強。prototype
參考文獻:
種一顆樹最好的時間是十年前。