函數(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ù)拷貝