背景
ES6中新增let/const关键字可以用来定义块级作用域变量,相比var拥有更好的封闭作用域。但是在实际开发中,经常出现使用let/const定义变量后,变量却被全局暴露的情况,这种情况不仅会出现变量污染的问题,还会导致程序的错误。
问题分析
- 在顶层作用域使用let/const定义变量,会将变量挂载到window对象上,具有全局作用域。
- 在for循环中使用let定义变量,每次循环都会生成新的块级作用域,但是在循环内使用的函数依然拥有外层函数的作用域,所以变量仍有可能被暴露出去。
-- -------------------- ---- ------- -------- ----- - --- ---- - - -- - - -- ---- - ----- ------- - -- -- --------------- ------------------- ------ - - ------ -- -------------------- -- ------------------ - -------------------- - -------------- -- -------- ----- - --- ---- - - -- - - -- ---- - --------- ------- - ----- ------- - -- -- ------------------- ------------------- ------ ------ - - ------ -- -- -- -- -- -
- ES6模块化中import语句只在模块作用域内有效,但是如果使用let/const定义变量并没有像var一样挂载到全局上,反而变量不能被全局访问,需要使用export导出后才能被其他模块访问。
-- -------------------- ---- ------- -- ------ ------ ----- --------- - --- ------ -------- --------------------- - --- --------- - --- ------ ----- - -- - -- ------ ------ - ---------- -------------- - ---- ----------- ----------------------- -- -- -------------------------- -- -------------
解决方案
- 使用IIFE将块级作用域隔离开来,不要使用let/const定义全局变量。
- 模块化开发中使用export导出变量,避免使用let/const在全局暴露变量。
-- -------------------- ---- ------- --------- -- - --- ------ - --------- -------- ----- - -------------------- - --------------- - - --- -- ----- --------------- -- ------ -- - --- -------------- -- -- ------ ------ ----- --------- - --- ------ -------- --------------------- - --- --------- - --- ------ ----- - -- - -- ------ ------ - ---------- -------------- - ---- ----------- ----------------------- -- -- -------------------------- -- --
总结
使用let/const定义变量使得代码更具可读性和可维护性。但是在使用let/const定义变量时,需要注意变量的作用域,避免出现全局污染的问题。使用IIFE将块级作用域隔离开来防止变量的全局暴露。在模块化开发中使用export导出变量,只允许在模块内部访问,避免使用let/const在全局暴露变量。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64755777968c7c53b026bc29