js閉包用法實(shí)例詳解
本文實(shí)例講述了js閉包用法。分享給大家供大家參考,具體如下:
引言
在公司中需要寫一個(gè)js腳本來(lái)進(jìn)行網(wǎng)站的統(tǒng)計(jì),實(shí)現(xiàn)類似百度統(tǒng)計(jì)或者站長(zhǎng)統(tǒng)計(jì)的功能,在實(shí)現(xiàn)的過(guò)程中自己感覺(jué)寫的代碼還是可以的,因?yàn)橹暗膉s代碼都是這些寫,但是在組長(zhǎng)代碼走查的時(shí)候卻非常的不滿意,因?yàn)槲覀冊(cè)趈s中寫的方法都是全局的方法,因?yàn)槲覀儗懙臇|西需要嵌入到別人的界面中,所以這些全局的東西很可能會(huì)和別人的東西重名從而引發(fā)錯(cuò)誤,所以說(shuō)組長(zhǎng)就給我留下一句話:用js閉包包起來(lái)。
變量作用域
我們都非常的熟悉變量的作用域就分為:全局變量和局部變量。js中在函數(shù)的內(nèi)部可以直接讀取全局變量。
Js代碼
var n=999;
function f1(){
alert(n);
}
f1(); // 999
另一方面,在函數(shù)外部自然無(wú)法讀取函數(shù)內(nèi)的局部變量。
Js代碼
function f1(){
var n=999;
}
alert(n); // error
我們還需要注意,在js中如果聲明變量的時(shí)候一定要用var命令,否則實(shí)際上聲明了一個(gè)全局的變量!
function f1(){
n=999;
}
f1();
alert(n); // 999
如何從外部讀取全局變量?
我們需要得到函數(shù)內(nèi)部的全局變量該怎么辦呢?。在正常情況下我們是做不到的,要想這么實(shí)現(xiàn)我們必須想一些辦法——在函數(shù)的內(nèi)部在定義一個(gè)函數(shù):
function f1(){
n=999;
function f2(){
alert(n); // 999
}
}
在上面的代碼中,函數(shù)f2就被包括在函數(shù)f1內(nèi)部,這時(shí)f1內(nèi)部的所有局部變量,對(duì)f2都是可見(jiàn)的。但是反過(guò)來(lái)就不行,f2內(nèi)部的局部變量,對(duì)f1 就是不可見(jiàn)的。這就是JavaScript語(yǔ)言特有的“鏈?zhǔn)阶饔糜颉苯Y(jié)構(gòu)(chain scope),子對(duì)象會(huì)一級(jí)一級(jí)地向上尋找所有父對(duì)象的變量。所以,父對(duì)象的所有變量,對(duì)子對(duì)象都是可見(jiàn)的,反之則不成立。
既然f2可以讀取f1中的局部變量,那么只要把f2作為返回值,我們不就可以在f1外部讀取它的內(nèi)部變量了嗎!
function f1(){
n=999;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
閉包的概念
在上面的代碼中f2函數(shù),就是閉包。各種專業(yè)文獻(xiàn)上的“閉包”(closure)定義非常抽象,很難看懂。我的理解是,閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。由于在Javascript語(yǔ)言中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此可以把閉包簡(jiǎn)單理解成“定義在一個(gè)函數(shù)內(nèi)部的函數(shù)”。所以,在本質(zhì)上,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來(lái)的一座橋梁。
下面來(lái)分享一下我們?cè)陧?xiàng)目中用到的js閉包的寫法:
(function () {
function getPageTitle() {
return document.title;
}
function getBrowerLanguage() {
var browerLanguage = !navigator.browserLanguage ? navigator.language : navigator.browserLanguage;
return browerLanguage;
}
/**
* 當(dāng)前頁(yè)面地址#后的部分
*/
function getLastUrl() {
var url = window.location.hash;
if (!url) {
return null;
}
else {
return url.toString().split("#")[1];
}
}
function GetRandomNum() {
var arr = document.cookie.match(new RegExp("(^| )" + "statisticssCookie=([^;]*)(;|$)"));
if (arr != null) {
return arr[2];
} else {
var tempRandomNum = guid();
document.cookie = "statisticssCookie = " + tempRandomNum;
return tempRandomNum;
}
}
function guid() {
function S4() {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
}
function addJs() {
var url = "http://localhost:10086/tongji/tongji/do?title=" + getPageTitle() + "&browerLanguage=" + getBrowerLanguage() + "&lastUrl=" + getLastUrl() + "&upFlag=" + GetRandomNum();
var head = document.getElementsByTagName('head')[0];
var js = document.createElement('script');
js.type = 'text/javascript';
js.src = url;
head.appendChild(js);
}
window.statistics = addJs;//將addJs這個(gè)方法掛在window下面,這樣在外界是可以訪問(wèn)的,否則外界永不能訪問(wèn)到我寫的方法
document.ready = addJs();//DOM樹加載完成后執(zhí)行
})(window)
小結(jié)
在開始的時(shí)候組長(zhǎng)就問(wèn)我會(huì)不會(huì)js閉包函數(shù),因?yàn)槿绻粫?huì)閉包寫不出很好的代碼。寫的代碼都非常的粗糙,所以說(shuō)我們?cè)趯懘a的時(shí)候,不能僅僅滿足功能實(shí)現(xiàn),而且需要考慮一些其他方面的東西。當(dāng)然js閉包在使用的時(shí)候也有一些弊端,所以我們?cè)谑褂玫臅r(shí)候也需要綜合全面的信息考慮。
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》、《JavaScript切換特效與技巧總結(jié)》、《JavaScript查找算法技巧總結(jié)》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》及《JavaScript遍歷算法與技巧總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
相關(guān)文章
關(guān)于ES6新特性最常用的知識(shí)點(diǎn)匯總
日常開發(fā)中寫的 JavaScript 代碼,會(huì)用到ES6的部分新特性,所以下面這篇文章主要給大家介紹了關(guān)于ES6新特性最常用的知識(shí)點(diǎn),文章總結(jié)的非常全面,需要的朋友可以參考下2021-11-11
JavaScript中所有聲明變量的方式及特性總結(jié)
在JavaScript中,變量的定義是編程的基礎(chǔ),而JavaScript提供了多種靈活的方式來(lái)定義變量,本文將詳細(xì)盤點(diǎn)JavaScript中所有變量定義的方式,并結(jié)合代碼示例進(jìn)行說(shuō)明,需要的朋友可以參考下2025-01-01
HTML+CSS+JavaScript實(shí)現(xiàn)可拖拽模態(tài)框
這篇文章主要為大家詳細(xì)介紹了HTML+CSS+JavaScript實(shí)現(xiàn)可拖拽模態(tài)框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
JavaScript1.6數(shù)組新特性介紹以及JQuery的幾個(gè)工具方法
這篇文章主要是對(duì)JavaScript1.6數(shù)組新特性以及JQuery的幾個(gè)工具方法進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-12-12
js離開或刷新頁(yè)面檢測(cè)(且兼容FF,IE,Chrome)
這篇文章主要介紹了js離開或刷新頁(yè)面檢測(cè)(且兼容FF,IE,Chrome)。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-03-03
JavaScript制作頁(yè)面倒計(jì)時(shí)器的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了JavaScript制作頁(yè)面倒計(jì)時(shí)器的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03
微信小程序?qū)崿F(xiàn)上傳圖片裁剪圖片過(guò)程解析
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)上傳圖片裁剪圖片過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
JS中使用 after 偽類清除浮動(dòng)實(shí)例
這篇文章主要介紹了使用 after 偽類清除浮動(dòng)實(shí)例,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下2017-03-03

