【JS第15期】Function 詳解

函數(shù)實(shí)際上是一個(gè)對(duì)象。每個(gè)函數(shù)都是Function 實(shí)例,而且都與其他引用類型一樣具有屬性和方法。由于函數(shù)也是對(duì)象,因此函數(shù)名實(shí)際上也是一個(gè)指向函數(shù)對(duì)象的指針。

函數(shù)定義方式

函數(shù)聲明

function sum(num1, num2) {
  return num1 + num2;
}

函數(shù)表達(dá)式

var sum = function(num1, num2) {
  return num1 + num2;
}

Function 構(gòu)造函數(shù)

var sum = new Function('num1', 'num2', 'return num1 + num2');

注意:使用構(gòu)造函數(shù)定義是不推薦的。因?yàn)檫@種語法會(huì)導(dǎo)致解析兩次代碼(第一次解析常規(guī)ECMAScript代碼, 第二次是解析傳入構(gòu)造函數(shù)中的字符串),從而影響性能

函數(shù)聲明與函數(shù)表達(dá)式的區(qū)別

  • 函數(shù)聲明會(huì)首先被解析器讀取,并使其在執(zhí)行任何代碼之前可以訪問。如:
console.log(sum()) // 1
function sum() {
  return 1;
}
  • 函數(shù)表達(dá)式則必須等到解析器執(zhí)行到它所在的代碼塊,才會(huì)真正被解析器執(zhí)行。如:
console.log(sum()) // sum is not a function
var sum = function () {
  return 1;
}

沒有重載

在創(chuàng)建兩個(gè)同名函數(shù)時(shí),后面的函數(shù)會(huì)覆蓋了前面的函數(shù)。如:

function sum() {
  return 1;
}
function sum() {
  return 2
}
sum() // 2;

作為值的函數(shù)

因?yàn)镋CMAScript 中函數(shù)名本身就是變量,所以函數(shù)可以作為值來使用。也就是說,不僅可以像傳遞參數(shù)一樣傳遞給另一個(gè)參數(shù),也可以將一個(gè)函數(shù)做為函數(shù)返回值返回,如下:

function test(func, arg) {
  return func(arg)
}
function test2() {
  return function() {
    console.log('test2')
  }
}

函數(shù)內(nèi)部屬性

arguments

arguments 是一個(gè)類數(shù)組的對(duì)象,返回值為函數(shù)的所有參數(shù)。這個(gè)對(duì)象還有另外一個(gè)屬性callee,該屬性是一個(gè)指針,指向arguments對(duì)象所在的函數(shù)的指針。舉例說明:

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

// 我們再重新給test定義一個(gè)方法
var test = function() {
  return 0;
}
test2(5) // 0;
test(5) // 0

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

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

// 我們再重新給test定義一個(gè)方法
var test = function() {
  return 0;
}
test2(5) // 120;
test(5) // 0

demo1.js 的代碼我們?yōu)閠est重新定義了方法,原test變量的指向的指針發(fā)生了變化,所以返回重新定義方法的返回值。

this

this 引用的是函數(shù)執(zhí)行的環(huán)境對(duì)象。但有些特殊的例外,如settimeout,setInterval等

caller

caller保存著調(diào)用當(dāng)前函數(shù)的函數(shù)引用,如果是在全局作用域下調(diào)用,則返回null。如:

function outer() {
  inner()
}

function inner() {
  console.log(inner.caller)
}
outer();

以上代碼為了實(shí)現(xiàn)松耦合,也可以通過arguments.callee.caller來訪問。如:

function outer() {
  inner()
}

function inner() {
  console.log(arguments.callee.caller)
}
outer();

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

當(dāng)函數(shù)在嚴(yán)格模式下運(yùn)行時(shí),訪問arguments.callee會(huì)導(dǎo)致錯(cuò)誤。

ECMAScript 5 還定義了 arguments.caller 屬性,但在嚴(yán)格模式下訪問它也會(huì)導(dǎo)致錯(cuò)誤,而在非嚴(yán)格模式下這個(gè)屬性始終是undefined。定義arguments.callee屬性是為了分清arguments.caller和函數(shù)的caller屬性。以上變化為了加強(qiáng)這門語言的安全性,這種第三方代碼不能在相同的環(huán)境里窺視其他代碼了。

