JavaScript的由於因此

  各位看官,樓主開始說過寫幾篇博客,這是這個系列的最後一集。吾覺得:瞭解JavaScript的身世之謎,掌握其近乎心想事成的變量系統,瞭解其解析運行的偷樑換柱之法,熟悉布大師迂迴曲折的OOP實現。那你離height level也不遠了。固然,要想height level還要再掌握兩個經常被各位園友掛在嘴邊的東西:this與閉包。this是什麼鬼?閉包又是什麼鬼?照本宣科的概念,這裏不說,咱們只聊「由於因此」。廢話少說,開聊!javascript

this是什麼鬼?前端

  this這玩兒稱呼爲鬼一點不爲過,好多小白一看滿屏都是this的腳本瞬間眩暈。看樣子有點像Java、C#之類的this,但憑直覺好像又超越了Java、C#的this,看得是隱隱約約、似懂非懂。各類度娘、G哥大部分獲得的都是照本宣科的解析。用心的會記下並研究的,無意的大大咧咧過目而已。因而乎,好多老鳥都沒完全搞清楚this是什麼鬼。要想了解this是什麼鬼,那得先了解這鬼是怎麼來的。java

  話說JavaScript的設計初衷是過程式的,後面布大師爲了緊跟時代潮流,迂迴曲折地實現OOP,爲此引入了this來表示實例對象。OOP是實現,可是JavaScript的世界今後多了一個this。this在應用於JavaScript的OOP時候,表示的是實例自己。可是若是我寫的JavaScript並不須要new對象,而是隨意處處寫了this,那這個時候this表明什麼?真所謂填一坑挖一坑啊!有坑得填啊,因而,布大師又想摺子給這個this賦予意義了:當this應用於OOP的時候,它表示實例自己;而當this應用於非OOP的時候則表示this所在元素的歸屬對象。這話說來講去仍是有點抽象,看代碼最實在:c++

1)當this在function中,可是funciton只是過程式函數閉包

    <script>
        /**解析:
         *test在這裏只是個過程式的函數,沒有玩OOP
         *調用test函數打印this,那這裏的this指的就是test函數的歸屬
         *而test函數是歸屬到當前Window對象上的
         * ****/
       function test(){
           console.log(this); //結果是 Window對象
       }
       test();
    </script>

2)當this在某個非實例化的對象中app

   <script>
        /**解析:
         *這裏的this被定義一個名爲f的函數中
         *f函數歸屬的是obj對象
         *結果:this表明obj對象
         * ****/
        var obj={
            a:123,
            f:function(){
                console.log(this);//結果 是obj對象
                console.log(this.a);//結果是123
            }
        };
        console.log(obj.f());//結果
    </script>

3)當this應用於OOP的玩法中函數

    <script>
        /**解析:
         *clazz是一個類的構造函數,用於建立clazz的實例對象
         *this在這裏就表示每個new出來的對象
         * ****/
        function clazz(a,b){
            this.a=a;
            this.b=b;
            this.print=function(){
                console.log(this.a+this.b);
            };
        }
        var c1=new clazz(1,1);
        c1.print(); //打印:2
        var c2=new clazz(2,2);
        c1.print(); //打印:4
    </script>

4)當this被偷樑換柱學習

    <script>
        /**解析:
         *利用call或者apply讓f函數運行期間的this指向另外一個對象
         * ****/
        var obj={
            a:123,
            f:function(){
                console.log(this);//結果 是obj對象
                console.log(this.a);//結果是 undefined
            }
        };
        //利用call或者apply讓f函數運行期間,將this換成當前window
        obj.f.call(this);
    </script>

閉包是什麼鬼?this

  我們仍是廢話少說,按套路,先了解這個所謂的閉包是怎麼來的。全世界(寫代碼的人)都知道,像c、java、c++這些言語都有一套一套嚴格的語法,特別像數據類型、函數的定義都有本身規則,不是你想怎麼寫就寫的。可是JavaScript這玩兒,被布大師設計得你想怎麼寫就怎麼寫,居然能夠函數裏面再定義函數,可見自由度之大。你再看看java、c++能這樣幹嗎?自由是自由了,可是這玩法引出了一個問題:但凡大學裏認真念過點書的鞋同都知道,函數是基於棧運行的,若是函數嵌套函數,子函數又引用了父函數裏定義的成員,當父函數已經over的時候,按常規套路,父函數出棧了,它定義的成員也應該被Over了,若是此時子函數還活着,那它引用的父函數變量又不見了,那子函數就無法用了。因而乎,布大師又不得不給這個bug作補丁,閉包這玩兒就出生了。那我們通俗給閉包來個定義吧:設計

  閉包:活着的人從死去的人那裏偷來了東西,讓那些東西不隨死去的人而消失。活着的人擁有了這些東西,這些東西的壽命也所以邊長了。這是JavaScript爲了應對天馬行空的自由度產生的bug而打的補丁!

  這好比雖然有點不雅,但也只是爲了看官便於理解,請勿介意。好,我們仍是看看代碼分析:

    <script>
        function oldMan(){
            var money=999999;// 老人的財富
            //老人有一個年輕的兒子
            return function young(){
                console.log("兒子要花老子的錢"+money+"美刀");
            }
        }
        var y=oldMan();//老人將兒子放出來以後就掛了,oldMan函數運行完成,出棧了!!
        y();//兒子開始活動了,兒子居然有老人的錢
    </script>

  看官,不知道你看了這寥寥幾十字的通俗解法,是否還對那個所謂的閉包還懷抱敬畏呢!

  

  若是你認真看這寥寥幾篇的通俗博文,我相信你對JavaScript的認識確定是另外一個階梯。固然要想在前端立足,僅僅掌握JavaScript還不足以混飯,你還得懂HTML、CSS。樓主打算接下來就這兩個知識再聊上幾篇。若有興趣,請留意!其餘JavaScript的問題,也歡迎一塊兒學習探討!

相關文章
相關標籤/搜索