Function類型
每個(gè)函數(shù)都是Function類型的實(shí)例,因此函數(shù)名實(shí)際上也是一個(gè)指向函數(shù)對(duì)象的指針
一伺绽、函數(shù)的定義方法
1、函數(shù)聲明
function sum(num1,num2) {
return num1 + num2;
}
2澜掩、函數(shù)表達(dá)式定義
var sum = function(num1,num2) {
return num1 + num2;
};
3杖挣、使用Function構(gòu)造函數(shù)(不推薦使用)
二、函數(shù)沒有重載(深入理解)
function addSomeNumber(num) {
return num + 100;
}
function addSomeNumber(num) {
return num + 200;
}
var result = addSomeNumber(100); //300
后面的函數(shù)會(huì)覆蓋了前面的函數(shù)株汉,因?yàn)閷⒑瘮?shù)名想象為指針乔妈,相當(dāng)于指針指向了新的函數(shù)對(duì)象氓皱;
三、函數(shù)聲明與函數(shù)表達(dá)式的區(qū)別
alert(sum(10,10));
function sum(num1,num2) {
return num1 + num2;
}
上面的代碼完全可以正常運(yùn)行股淡。因?yàn)樵诖a開始執(zhí)行之前廷区,解析器就已經(jīng)通過一個(gè)名為函數(shù)聲明提升的過程,讀取并將函數(shù)聲明添加到執(zhí)行環(huán)境中隙轻,相當(dāng)于解析器會(huì)率先讀取函數(shù)聲明,并使其在執(zhí)行任何代碼之前可用搞监。再看一下函數(shù)表達(dá)式的例子:
alert(sum(10,10));
var sum = function(num1,num2){
return num1 + num2;
};
以上代碼會(huì)在運(yùn)行期間產(chǎn)生錯(cuò)誤镰矿,因?yàn)樵谟诤瘮?shù)位于一個(gè)初始化語句中俘种,而不是一個(gè)函數(shù)聲明。
除了什么時(shí)候可以通過變量訪問函數(shù)這一點(diǎn)區(qū)別之外苍姜,函數(shù)聲明與函數(shù)表達(dá)式的語法其實(shí)是等價(jià)的衙猪。
五、作為值得函數(shù)
因?yàn)楹瘮?shù)名本身就是變量垫释,所以函數(shù)也可以作為值來使用。請(qǐng)看下面的例子:
function createComparisonFunction(propertyName) {
return function(object1,object2) {
var value1 = object1[propertyName];
var value2 = object2[propertyName];
if(value1 < value2) {
return -1;
}
if(value1 > value2) {
return 1;
} else {
return 0;
}
};
}
六显蝌、函數(shù)內(nèi)部屬性
在函數(shù)內(nèi)部曼尊,有兩個(gè)特殊的對(duì)象:arguments和this脏嚷;
- arguments:它是一個(gè)類數(shù)組對(duì)象,包含著傳入函數(shù)中的所有參數(shù)父叙;雖然arguments的主要用途是保存函數(shù)參數(shù)高每,但這個(gè)對(duì)象還有一個(gè)名為callee的屬性,該屬性是一個(gè)指針爷怀,指向擁有這個(gè)arguments對(duì)象的函數(shù)。請(qǐng)看下面非常經(jīng)典的階乘函數(shù):
function factoria(num) {
if(num <= 1) {
return 1;
} else {
return num * factoria(num - 1);
}
}
由于這個(gè)函數(shù)的執(zhí)行與函數(shù)名factorial緊緊耦合在了一起运授,所以一旦函數(shù)名字改變了吁朦,結(jié)果就會(huì)改變渡贾,此時(shí)使用callee屬性能更好的解決這個(gè)問題。
function factoria(num) {
if(num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
- this對(duì)象:引用的是函數(shù)執(zhí)行的環(huán)境對(duì)象纺讲,看看下面的例子:
window.color = "red";
var o = { color: "blue" };
function sayColor() {
alert(this.color);
}
sayColor(); //"red"
o.sayColor = sayColor;
o.sayColor(); //"blue"
把這個(gè)函數(shù)賦給對(duì)象o并調(diào)用o.sayColor()時(shí)囤屹,this引用的是對(duì)象o,因此對(duì)this.color求值會(huì)轉(zhuǎn)換成對(duì)o.color求值乡括;
一定要記住,函數(shù)的名字僅僅是一個(gè)包含指針的變量而已诲泌。因此,即使是在不同的環(huán)境中執(zhí)行角钩,全局的sayColor()函數(shù)與o.sayColor()指向的仍然是同一個(gè)函數(shù)呻澜。
- ECMAScript5也規(guī)范化了另一個(gè)函數(shù)對(duì)象的屬性:caller。這個(gè)屬性中保存著調(diào)用當(dāng)前函數(shù)的函數(shù)的引用脊髓,如果是在全局作用域中調(diào)用當(dāng)前函數(shù)将硝,它的值為null屏镊。
function outer() {
inner();
}
function inner() {
alert(arguments.callee.caller);
}
outer();
需要注意的是當(dāng)函數(shù)在嚴(yán)格模式下運(yùn)行,訪問arguments.callee會(huì)導(dǎo)致錯(cuò)誤的而芥,并且不能為函數(shù)的caller屬性賦值;
七误辑、函數(shù)屬性和方法
- 函數(shù)的屬性:
1歌逢、length:表示函數(shù)希望接收的命名參數(shù)的個(gè)數(shù)。
2砰苍、prototype:是保存所有實(shí)例方法的真實(shí)所在阱高。 - 函數(shù)的方法:
1、apply(在其中運(yùn)行函數(shù)的作用域,參數(shù)數(shù)組)
function sum(num1,num2) {
return num1 + num2;
}
function callSum1(num1,num2) {
return sum.apply(this,arguments);
}
function callSum2(num1,num2) {
return sum.apply(this,[num1,num2]);
}
2寒屯、call(在其中運(yùn)行函數(shù)的作用域黍少,处面,,昵济,)
與apply()的區(qū)別在于其余參數(shù)都直接傳遞給函數(shù)野揪,而不是以數(shù)組的形式傳遞參數(shù);
實(shí)際上call()和apply()方法的真正強(qiáng)大之處在于能夠擴(kuò)充函數(shù)賴以運(yùn)行的作用域海铆。
window.color = "red";
var o = { color: "blue" };
function sayColor() {
alert(this.color);
}
sayColor(); //"red"
sayColor.call(window); //"red"
sayColor.call(this); //"red"
sayColor.call(o);// "blue"
3挣惰、bind():這個(gè)方法會(huì)創(chuàng)建一個(gè)函數(shù)的實(shí)例憎茂,其this值會(huì)被綁定到傳給bind()函數(shù)的值。例如:
window.color = "red";
var o = { color: "blue" };
function sayColor() {
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //"blue"