函數是這樣的一段JavaScript代碼,她只定義一次,可是可能被執行或調用屢次。
Function類型是JavaScript提供的引用類型之一,經過Function可u需變動建立對象。
在JavaScript中,函數也是以對象形式存在的。每個函數都是一個Function對象。函數名,本質就是一個變量,是指向某個Function對象的引用。
function fn(){
console.log(‘臥龍學院’);
}
console.log (fn instanceof Function);//truejavascript
在JavaScript中,函數除了能夠經過函數定義語句或字面量變大時兩個方式意外,還能夠經過Function類型進行定義:
var add = new Function(
'num1'.
'num2',
)
注意:經過Function類型定義函數的效率遠不如經過函數定義或者字面量定義表達式兩個方式定義,目前,定義函數具備三種表達式。java
Function的apply()方法用於調用一個函數,而且接受指定的this值,以及一個數組做爲參數。其語法以下結構:
func.apply(thisarg,[argsarray])
this參數:可選項,在func函數運行時使用的this值。
argsarray參數:可選項,一個數組或者類數組對象,其中的數組元素將做爲單獨的參數傳給func函數。也可使用argumengts對象做爲該參數。
返回值調用該函數的返回結果。數組
Function的call()方法用於調用一個函數,而且接受指定的this值做爲參數,以及參數列表。
thisarg參數:在func函數運行時使用的this值。arg1 arg2 參數:指定參數列表
返回值:調用該函數的返回結果。
apply()於call()很是類似,不一樣之處在於提供參數的方法閉包
Function的bind()方法用於建立一個新的函數(稱之爲綁定函數),而且接受指定的this值做爲參數,以及參數列表。其語法結果以下:
fun。bind(thisarg[[arg[,arg[,arg2]]])
thisarg參數:當綁定函數被調用時,該參數會做爲原函數運行時的this指向,
arg1,arg2,參數。。。當綁定函數被調用時,這些參數將設置於實參以前傳遞給被綁定的方法。
返回值:返回又指定的this值和初始化參數改造的原函數拷貝。app
在其餘開發語言中,函數具備一種特性,叫作重載。所謂重載,就是定義多個同名函數,但每個函數接受的參數的個數不一樣,程序會根據調用實參個數進行判斷,具體調用的是那個函數。以下是列:
function add (a,b){
return a+b;
}
function add (a,b,c){
return a+b+c;
}
add(1,2);//3
add(1,2,3);//6
可是在JavaScript中,函數是沒有重載現象的。也就是說,若是用是定義多個同名的函數,只有最後一個定義的函數是有效的。
不過,JavaScript提供了arguments對象,該對象能夠模型函數重載的現象。arguments對象時函數內部的本地變量;argumengts以及再也不時函數的屬性了。argumengts對象能夠獲取函數的全部參數,但argumengts對象並非一個數組,而是一個類數組對象函數
在一個函數的函數體內,若是想調用自身函數的話,有以下兩種方式:
經過使用自身函數名實現。
經過使用arguments對象的callee屬性實現。
調用自身的函數被稱之爲遞歸函數。在某種意義上說,遞歸近似於循環。二者都重複執行相同的代碼,而且二者都須要一個終止條件以免無限循環或者無限遞歸。
function loop(x){
if(x>=10){ return;}
loop(x+1);
}
loop(0);
上述代碼是一個經典的遞歸函數。雖然這個函數表面看起來並無什麼問題,若是直線下述代碼可能會致使出錯。
car anotherloop = loop ;
loop = null ;
anotherLoop (0)// 出錯
上述代碼將函數loop()保存到另外一個變量anotherloop中,而後將loop設置爲null值。當執行another loop時,必定會執行函數loop(),而loop已經再也不是一個函數,最終致使出錯。
想要解決上述遞歸函數的問題,可使用arguments對象callee屬性替換具體的函數名。
function loop (x) {
if (x>=10){
return;
}
arguments.callee(x+1);
}oop
JavaScript能夠將函數做爲數據使用。做爲函數本體,它像普通的數據同樣,不必定要有名字。默認名字的函數被定之爲匿名函數。以下實例:
function(a){return a;}
匿名函數的兩種使用方法:
能夠將匿名函數做爲函數做爲參數傳遞給其餘函數。這樣,接受方函授就能利用所傳遞的函數來完成某些事情。
能夠定義某個匿名函數來執行某些一次性任務。性能
當一個函數做爲參數傳遞給另外一個函數時,做爲參數的函數被稱之爲回調函數。
function add(a,breturn a ()+b()} var one = function () {return1;}
var two = function(){return 2;}
console.log (add(one,two));//output 3}
能夠直接使用匿名函數來替代one()和two(),以做爲目標函數的參數
console。log (add(function(){return 1;}, function(return2;)))
上述代碼中。函數one()two()都做爲函數add()的參數傳遞。全部one()和two()都是回調函數。當將函數A傳遞給函數B,並由B來執行A時,A就成了一個回調函數。 若是A 仍是一個無名函數 就稱之爲匿名會點函數。 回調函數的優勢以下:
它能夠在不作命名的狀況下傳遞函數(這意味着能夠節省全局變量)。
能夠將一個函數調用操做委託給另外一個函數()這意味着能夠節省一些代碼編寫工做。
回調函數也有助於提高性能測試
所謂自掉函數就是定義函數後自行調用。以下實例:
(function(){console.log('javascript');
})();
上述代碼的含義:第一對 括號的做用,放置的時一個匿名函數。
第二隊括號的做用,時’當即調用‘。
自調函數只須要將匿名函數的定義放進一對括號中, 而後外面再跟一對括號便可。
自調函數也能夠再調用時接受參數。以下示例:
(function(name){
console.log('hello'+name+'!');
})(''jacasript);//hello javasript
上述代碼的含義以下:
當一個括號中的匿名函數接受一個參數。
第二個括號,再調用時, 像匿名函數傳遞參數內容。this
將一個函數做爲另外一個函數的結果進行返回,做爲結果返回的函數稱之爲做爲值的函數。
function fn( f,args){
return f (ars);
}
function add(num){//做爲值的函數
return num +10;
}
var result = fn(add,10);
console.log (result);//20
上述代碼還能夠編寫成以下方式:
function fn(args){
return function add(){
return args +10
}
}
上述兩段代碼的區別在於:
var f = fn(10); //function add(){return 10+10;}
var result =f()//20
不少開發語言中都具備塊級做用域,但ECMAScript5版本中並無跨級做用域,這常常會致使理解上的困惑。以下示例:
if (true){
var color= ‘blue’;
}
console。log(color);//blue
上述代碼再if語句中的定義了變量color。但該變量的做用域時全局域,緣由是ECMASript5版本中沒有塊級做用域。
雖然再ECMASript5版本沒有塊級做用域。但具備函數做用域。在某個函數內部定義的變量的做用域就是該函數的做用域。
function fun(){
var v = this is 'wolongxueyuan ';
}
console .log (v)//輸出報錯
上述代碼在函數fun內部定義了變量v ,該變量的做用域是fun函數的做用域。 因此在全局域訪問該變量時會報錯。每一段JavaScript代碼(全局代碼或函數)都有一個與值關聯的做用域鏈。 這個做用或鏈式一個對象列表或鏈表,這組對象定義了這段代碼做用域中的變量。
JavaScript容許函數嵌套,而且內部函數能夠訪問定義在外部函數中的全部變量函數,已經外部函數能訪問的全部變量和函數。可是,外部函數做用域訪問時,一個閉包就產生了。閉包就是詞法表示包括沒必要計算的變量的函數, 也就是說, 該函數能使用函數外定義的變量以下述代碼就是一個最簡單形式的閉包結構:var b ;function f(){var a=' a'};b=function(){returnn a+'b';}return a;}//測試 console.log (f());//aconsole.log(b());//ab閉包的特色局部變量;在函數中定義有貢獻意義 的局部變量。()定義成全局變量會對外形成污染內部函數:在函數(f)中聲明有內嵌函數,內嵌函數(g)對函數(f)中的局部變量進行訪問。外部使用:函數(f)向外返回詞內嵌函數(g),外部能夠經過詞內嵌函數持有並訪問聲明在函數(f) 中的局部變量,而此變量在外部時經過其餘途徑沒法訪問的。閉包做用:提供可共享的局部變量。保護貢獻的局部變量。提供專門的讀寫變量的函數。 避免全局污染