【JS第15期】Function 詳解

函數其實是一個對象。每一個函數都是Function 實例,並且都與其餘引用類型同樣具備屬性和方法。因爲函數也是對象,所以函數名實際上也是一個指向函數對象的指針。前端

函數定義方式

函數聲明chrome

function sum(num1, num2) {
  return num1 + num2;
}
複製代碼

函數表達式數組

var sum = function(num1, num2) {
  return num1 + num2;
}
複製代碼

Function 構造函數安全

var sum = new Function('num1', 'num2', 'return num1 + num2');
複製代碼

注意:使用構造函數定義是不推薦的。由於這種語法會致使解析兩次代碼(第一次解析常規ECMAScript代碼, 第二次是解析傳入構造函數中的字符串),從而影響性能bash

函數聲明與函數表達式的區別app

  • 函數聲明會首先被解析器讀取,並使其在執行任何代碼以前能夠訪問。如:
console.log(sum()) // 1
function sum() {
  return 1;
}
複製代碼
  • 函數表達式則必須等到解析器執行到它所在的代碼塊,纔會真正被解析器執行。如:
console.log(sum()) // sum is not a function
var sum = function () {
  return 1;
}
複製代碼

沒有重載

在建立兩個同名函數時,後面的函數會覆蓋了前面的函數。如:函數

function sum() {
  return 1;
}
function sum() {
  return 2
}
sum() // 2;
複製代碼

做爲值的函數

由於ECMAScript 中函數名自己就是變量,因此函數能夠做爲值來使用。也就是說,不只能夠像傳遞參數同樣傳遞給另外一個參數,也能夠將一個函數作爲函數返回值返回,以下:性能

function test(func, arg) {
  return func(arg)
}
function test2() {
  return function() {
    console.log('test2')
  }
}
複製代碼

函數內部屬性

argumentsui

arguments 是一個類數組的對象,返回值爲函數的全部參數。這個對象還有另一個屬性callee,該屬性是一個指針,指向arguments對象所在的函數的指針。舉例說明:this

// demo1.js
// 定義一個階乘
function test(num){
  console.log('111')
    if(num <= 1){
        return 1;
    } else {
        return num * test(num - 1);
    }
}
test(5) // 120
// 將test函數賦值給另外一個變量
var test2 = test

// 咱們再從新給test定義一個方法
var test = function() {
  return 0;
}
test2(5) // 0;
test(5) // 0
複製代碼

再看下使用callee屬性後是如何

// demo2.js
// 定義一個階乘
function test(num){
    if(num <= 1){
        return 1;
    } else {
        return num * arguments.callee(num - 1);
    }
}
test(5) // 120
// 將test函數賦值給另外一個變量
var test2 = test

// 咱們再從新給test定義一個方法
var test = function() {
  return 0;
}
test2(5) // 120;
test(5) // 0
複製代碼

demo1.js 的代碼咱們爲test從新定義了方法,原test變量的指向的指針發生了變化,因此返回從新定義方法的返回值。

this

this 引用的是函數執行的環境對象。但有些特殊的例外,如settimeout,setInterval等

caller

caller保存着調用當前函數的函數引用,若是是在全局做用域下調用,則返回null。如:

function outer() {
  inner()
}

function inner() {
  console.log(inner.caller)
}
outer();
複製代碼

以上代碼爲了實現鬆耦合,也能夠經過arguments.callee.caller來訪問。如:

function outer() {
  inner()
}

function inner() {
  console.log(arguments.callee.caller)
}
outer();
複製代碼

IE、firefox、chrome、safri 的全部版本以及opera9.6都支持caller屬性。

當函數在嚴格模式下運行時,訪問arguments.callee會致使錯誤。

ECMAScript 5 還定義了 arguments.caller 屬性,但在嚴格模式下訪問它也會致使錯誤,而在非嚴格模式下這個屬性始終是undefined。定義arguments.callee屬性是爲了分清arguments.caller和函數的caller屬性。以上變化爲了增強這門語言的安全性,這種第三方代碼不能在相同的環境裏窺視其餘代碼了。

嚴格模式還有一個限制:不能爲函數的caller屬性賦值,不然會致使錯誤。

函數的屬性和方法

屬性

length length屬性表示函數但願接收的命名參數的個數 prototype prototype 指向原型對象。包括諸如:toString()、valueof()等方法

方法

如下的方法都是改變函數的this指向的 call() call() 方法調用一個函數, 其具備一個指定的this值和分別地提供的參數(參數的列表)。 語法

fun.call(thisArg, arg1, arg2, ...)
複製代碼

參數

參數 描述
thisArg 在fun函數運行時指定的this值。
arg1, arg2, ... 指定的參數列表。

返回值 返回值是你調用的方法的返回值,若該方法沒有返回值,則返回undefined。 apply()

方法調用一個函數, 其具備一個指定的this值,以及做爲一個數組(或相似數組的對象)提供的參數。

語法

fun.call(thisArg, [argsArray])
複製代碼

參數

參數 描述
thisArg 在fun函數運行時指定的this值。
argsArray 可選的。一個數組或者類數組對象,其中的數組元素將做爲單獨的參數傳給 func 函數。

返回值 調用有指定this值和參數的函數的結果。 bind() bind()方法建立一個新的函數, 當被調用時,將其this關鍵字設置爲提供的值,在調用新函數時,在任何提供以前提供一個給定的參數序列。

語法

fun.bind(thisArg[, arg1[, arg2[, ...]]])
複製代碼

參數

參數 描述
thisArg 當綁定函數被調用時,該參數會做爲原函數運行時的 this 指向。當使用new 操做符調用綁定函數時,該參數無效。
arg1, arg2, ... 當綁定函數被調用時,這些參數將置於實參以前傳遞給被綁定的方法。

返回值 返回由指定的this值和初始化參數改造的原函數拷貝

若有侵權,請發郵箱至wk_daxiangmubu@163.com 或留言,本人會在第一時間與您聯繫,謝謝!!

關注咱們
長按二維碼關注咱們,瞭解最新前端資訊
相關文章
相關標籤/搜索