這篇文章記錄我寫在線我的簡歷過程當中學習的知識
完整代碼(暫未完成)
預覽地址javascript
英文官網html
模塊化:把對應功能放到塊裏面,這個塊能夠是文件,或者div或者別的等等github
將js分紅不一樣的幾個模塊後,而後使用文件引入,可是會出現問題:若是使用var
聲明變量,那麼就會成爲全局變量,這樣容易覆蓋.面試
在ES6以前,只有函數裏面纔有局部變量.
若是隻用花括號包起來,那麼在C++或者JAVA裏面就是局部變量,可是JS裏面會變量提高,提高到當前函數的最高地方,因此仍然是全局變量.segmentfault
因此若是想用局部變量,解決方法是把它放到一個函數中,而後當即執行,這樣這個函數內部的變量就是局部變量.也不會被相同名字的全局變量覆蓋.閉包
不加感嘆號就會語法錯誤,不會執行.因此得加一個感嘆號,取反,就會運行後面的代碼,執行後面的函數.雖然改變了返回值,可是咱們不須要返回值.因此改變了也無所謂mvc
因此接下來咱們將全部本身分離出來的單個js文件,都使用當即執行函數!function(){}.call()
包起來模塊化
ps:
ES6模塊
下面的例子都使用當即執行函數隔離做用域
若是兩個模塊之間須要交流,例如在第一個模塊上初始化,在第二個模塊上使用
window
好比兩個模塊
module1.js和module2.js都被引入一個html文件裏
//module1.js !function(){ var person = window.person = { name:"frank", } //局部變量person和全局變量person用的是同一個地址 }.call()
雖然不一樣變量,可是是一樣的地址
//module2.js !function(){ var person = person;//即var person = window.person; console.log(person); }.call();
這樣不一樣模塊間就能夠通訊,但這種方法很差.
始終不知道person的所有信息
,只能知道age的信息,且只能作一些它容許你操做的事情,這樣module1就會對局部變量person有一個掌控.不會出現有人把person變成-1的狀況,由於他訪問不到age,他只能去GrowUp,除此以外沒有能訪問到的方法.
//module1.js !function(){ var person = { name:"mataotao", age:18, }; window.mataotaoGrowUp = function(){ person.age+=1; return person.age; }; }.call();
//module2.js !function(){ var newAge = window.mataotaoGrowUp(); console.log(newAge);//19 }.call();
閉包在哪裏?
若是一個函數訪問了函數外的變量(mataotaoGrowUp()
使用了person.age
),那麼 函數+函數外的變量,就是 閉包.
閉包做用:
若是沒有當即執行函數來模塊化,那麼這個閉包毫無心義,由於person直接使全局變量,全部的函數均可以訪問到,而且修改也沒法隱藏數據細節
當即執行函數+閉包 實現對象細節的封裝的方法
面試官會將上面的module1作以下修改(實際本質不變)
//module1.js var accessor = function(){//這是一個返回了匿名函數的函數,accessor-訪問器 var person = { name:"mataotao", age:18, }; return function(){ person.age+=1; return person.age; }; } var growUp = accessor();//執行accessor獲得一個GrowUp函數 //growUp如今是一個全局變量了 growUp();
實際growUp()
就至關於當即執行了,由於我聲明瞭一個函數,並且當即執行了
這就是閉包
例如在<script src="./js/init_Swiper.js"></script><!-- 初始化Swiper>標籤 -->
這個模塊中咱們初始化了一個Swiper
這個而且對.swiper-container
這個div進行操做,.swiper-container
這個div就是 VIEW(用戶能夠看到的東西).
這個div就是init-swiper這個模塊的view.
明白這個以後咱們將view單獨分離出來
也將剩下的幾個js模塊進行修改
例如<script src="./js/sticky-navbar.js"></script>
view就是要告訴js,html中的哪一塊是我要操做的東西
MVC中的C用來控制/操做view
以topNavBar爲例
將要作的操做寫成controller函數,並把要操做的view當作參數傳進去,實現對view的控制/操做
進一步的改進:
須要注意:
controller.init(view);//至關於controller.init.call(controller,view);//this就是當前對象
this.bindEvents();//至關於this.bindEventS.call(this)
,這裏的this就是init函數裏call的controller,因此這個this是轉過來了,也是對象自己若是咱們要作其餘的事情,好比把激活和不激活這個導航分離,不要寫在bindEvents裏了,繼續在對象裏添加操做的函數bind(this)
後,就是把controller綁定到這個函數的this
上,把這個函數的this
由window變成controller,以後this.active();
和this.deactive();
這兩個this
就變成了controller了
bind
方法用於將函數體內的this
綁定到某個對象,而後返回一個新函數。
bind()使用方法
這裏的bind()
就是將函數體內的this
綁定到了controller,函數體內的this
就是controller了
若是不用bind()
也能夠用箭頭函數()=>{}
,箭頭函數自己是沒有this的.因此若是在箭頭函數用this
,那麼就是箭頭函數外面的離它最近的this
!
原本:
修改後:
修改以後的先後對比
結構很是清晰有條理,將整個要作的事層次分明得分爲幾個部分
這樣代碼就不會顯得混亂了,controller對view的操做被有條理地分開,有初始化view,綁定view事件,激活這個view,不激活這個view等等對view的操做
controller全部的屬性就是對view的全部操做!!!這就是mvc裏的c的意義