函數(shù)類型
1.函數(shù)也是對象书斜,并且函數(shù)名僅僅是指向函數(shù)的指針礼患。
var sum=function(num1,num2){
return num1+num2;
}
console.info(sum(10,20));//30
var anothersum=sum;
console.info(anothersum(10,20));//30
sum=null;
console.info(anothersum(10,20));//30
2.函數(shù)沒有重載
3.函數(shù)聲明和函數(shù)表達式的區(qū)別
在js中函數(shù)聲明會在代碼解析器一開始將函數(shù)聲明體提升到頂部執(zhí)行屋厘,因此即便調(diào)用函數(shù)語句在函數(shù)聲明之前坏逢,也不會報錯高诺。
alert(sum(10,20));//不會出錯
function sum(num1,num2){
return num1+num2;
}
而函數(shù)表達式在定義函數(shù)的時候踱讨,必須要等到代碼執(zhí)行到表達以后,才能調(diào)用此函數(shù)持偏。
alert(sum(10,20));//出錯
var sum=function(num1,num2){
return num1+num2;
}
4.作為值的函數(shù)
在js中驼卖,可以像傳遞參數(shù)一樣,將一個函數(shù)傳遞給另一個函數(shù)鸿秆,也可以將一個函數(shù)當(dāng)作另一個函數(shù)的結(jié)果返回酌畜。如下
function callSomeFunction(someFunction,someArguments){
return someFunction(someArguments);
}
var add10=function(num){
return num+10;
}
alert(callSomeFunction(add10,10));//20
function greenting(name){
return "Hello"+name;
}
alert(callSomeFunction(greenting,"tzw"));//"Hello tzw"
注意:因為函數(shù)變量是函數(shù)指針,因此在傳遞函數(shù)參數(shù)時卿叽,不需要寫圓括號桥胞。
另外,一個函數(shù)也可以當(dāng)作另一個函數(shù)的結(jié)果返回(典型的例子為創(chuàng)建一個比較函數(shù))考婴。例如如下:
function createComparisonFunction(propertyName){
return function(Oject1,Object2){
var Value1=Object1[propertyName];
var Value2=Object2[propertyName];
if(Value1<Value2){
return -1;//升序返回-1
}else if(Value1>Value2){
return 1;//降序返回1
}else{
return 0;
}
}
}
- 函數(shù)的內(nèi)部屬性
函數(shù)內(nèi)部有兩個對象:arguments和this贩虾。arguments對象是用來保存函數(shù)參數(shù),并且這個對象有一個名叫callee的屬性沥阱,該屬性是一個指針缎罢,是來指向該擁有arguments對象的函數(shù)。利用階乘函數(shù)來看:
function factorial(num){
if(num<=1){
return 1;
}else if(num>1){
return num*arguments.callee(num-1);
}
}
this是引用的是函數(shù)已執(zhí)行的環(huán)境對象,當(dāng)在網(wǎng)頁的全局作用域中調(diào)用函數(shù)的話策精,則是指windows對象舰始。
window.color="red";
var o={"color":"blue"};
function sayColor(){
console.info(this.color);//red
}
o.sayColor=sayColor;
o.sayColor();//blue
還有一個特殊的屬性:caller。這個屬性保存著調(diào)用當(dāng)前函數(shù)的函數(shù)引用咽袜。
function outer(){
inner();
}
function inner(){
console.info(inner.caller);
}
outer();
如果需要更加離散的耦合丸卷,則可以把inner替換成arguments.callee即可;
function outer(){
inner();
}
function inner(){
console.info(arguments.callee.caller);
}
outer();
- 函數(shù)的屬性和方法
函數(shù)也是對象酬蹋,所以函數(shù)也會包含屬性和方法及老。每個函數(shù)包含兩個屬性:length和prototype。length:指定義的函數(shù)所能接受的參數(shù)的個數(shù)范抓。每個函數(shù)也還有兩個非繼承而來的方法:apply()和call(),用來設(shè)置函數(shù)體內(nèi)this對象的值食铐。
apply()接受兩個參數(shù)匕垫,第一個為運行的函數(shù)的作用域,第二個參數(shù)為參數(shù)數(shù)組虐呻。
function sum(num1,num2){
return num1+num2;
}
function callsum1(num1,num2){
return sum.apply(this,arguments);//傳入arguments對象
}
function callsum2(num1,num2){
return sum.apply(this,[num1,num2]);//傳入?yún)?shù)數(shù)組
}
alert(callsum1(10,10));//20
alert(callsum2(10,10));//20
call方法同樣也是有兩個參數(shù)象泵,第一個參數(shù)為this,運行函數(shù)的作用域斟叼,第二個參數(shù)就需要將所有參數(shù)逐一列出來偶惠。
function callsum3(num1,num2){
return sum.call(this,num1,num2);//傳入?yún)?shù)
}
alert(callsum3(10,10));//20
實際上apply和call真正常用來擴充函數(shù)運行的作用域。
window.color="red";
var 0={"color":"blue"};
function sayColor(){
alert(this.color);
}
sayColor();//red
sayColor.call(this);//red
sayColor.call(window);//red
sayColor.call(o);//blue
用call和apply最大的好處在于對象與方法不需要有耦合關(guān)系朗涩,之前還需要將方法放入對象中忽孽,再調(diào)用。現(xiàn)在只需要用call和apply就可以了谢床。
另外兄一,還提供了一個bind()方法,這個方法會創(chuàng)建一個函數(shù)(方法)的實例识腿,他的this值會綁定到bind傳入的參數(shù)出革。
window.color="red";
var 0={"color":"blue"};
function sayColor(){
alert(this.color);
}
var objectSayColor=sayColor.bind(o);//this值綁定了o對象
objectSayColor();//blue