一、創(chuàng)建函數(shù)的幾種方式
1、聲明函數(shù)
最普通最標(biāo)準(zhǔn)的聲明函數(shù)方法,包括函數(shù)名及函數(shù)體。
function? fn1(){}
2、創(chuàng)建匿名函數(shù)表達(dá)式
創(chuàng)建一個(gè)變量,這個(gè)變量的內(nèi)容為一個(gè)函數(shù)
var fn1 = function(){}
注意采用這種方法創(chuàng)建的函數(shù)為匿名函數(shù),即沒有函數(shù)name
var fn1 = function (){};
3、創(chuàng)建具名函數(shù)表達(dá)式
創(chuàng)建一個(gè)變量,內(nèi)容為一個(gè)帶有名稱的函數(shù)
var fn1 = function frankName(){};
注意:具名函數(shù)表達(dá)式的函數(shù)名只能在創(chuàng)建函數(shù)內(nèi)部使用
即采用此種方法創(chuàng)建的函數(shù)在函數(shù)外層只能使用fn1不能使用frankName的函數(shù)名。frankName的命名只能在創(chuàng)建的函數(shù)內(nèi)部使用測試:
varfn1=function frankName(){
? ? console.log("in:fn1<",typeoffn1,">frankName:<",typeof frankName,">");
};
console.log("out:fn1<",typeoffn1,">frankName:<",typeof? frankName,">");
fn1();
//out:fn1< function >frankName:<undefined>//in:fn1< function >frankName:< function >
可以看到在函數(shù)外部(out)無法使用frankName的函數(shù)名,為undefined。
注意:在對(duì)象內(nèi)定義函數(shù)如var o={ fn : function (){…} },也屬于函數(shù)表達(dá)式
4、Function構(gòu)造函數(shù)
可以給Function構(gòu)造函數(shù)傳一個(gè)函數(shù)字符串,返回包含這個(gè)字符串命令的函數(shù),此種方法創(chuàng)建的是匿名函數(shù)。


5、自執(zhí)行函數(shù)
(function(){alert(1);})();
(functionfn1(){alert(1);})();
自執(zhí)行函數(shù)屬于上述的“函數(shù)表達(dá)式”,規(guī)則相同
6、其他創(chuàng)建函數(shù)的方法
當(dāng)然還有其他創(chuàng)建函數(shù)或執(zhí)行函數(shù)的方法,這里不再多說,比如采用eval,setTimeout,setInterval等非常用方法,這里不做過多介紹,屬于非標(biāo)準(zhǔn)方法,這里不做過多展開
二、函數(shù)作用域鏈的問題
問題:在函數(shù)表達(dá)式內(nèi)部能不能訪問存放當(dāng)前函數(shù)的變量?
測試1,對(duì)象內(nèi)部的函數(shù)表達(dá)式:
var o = {
?fn:function(){? ??
console.log(fn);??
}
};
o.fn();//ERROR報(bào)錯(cuò)
測試2,非對(duì)象內(nèi)部的函數(shù)表達(dá)式:
var fn = function(){? console.log(fn);};
fn();
//function (){console.log(fn);};正確
總結(jié):使用var或是非對(duì)象內(nèi)部的函數(shù)表達(dá)式內(nèi),可以訪問到存放當(dāng)前函數(shù)的變量;在對(duì)象內(nèi)部的不能訪問到。
原因也非常簡單,因?yàn)?b>函數(shù)作用域鏈的問題,采用var的是在外部創(chuàng)建了一個(gè)fn變量,函數(shù)內(nèi)部當(dāng)然可以在內(nèi)部尋找不到fn后向上冊(cè)作用域查找fn,而在創(chuàng)建對(duì)象內(nèi)部時(shí),因?yàn)闆]有在函數(shù)作用域內(nèi)創(chuàng)建fn,所以無法訪問。
三、簡單的幾個(gè)代碼片段
代碼片段一:
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());
//?The Window
代碼片段二:
var name = "The Window";
var object = {
????name : "My Object",
????getNameFunc : function(){
????var that = this;
????????return function(){
????????return that.name;
????????};
????}
};
alert(object.getNameFunc()());
//My Object
ps:匿名函數(shù)的執(zhí)行環(huán)境是window
代碼片段三:

代碼片段四:

四、閉包的注意事項(xiàng)
?由于閉包會(huì)常駐內(nèi)存,使用不當(dāng)會(huì)導(dǎo)致內(nèi)存溢出。