簡(jiǎn)單聊聊JavaScript中作用域與自執(zhí)行函數(shù)的使用
前言
不得不吐槽,學(xué)個(gè)JS,這個(gè)概念也太多了,但是這些概念你不懂吧,代碼你都看不懂,你都寸步難行。好吧,這又遇到了作用域方面的知識(shí)盲區(qū),然后發(fā)現(xiàn),又牽扯出了自執(zhí)行函數(shù)。那又能咋整,為了這點(diǎn)破工資,學(xué)唄。
適可而止,淺嘗輒止。
JS作用域
作用域指的是一個(gè)變量的作用范圍。我們定義的變量它只能在自己的作用域內(nèi)有效,超出了自己的作用域,變量就不起作用了。但是,JavaScript這門(mén)語(yǔ)言很活,如果你不搞懂它的作用域原理,你很可能在不知不覺(jué)中被坑了。
在JavaScript中,主要有三種作用域:
- 全局作用域:在所有函數(shù)外部定義的變量、函數(shù)和對(duì)象,可以被代碼中的所有部分訪問(wèn)。
- 函數(shù)作用域:在函數(shù)內(nèi)部定義的變量、函數(shù)和對(duì)象,只能在函數(shù)內(nèi)部訪問(wèn)。
- 塊級(jí)作用域:在塊級(jí)作用域(使用 let 或 const 關(guān)鍵字定義的變量)中定義的變量,只能在該塊內(nèi)訪問(wèn)。
下面通過(guò)不同的示例代碼來(lái)演示這幾種作用域,以便更好的理解:
// 全局作用域 var a = "global_var_a"; console.log("全局作用域中訪問(wèn):" + a); // 全局作用域中訪問(wèn):global_var_a if (true) { console.log("在判斷語(yǔ)句中訪問(wèn):" + a); // 在判斷語(yǔ)句中訪問(wèn):global_var_a } function getA() { console.log("在函數(shù)中訪問(wèn):" + a); // 在函數(shù)中訪問(wèn):global_var_a } getA() // ================================================================================== // 函數(shù)作用域 var a = "global_var_a"; console.log("全局作用域訪問(wèn):" + a); // 全局作用域訪問(wèn):global_var_a if (true) { var a = "block_var_a"; // 與全局變量同名 console.log("在判斷語(yǔ)句中訪問(wèn):" + a); // 在判斷語(yǔ)句中訪問(wèn):block_var_a } function getA() { var a = "func_var_a"; // 與全局變量同名 var b = "func_var_b"; console.log("在函數(shù)中訪問(wèn):" + a); // 在函數(shù)中訪問(wèn):func_var_a } getA() console.log("在全局作用域中訪問(wèn):" + a); // 在全局作用域中訪問(wèn):block_var_a;由于允許變量重復(fù)聲明,導(dǎo)致變量被覆蓋 console.log("在全局作用域中訪問(wèn):" + b); // Uncaught ReferenceError: b is not defined // ================================================================================== // 塊作用域 var a = "global_var_a"; const b = "global_const_b"; console.log("全局作用域中訪問(wèn):" + a); // 全局作用域中訪問(wèn):global_var_a console.log("全局作用域中訪問(wèn):" + b); // 全局作用域中訪問(wèn):global_const_b if (true) { let a = "block_let_a"; const b = "block_const_b"; console.log("在判斷語(yǔ)句中訪問(wèn):" + a); // 在判斷語(yǔ)句中訪問(wèn):block_let_a console.log("在判斷語(yǔ)句中訪問(wèn):" + b); // 在判斷語(yǔ)句中訪問(wèn):block_const_b let c = "block_let_c"; const d = "block_let_d"; } function getA() { let a = "func_let_a"; const b = "func_const_b"; console.log("在函數(shù)中訪問(wèn):" + a); // 在函數(shù)中訪問(wèn):func_let_a console.log("在函數(shù)中訪問(wèn):" + b); // 在函數(shù)中訪問(wèn):func_const_b let e = "func_let_e"; const f = "func_const_f"; } getA() console.log("全局作用域中訪問(wèn):" + a); // 全局作用域中訪問(wèn):global_var_a console.log("全局作用域中訪問(wèn):" + b); // 全局作用域中訪問(wèn):global_const_b // console.log("全局作用域中訪問(wèn):" + c); Uncaught ReferenceError: c is not defined // console.log("全局作用域中訪問(wèn):" + d); Uncaught ReferenceError: d is not defined // console.log("全局作用域中訪問(wèn):" + e); Uncaught ReferenceError: e is not defined // console.log("全局作用域中訪問(wèn):" + f); Uncaught ReferenceError: f is not defined
這里順便多說(shuō)一嘴,關(guān)于var定義變量時(shí)的變量提升問(wèn)題,看下面這段代碼:
if (false) { var a = "abc"; console.log(a); } else { console.log(a); } console.log(a);
我們執(zhí)行上面的代碼,理應(yīng)報(bào)Uncaught ReferenceError: a is not defined
這個(gè)錯(cuò)誤的,但是由于變量提升問(wèn)題,這段代碼是不會(huì)報(bào)錯(cuò)的,但是邏輯是有問(wèn)題的。
JS自執(zhí)行函數(shù)
說(shuō)完JS的作用域問(wèn)題,再來(lái)說(shuō)說(shuō)自執(zhí)行函數(shù)。它的定義如下:
自執(zhí)行函數(shù)是指定義后立即執(zhí)行的函數(shù),它可以被用來(lái)創(chuàng)建一個(gè)私有作用域。自執(zhí)行函數(shù)的作用域只在函數(shù)內(nèi)部有效,可以用來(lái)隱藏變量和函數(shù),避免全局命名沖突,保持代碼的整潔性和可維護(hù)性。它可以用來(lái)創(chuàng)建私有作用域、實(shí)現(xiàn)模塊化、簡(jiǎn)化代碼等等,非常靈活和實(shí)用。
自執(zhí)行函數(shù)有三種寫(xiě)法:
(function("參數(shù)") {"函數(shù)方法";})("給參數(shù)傳的值") (function("參數(shù)") {"函數(shù)方法";}("給參數(shù)傳的值")) !function("參數(shù)") {"函數(shù)方法";}("給參數(shù)傳的值") // ! 可以換作 void 或其他運(yùn)算符(比如 +,-,= 等,都能起到立即執(zhí)行的作用)
因?yàn)槿肿兞亢苋菀滓鹨恍〣ug,所以使用自執(zhí)行函數(shù)來(lái)實(shí)現(xiàn)模塊化,內(nèi)部變量和函數(shù)對(duì)外部不可見(jiàn),只有暴露出去的接口可以被外部訪問(wèn)??聪旅孢@段代碼。
var myModule = (function(){ var privateVar ='私有變量'; function privateFunc(){ console.log('私有函數(shù)'); } return { publicFunc: function() { console.log('公有函數(shù)'); } }; })(); myModule.publicFunc(); // "公有函數(shù)" console.log(myModule.privateVar); // undefined myModule.privateFunc(); // Uncaught TypeError: myModule.privateFunc is not a function
在上面的代碼中,自執(zhí)行函數(shù)返回一個(gè)包含公有函數(shù)publicFunc的對(duì)象,這個(gè)函數(shù)可以被外部訪問(wèn),而私有變量privateVar和私有函數(shù)privateFunc對(duì)外部不可見(jiàn)。這樣可以有效地隔離代碼,避免全局變量污染,提高代碼的可維護(hù)性和重用性。大部分開(kāi)元的JavaScript模塊就是以這種方式提供的。
到此這篇關(guān)于簡(jiǎn)單聊聊JavaScript中作用域與自執(zhí)行函數(shù)的使用的文章就介紹到這了,更多相關(guān)JavaScript作用域與自執(zhí)行函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序?qū)崿F(xiàn)的繪制table表格功能示例
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)的繪制table表格功能,涉及微信小程序數(shù)據(jù)讀取及界面布局相關(guān)操作技巧,需要的朋友可以參考下2019-04-04基于原生js實(shí)現(xiàn)判斷元素是否有指定class名
這篇文章主要介紹了基于原生js實(shí)現(xiàn)判斷元素是否有指定class名,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07微信小程序?qū)崿F(xiàn)富文本圖片寬度自適應(yīng)的方法
小程序里圖片會(huì)顯示不全,這時(shí)就應(yīng)該做相應(yīng)的處理,使小程序里圖片顯示正確,這篇文章主要介紹了微信小程序?qū)崿F(xiàn)富文本圖片寬度自適應(yīng)的方法,感興趣的小伙伴們可以參考一下2019-01-01JavaScript表單驗(yàn)證的兩種實(shí)現(xiàn)方法
這篇文章主要為大家詳細(xì)介紹了JavaScript表單驗(yàn)證的兩種實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02關(guān)于javascript的“靜態(tài)類(lèi)"
關(guān)于javascript的“靜態(tài)類(lèi)"...2006-10-10