摘要:函數(shù)作用域雖然不存在真正意義上的塊級作用域,但是存在函數(shù)作用域,為了解決上述偽塊級作用域的問題,使用函數(shù)解決法如下結(jié)果為結(jié)果為注意以上生成函數(shù)作用域的寫法存在兩個(gè)問題,第一申明了全局的具名函數(shù),污染了全局作用域。
ES5和ES6作用域 ES5的塊級作用域 ES5的塊級作用域是一個(gè)偽塊級作用域,代碼塊:{},它的塊里面和塊外面都是共用一個(gè)作用域,即:
Example:
{ var a =3; console.log(a); //結(jié)果為3 } console.log(a); //結(jié)果為3
Example:
ES5的偽塊級作用域另外一個(gè)典型的例子如下:
var a = []; for(var i=0;i<10;i++){ a.push(function(){ console.log(i); }); } a[0](); //預(yù)期結(jié)果是0,實(shí)際結(jié)果是10
注意:出現(xiàn)上述現(xiàn)象的主要原因是使用var定義的變量 i 是一個(gè)全局變量,導(dǎo)致真正在調(diào)用的時(shí)候雖然循環(huán)了10次,可是最終十次都是只修改了全局變量 i ,并沒有區(qū)分出私有作用域。與之相反的兩個(gè)例子如下:
Example1: 這個(gè)是利用ES6的let申明的變量會限制在當(dāng)前塊級作用域內(nèi),每次重新申明了變量,申明了10次
var a =[]; for(let i=0;i<10;i++){ a.push(function(){ console.log(i); }); } a[0](); //結(jié)果為10
Example2: 這個(gè)是利用構(gòu)建閉包來生成私有作用域
var a = []; for(var i=0;i<10;i++){ a.push((function($i){//$i是該匿名函數(shù)的入?yún)?,等同下面的i function k(){ console.log($i); } return k; })(i)); } a[0](); //結(jié)果為0
注意:如果上面的Example2不使用參數(shù)傳遞的方式創(chuàng)建私有作用域,那也可以內(nèi)部定義變量的方式來代替,值得注意的是如果是直接引用外部變量創(chuàng)建的結(jié)果最終是一個(gè)空作用域,并不能達(dá)到隔變量 i 的效果
Example3:錯(cuò)誤例子
var a = []; for(var i=0;i<10;i++){ a.push((function(){//$i是該匿名函數(shù)的入?yún)?,等同下面的i function k(){ console.log(i); } return k; })()); } a[0](); //結(jié)果為10ES5中的塊級作用域有效的只有try catch,如:
Example:
try{ throw 3; }catch(e){ console.log(e); //結(jié)果為3 } console.log(e); //結(jié)果為ReferenceError
注意:正因?yàn)閠ry catch有如上的功能,所以有時(shí)候有些框架為了區(qū)分塊級 私有 作用域就是用它來解決的,例如google的Traceur項(xiàng)目。
綜上所述:ES5偽塊級作用域的問題是沒有創(chuàng)建私有作用域,污染了它的父級甚至可能是全局作用域覆蓋window對象的原生方法或?qū)傩浴?/p> ES5函數(shù)作用域
ES5雖然不存在真正意義上的塊級作用域,但是存在函數(shù)作用域,為了解決上述ES5偽塊級作用域的問題,使用函數(shù)解決法如下:
Exapmle1
var a = 1; function fun(){ var a = 5; console.log(a); //結(jié)果為5 } fun(); console.log(a); //結(jié)果為1
注意:以上生成函數(shù)作用域的寫法存在兩個(gè)問題,第一:申明了全局的具名函數(shù)fun,污染了全局作用域。第二:如果要實(shí)現(xiàn)這個(gè)私有作用域,必須要函數(shù)調(diào)用才行。
Example2:改良上述兩個(gè)問題的寫法如下:
var a = 1; (function (){ var a =5; console.log(a); //結(jié)果為5 })(); console.log(a); //結(jié)果為1
注意:例子2的寫法在JS社區(qū)規(guī)定的術(shù)語是立即執(zhí)行函數(shù)表達(dá)式——IIFE,它可以無傷地創(chuàng)建一個(gè)塊級私有作用域替代ES5的偽塊級作用域,還有雖然它般用和閉包結(jié)合使用,但注意和閉包的區(qū)分。
立即執(zhí)行函數(shù)表達(dá)式另一個(gè)常用技巧倒置立即執(zhí)行函數(shù)代碼的運(yùn)行順序,將需要運(yùn)行的函數(shù)放在第二位,在立即執(zhí)行函數(shù)執(zhí)行之后當(dāng)作參數(shù)傳遞進(jìn)去。這種模式在UMD(Universal Module Definition)項(xiàng)目中被廣泛使用。
Example
var a=2; (function IIFE( def ){ def( window ); })(function def( global ) { var a=3; console.log( a ); // 3 console.log(global.a); //2 });
代碼解讀:例子中將代碼主體放在了立即執(zhí)行函數(shù)的參數(shù)部分,當(dāng)做參數(shù)傳遞給執(zhí)行函數(shù),執(zhí)行函數(shù)的內(nèi)部又立即調(diào)用了這個(gè)函數(shù),并將全局的window對象當(dāng)做參數(shù)傳遞給參數(shù)主體函數(shù),并匿名window為global來調(diào)動(dòng)全局a變量,達(dá)到不會與參數(shù)主體函數(shù)的作用域沖突。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/83985.html
摘要:允許在塊級作用域內(nèi)聲明函數(shù)。上面代碼中,存在全局變量,但是塊級作用域內(nèi)又聲明了一個(gè)局部變量,導(dǎo)致后者綁定這個(gè)塊級作用域,所以在聲明變量前,對賦值會報(bào)錯(cuò)。 ES5的作用域 變量起作用的范圍,js中能創(chuàng)建作用域的只能是函數(shù) { let a = 1; var b = 2; } console.log(a); // a is not defined console.log(b); //...
摘要:和數(shù)組遍歷方法詳解在中常用的種數(shù)組遍歷方法原始的循環(huán)語句數(shù)組對象內(nèi)置方法數(shù)組對象內(nèi)置方法數(shù)組對象內(nèi)置方法數(shù)組對象內(nèi)置方法數(shù)組對象內(nèi)置方法數(shù)組對象內(nèi)置方法數(shù)組對象內(nèi)置方法數(shù)組對象內(nèi)置方法循環(huán)語句中新增加了一種循環(huán)語句三種數(shù)組循環(huán)示例如下原始循 ES5和ES6數(shù)組遍歷方法詳解 在ES5中常用的10種數(shù)組遍歷方法: 1、原始的for循環(huán)語句2、Array.prototype.forEach數(shù)...
摘要:不同的是函數(shù)體并不會再被提升至函數(shù)作用域頭部,而僅會被提升到塊級作用域頭部避免全局變量在計(jì)算機(jī)編程中,全局變量指的是在所有作用域中都能訪問的變量。 ES6 變量作用域與提升:變量的生命周期詳解從屬于筆者的現(xiàn)代 JavaScript 開發(fā):語法基礎(chǔ)與實(shí)踐技巧系列文章。本文詳細(xì)討論了 JavaScript 中作用域、執(zhí)行上下文、不同作用域下變量提升與函數(shù)提升的表現(xiàn)、頂層對象以及如何避免創(chuàng)建...
摘要:命令用于規(guī)定模塊的對外接口,命令用于輸入其他模塊提供的功能所以在一定程度上來說,也具有聲明變量的功能。當(dāng)沒有聲明,直接給變量賦值時(shí),會隱式地給變量聲明,此時(shí)這個(gè)變量作為全局變量存在。 前言 如果文章中有出現(xiàn)紕漏、錯(cuò)誤之處,還請看到的小伙伴多多指教,先行謝過 在ES5階段,JavaScript 使用 var 和 function 來聲明變量, ES6 中又添加了let、const、imp...
摘要:使用或調(diào)用由于已經(jīng)在詞法層面完成了綁定,通過或方法調(diào)用一個(gè)函數(shù)時(shí),只是傳入了參數(shù)而已,對并沒有什么影響箭頭函數(shù)不會在其內(nèi)部暴露出參數(shù)等等,都不會指向箭頭函數(shù)的,而是指向了箭頭函數(shù)所在作用域的一個(gè)名為的值如果有的話,否則,就是。 ES6之箭頭函數(shù) 標(biāo)簽(空格分隔): 未分類 返回值 單行函數(shù)體默認(rèn)返回改行計(jì)算結(jié)果, 多行需要指定返回值 let c = (a,b)=>a+b; conso...
閱讀 3527·2023-04-25 14:57
閱讀 2574·2021-11-22 14:56
閱讀 2097·2021-09-29 09:45
閱讀 1779·2021-09-22 15:53
閱讀 3327·2021-08-25 09:41
閱讀 908·2019-08-29 15:22
閱讀 3307·2019-08-29 13:22
閱讀 3132·2019-08-29 13:08