<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        通過JS運行機制的角度說說作用域

        來源:懂視網 責編:小采 時間:2020-11-27 22:00:15
        文檔

        通過JS運行機制的角度說說作用域

        通過JS運行機制的角度說說作用域:前言 任何程序設計語言都有作用域的概念,簡單的說,作用域就是變量與函數的可訪問范圍。JS中的作用域、閉包、this機制和原型往往是最難理解的概念之一。筆者將通過幾篇文章和大家談談自己的理解,希望對大家的學習有一些幫助。如果有什么理解偏差的地方,希望
        推薦度:
        導讀通過JS運行機制的角度說說作用域:前言 任何程序設計語言都有作用域的概念,簡單的說,作用域就是變量與函數的可訪問范圍。JS中的作用域、閉包、this機制和原型往往是最難理解的概念之一。筆者將通過幾篇文章和大家談談自己的理解,希望對大家的學習有一些幫助。如果有什么理解偏差的地方,希望

        前言

        任何程序設計語言都有作用域的概念,簡單的說,作用域就是變量與函數的可訪問范圍。JS中的作用域、閉包、this機制和原型往往是最難理解的概念之一。筆者將通過幾篇文章和大家談談自己的理解,希望對大家的學習有一些幫助。如果有什么理解偏差的地方,希望大家可以評論指出,相互學習。

        有過一定編程經驗的同學,一定不會對作用域感到陌生,在C/C++/Java中等語言中,作用域從來沒有JavaScript中的作用域那樣令人困惑以致于成為一個大多數JS開發者都難以跨過的門檻。

        作用域形成機制

        JS中存在的三種作用域類型:全局作用域,函數作用域和ES6中新加入的塊級作用域。

        var a = 1;
        
        function foo() {
         var b = 2;
         console.log(a);	// 1
         console.log(b);	// 2
         console.log(c);	// ReferenceError
        }
        
        function foo1() {
         var c = 3;
         console.log(a);	// 1
         console.log(b);	// ReferenceError
         console.log(c);	// 3
        }
        
        console.log(a);	// 1
        console.log(b); 	// ReferenceError
        console.log(c);	// ReferenceError
        foo();
        foo1();

        從上面的例子可以看到,每個函數內部形成了屬于自己的作用域,函數內部聲明的變量僅僅在定義的函數內部才可以訪問。全局作用域中可以訪問到的有a,foo,foo作用域中可以訪問到的有b,foo,a,foo1的作用域中可以訪問到的有c,foo,a。因為foo的作用域嵌套在全局作用域之中,當console.log(a);執行的時候,JS在foo的作用域查找不到a,就會到它的上層(這里是foo的上層直接就是全局作用域)查找,發現這里聲明了一個a,將它的值打印了出來。這種從里到外的查找就是根據作用域鏈查找。foo1和foo的作用域沒有嵌套關系,所以相互隔離。

        如果函數中使用了未聲明的變量怎么辦?

        function foo() {
        	a = 2;
        }
        
        foo();
        console.log(a);	// 2

        JS引擎在foo中查找不到a的聲明,便會到它的上層(這里是全局作用域中)查找,這個時候還是沒有查找到a的聲明,在非嚴格模式下,JS引擎會在全局中自動聲明一個a,這個時候,未經聲明的變量a實際上泄漏到了全局作用域中。

        只有使用未聲明的變量才會出現變量泄漏的問題么,其實,不僅僅這種寫法會出現,更常見的也會出現在for循環和if代碼塊中也會出現。

        for(var i=1;i<10;i++) {
         console.log(i);
        }
        
        console.log(i);	// 10,	這里的i泄漏到了全局作用域中
        
        if(true) {
         var a = 2;
        }
        
        console.log(a);	// 2, 這里的a也泄漏到了全局變量之中

        如果你學習過C語言系列的語法,往往很容易感到困惑,if和for居然沒有作用域,這真是太奇怪了。這一切的問題的根源,都是由于ES6之前沒有塊級作用域導致的。所以可想而知,if包裹的代碼塊,同樣里面的聲明也是暴露出來的~

        一切問題的解決直到ES6中引入了let和const得以完美的解決。使用let和const,將可以使用塊級作用域,使得聲明變量泄漏的問題得以解決。

        for(let i=1;i<10;i++) {
         console.log(i);
        }
        
        console.log(i);	// ReferenceError
        
        if(true) {
         let a = 2;
        }
        
        console.log(a);	// ReferenceError

        聲明提升機制

        對于在JS中聲明的不論是變量還是函數,基本上都會存在著變量聲明提升的行為,將變量的聲明提升到所在作用域的頂端。ES6中的let和const不會,在未聲明之前都不可以使用。

        看看下面的代碼

        console.log(a);	// undefined
        console.log(b);	// undefined
        console.log(foo);	// Function
        console.log(foo2);	// ReferenceError
        
        function foo () {
         console.log('聲明提升了哈');
        }
        
        var a = 1;
        
        var b = function foo2() {
         console.log('不同的函數聲明方式提升的結果也不一樣哦');
        };

        JS 引擎解釋這段代碼之前首先對代碼中所有的變量進行了聲明的提升,函數聲明的提升的優先級是高于普通變量的,函數聲明會整個提升到所在作用域的頂端(但是以函數表達式方式聲明的函數不會),代碼實際上是下面這個樣子:

        function foo () {
         console.log('聲明提升了哈');
        }
        var a;
        var b;
        var foo2;
        
        console.log(a);
        console.log(b);
        console.log(foo);
        console.log(foo2);
        
        b = function foo2 () {
         console.log('不同的函數聲明方式提升的結果也不一樣哦');
        }

        靜態作用域機制(詞法作用域)

        關于JS中的作用域,需要明確的一點就是,JS中只存在靜態作用域(詞法作用域)。靜態作用域是什么意思呢?意思就是它的作用域在你寫下代碼的時候就已經確定了,和函數的調用順序無關,了解這一點。就可以對一些常見的現象進行解釋。

        var a = 2;
        function foo() {
         console.log(a);
        }
        
        var obj = {
         a: 3,
         foo: foo
        }
        
        obj.foo();	// 2

        foo中的a在代碼寫完時就確認了,指向了全局作用域中的a,一旦確定就無法更改了。同理,下面的代碼

        function foo() {
         console.log(b);	// ReferenceError
        }
        
        function foo1 () {
         var b = 1;
         foo();
        }
        
        foo1();

        這里,JS引擎在全局作用域中查找不到b,所以會拋出一個異常。所以可以明確的道理是,foo的作用域和foo1的作用域仍然是相互獨立的,不會因為調用時候的順序而更改作用域的嵌套順序,靜態作用域在代碼書寫時就已經確定無法更改了,明白這一點在分析JS代碼的時候尤為重要。

        坑外話

        變量的遮蔽效應

        在函數中定義的變量會遮蔽上層作用域中同名的變量,兩個變量互不影響。

        var a = 1;
        function foo() {
         var a = 2;
         console.log(a);	// 2
        }
        console.log(a);	// 1

        Try-Catch 中的塊級作用域

        try-catch的catch中會創建一個塊級作用域,該作用域內變量的表現同樣遵守變量的聲明提升規則。

        try {
         throw undefined;
        }catch(e) {
         a = 1;
         console.log(e);	// undefined
        }
        
        console.log(a);	// 1,	變量提升規則
        console.log(e);	// ReferenceError,catch的塊作用域中定義的變量

        隱式聲明

        以參數形式傳入的變量在函數內部實際上存在的隱式的聲明,使用時不算作未聲明的變量。

        function foo(a) {
         a = 1;
         console.log(a);
        }
        
        foo();	// 1
        console.log(a);	// ReferenceError

        本來想一篇文章寫完作用域和閉包的,想例子實在是累,就拆作兩篇吧,逃~

        總結

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        通過JS運行機制的角度說說作用域

        通過JS運行機制的角度說說作用域:前言 任何程序設計語言都有作用域的概念,簡單的說,作用域就是變量與函數的可訪問范圍。JS中的作用域、閉包、this機制和原型往往是最難理解的概念之一。筆者將通過幾篇文章和大家談談自己的理解,希望對大家的學習有一些幫助。如果有什么理解偏差的地方,希望
        推薦度:
        標簽: js 談談 機制
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲av日韩av天堂影片精品| 久久国产成人精品国产成人亚洲| 亚洲日韩中文字幕无码一区| 日韩午夜理论免费TV影院| 国产亚洲?V无码?V男人的天堂 | 99热在线观看免费| 亚洲国产精品无码久久一区二区 | 亚洲AⅤ优女AV综合久久久| 亚洲毛片av日韩av无码| 精品在线视频免费| 亚洲国产精品不卡毛片a在线| 国产亚洲精彩视频| 国产jizzjizz免费看jizz| 国产精品亚洲一区二区三区久久 | 亚洲精品中文字幕无乱码麻豆| 男人和女人高潮免费网站| 亚洲国产成人久久综合区| 美女被免费网站91色| 久久精品亚洲日本佐佐木明希| 午夜老司机永久免费看片| 亚洲国产高清在线精品一区| 思思99re66在线精品免费观看| 亚洲视频在线观看一区| 一级毛片免费在线观看网站| 成熟女人牲交片免费观看视频| 蜜桃传媒一区二区亚洲AV| 亚洲精品无码成人片在线观看| 在线观看免费黄网站| 亚洲天堂福利视频| 吃奶摸下高潮60分钟免费视频| 精品久久久久久无码免费| 亚洲av丰满熟妇在线播放| 插B内射18免费视频| 成人a毛片视频免费看| 亚洲美女激情视频| 在线观看无码的免费网站| 一级全免费视频播放| 亚洲经典在线中文字幕| 国产jizzjizz视频免费看| 一级毛片免费观看不卡的| 亚洲色丰满少妇高潮18p|