javascript:函數屬性梳理

主題

javascript中最有意思的就是函數,函數也是對象。本文主要講解函數對象中的三個在屬性:javascript

  1. length
  2. arguments
  3. caller

1. length

沒錯,length屬性並不是數組專有,函數也有。在函數中length屬性描述的是參數的數量,若是沒有參數則長度等於0。java

2. arguments

arguments是一個類數組對象包含着傳入函數的全部參數,以及他自身的一些屬性。arguments不是一個 Array。它相似於Array,但除了length屬性和索引元素以外沒有任何Array屬性。例如,它沒有 pop 方法。可是它能夠被轉換爲一個真正的Arrayes6

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

3. caller

若是一個函數f是在全局做用域內被調用的,則f.callernull,相反,若是一個函數是在另一個函數做用域內被調用的,則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.callerspa

結語

本文目的在於本身的知識梳理與增強。prototype

參考文獻:

  • 《javascript高級程序設計》
  • MDN

種一顆樹最好的時間是十年前。

相關文章
相關標籤/搜索