各位看官,樓主開始說過寫幾篇博客,這是這個系列的最後一集。吾覺得:瞭解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的問題,也歡迎一塊兒學習探討!