嚴(yán)格模式還有一個(gè)限制:不能為函數(shù)的caller屬性賦值,否則會(huì)導(dǎo)致錯(cuò)誤。

函數(shù)的屬性和方法

屬性

length
length屬性表示函數(shù)希望接收的命名參數(shù)的個(gè)數(shù)
prototype
prototype 指向原型對(duì)象。包括諸如:toString()、valueof()等方法

方法

以下的方法都是改變函數(shù)的this指向的
call()
call() 方法調(diào)用一個(gè)函數(shù), 其具有一個(gè)指定的this值和分別地提供的參數(shù)(參數(shù)的列表)。
語法

fun.call(thisArg, arg1, arg2, ...)
參數(shù) 描述
thisArg 在fun函數(shù)運(yùn)行時(shí)指定的this值。
arg1, arg2, ... 指定的參數(shù)列表。

參數(shù)

參數(shù) 描述
thisArg 在fun函數(shù)運(yùn)行時(shí)指定的this值。
arg1, arg2, ... 指定的參數(shù)列表。

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

方法調(diào)用一個(gè)函數(shù), 其具有一個(gè)指定的this值,以及作為一個(gè)數(shù)組(或類似數(shù)組的對(duì)象)提供的參數(shù)。

語法

fun.call(thisArg, [argsArray])
參數(shù) 描述
thisArg 在fun函數(shù)運(yùn)行時(shí)指定的this值。
argsArray 可選的。一個(gè)數(shù)組或者類數(shù)組對(duì)象,其中的數(shù)組元素將作為單獨(dú)的參數(shù)傳給 func 函數(shù)。

參數(shù)

參數(shù) 描述
thisArg 在fun函數(shù)運(yùn)行時(shí)指定的this值。
argsArray 可選的。一個(gè)數(shù)組或者類數(shù)組對(duì)象,其中的數(shù)組元素將作為單獨(dú)的參數(shù)傳給 func 函數(shù)。

返回值
調(diào)用有指定this值和參數(shù)的函數(shù)的結(jié)果。
bind()
bind()方法創(chuàng)建一個(gè)新的函數(shù), 當(dāng)被調(diào)用時(shí),將其this關(guān)鍵字設(shè)置為提供的值,在調(diào)用新函數(shù)時(shí),在任何提供之前提供一個(gè)給定的參數(shù)序列。

語法

fun.bind(thisArg[, arg1[, arg2[, ...]]])
參數(shù) 描述
thisArg 當(dāng)綁定函數(shù)被調(diào)用時(shí),該參數(shù)會(huì)作為原函數(shù)運(yùn)行時(shí)的 this 指向。當(dāng)使用new 操作符調(diào)用綁定函數(shù)時(shí),該參數(shù)無效。
arg1, arg2, ... 當(dāng)綁定函數(shù)被調(diào)用時(shí),這些參數(shù)將置于實(shí)參之前傳遞給被綁定的方法。

參數(shù)

參數(shù) 描述
thisArg 當(dāng)綁定函數(shù)被調(diào)用時(shí),該參數(shù)會(huì)作為原函數(shù)運(yùn)行時(shí)的 this 指向。當(dāng)使用new 操作符調(diào)用綁定函數(shù)時(shí),該參數(shù)無效。
arg1, arg2, ... 當(dāng)綁定函數(shù)被調(diào)用時(shí),這些參數(shù)將置于實(shí)參之前傳遞給被綁定的方法。

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,679評(píng)論 0 4
  • 函數(shù)和對(duì)象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對(duì)于任何一門語言來說都是核心的概念。通過函數(shù)可以封裝任意多條語句,而且...
    道無虛閱讀 4,950評(píng)論 0 5
  • 第3章 基本概念 3.1 語法 3.2 關(guān)鍵字和保留字 3.3 變量 3.4 數(shù)據(jù)類型 5種簡單數(shù)據(jù)類型:Unde...
    RickCole閱讀 5,527評(píng)論 0 21
  • ??引用類型的值(對(duì)象)是引用類型的一個(gè)實(shí)例。 ??在 ECMAscript 中,引用類型是一種數(shù)據(jù)結(jié)構(gòu),用于將數(shù)...
    霜天曉閱讀 1,219評(píng)論 0 1
  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,567評(píng)論 0 13

友情鏈接更多精彩內(nèi)容