前端這幾年發展太快了,我學習的速度都跟不上演變的速度了(門派太多了,後臺都是大牛公司支撐相似於facebook的react、google的angular,angular的1.0還沒怎麼用過項目,網上查閱2.0的正式版就要出來,書寫方法大改,思惟架構都有很大的改變,真是難爲了如今的前端)。2010年第一次接觸前端js,仍是從asp.net拖控件中接觸,再接着就是我大學那個時代最出名的傳智播客視頻教學,那個時候課餘時間全去看這個視頻了,對着教學一個一個的敲,依稀的記得好定義了好多function,如今想一想仍是頗有趣,心想反正就幾個方法也不會重複。javascript
隨着前端的代碼越寫越多(本身偶爾會和朋友一塊兒接點外包或幫老師作點項目,畢竟學了不用,永遠也只是紙上談兵),發現本身詞窮了,本身定義的function名稱太多了(方法重名但是會覆蓋以前的方法),這個時候怎麼辦了,在學校最好一點是什麼,就是幾乎每一個學校都有圖書館,你都能找到本身想要的書籍,由於我自己大學主專業是學習C#的,js這種弱類型語言不停的寫function太不美觀了(自黑一下,其實我是讓人討人厭的處女座),圖書館有不少js設計模式的書籍,js高級編程,寫的都很不錯,到如今項目中也都沒有徹底的用到,有些可能用到了吧,但是都不記得這些專業術語名詞(如今什麼設計模式,什麼新技術的縮寫名詞太多了,有些雖然用過,可就是就不住。記不住又不行,有些面試官就是喜歡問,不知道你可就慘了,有些更好笑的是考官在網上現查的,而後當即來問你,'哈哈,其實我也作過這種事')。雖然我是一個大懶人但是看多了,至少也是會記住一兩個,用Function的prototype和arguments去搞面向對象仍是頗有趣的,由於是弱類型,因此不少寫法更靈活。若是你想說你更懶,那你就Object裏面定義一大頓方法也行,其實這種寫法在如今也是很流行,好比咱們經常使用的工具類。css
好的程序員不是一我的獨自敲代碼,閉門造車,咱們多去查看新技術、新框架、新組建(不過這也確實難爲不少人,畢竟互聯網是一個多姿多彩的世界。幸虧隨着時代的進步,咱們看書學技術的途徑也愈來愈多了,剛開始我關注過一些有趣技術網站的qq帳號,天天均可以在咱們逛QQ空間的時候,看到幾條頗有趣翻譯的外國技術分享文章,再後來有朋友推薦我去看各大公司技術論壇網站,不過這個沒看多久,太多了,好壞難分,重疊的太多了。移動互聯網發展愈來愈快,微信火得一塌糊塗,幾個微信前端公共帳號仍是不錯的,天天都會推薦一篇不錯的文章,公共號爲’前端早讀課‘,’前端大全‘),我的認爲好的程序員都應該有拿來主義和創新精神,因此咱們引用的框架愈來愈多,好多框架都是一個js文件,它們都怕本身的代碼被污染,因此大多數用到了閉包,那什麼是閉包了,閉包有什麼好處呢,網上有好多,在這裏我也囉嗦幾句。html
閉包的好處:前端
1. 邏輯連續,當閉包做爲另外一個函數調用的參數時,避免你脫離當前邏輯而單獨編寫額外邏輯。
2. 方便調用上下文的局部變量。
3. 增強封裝性,第2點的延伸,能夠達到對變量的保護做用。java
閉包的壞處:node
閉包有一個很是嚴重的問題,那就是內存浪費問題,這個內存浪費不只僅由於它常駐內存,更重要的是,對閉包的使用不當會形成無效內存的產生。react
優化注意:jquery
1)因爲閉包會使得函數中的變量都被保存在內存中,內存消耗很大,因此不能濫用閉包,不然會形成網頁的性能問題,在IE中可能致使內存泄露。解決方法是,在退出函數以前,將不使用的局部變量所有刪除。
2)閉包會在父函數外部,改變父函數內部變量的值。因此,若是你把父函數看成對象(object)使用,把閉包看成它的公用方法(Public Method),把內部變量看成它的私有屬性(private value),這時必定要當心,不要隨便webpack
只要你搞前端,或者搞web幾乎都有人問你,概率幾乎達到80%,這個時候推薦一篇博客(深刻理解JavaScript系列(2):揭祕命名函數表達式),這但是湯姆大叔,自己很是的佩服他,他寫的js設計模式和js注意事項確實不錯,就在博客園中,也很感謝這些人在博客園中,咱們大學生活才更幸福。git
Extjs或sencha touch這兩個都是同一家公司的,也是我用到的最先的前端模塊化和MVC,sencha touch我用的也是最多的,由於移動端畢竟火爆。
說的它的好處吧:
1.靈活架構,焦點分離
2.方便模塊間組合、分解
3.方便單個模塊功能調試、升級
4.多人協做互不干擾
mvc是後端說的最多的術語,若是你如今還不懂你最好快點去惡補下,由於如今不少形形色色的前端MVC層出不窮,
MVC開始是存在於桌面程序中的,M是指業務模型,V是指用戶界面,C則是控制器,使用MVC的目的是將M和V的實現代碼分離,從而使同一個程序可使用不一樣的表現形式。好比一批統計數據能夠分別用柱狀圖、餅圖來表示。C存在的目的則是確保M和V的同步,一旦M改變,V應該同步更新。
MVC 是一種使用 MVC(Model View Controller 模型-視圖-控制器)設計建立 Web 應用程序的模式:
Model(模型)表示應用程序核心(好比數據庫記錄列表)。
View(視圖)顯示數據(數據庫記錄)。
Controller(控制器)處理輸入(寫入數據庫記錄)。
MVC 模式同時提供了對 HTML、CSS 和 JavaScript 的徹底控制。
Model(模型)是應用程序中用於處理應用程序數據邏輯的部分。
一般模型對象負責在數據庫中存取數據。
View(視圖)是應用程序中處理數據顯示的部分。
一般視圖是依據模型數據建立的。
Controller(控制器)是應用程序中處理用戶交互的部分。
一般控制器負責從視圖讀取數據,控制用戶輸入,並向模型發送數據。
MVC 分層有助於管理複雜的應用程序,由於您能夠在一個時間內專門關注一個方面。例如,您能夠在不依賴業務邏輯的狀況下專一於視圖設計。同時也讓應用程序的測試更加容易。
MVC 分層同時也簡化了分組開發。不一樣的開發人員可同時開發視圖、控制器邏輯和業務邏輯。
囉嗦一點說一下sencha這家js框架公司的好處和弊端吧,他們提供的框架有很好的樣式體系,基於sass寫的,能夠隨便咱們改變樣式風格,提供的sencha.cmd第一次讓我感受到了前端的工程化,提供了代碼的壓縮、代碼驗證、代碼模塊的依賴合併。組件豐富,說了這麼多你們感受必定很爽吧。可是因爲他提供很是多的組件,因此致使js代碼過多,雖然有些咱們能夠自行配置篩選壓縮,它的依賴壓縮不是所有根據配置,大部門和文件夾裏面的文件有關,必須不停的移除或添加,反正就是很麻煩,特別是版本的升級時候,真是想吐了。有時由於壓縮的緣故還會報一些下錯。
說來前面的大框架咱們必定想用到更加輕便的模塊框架了,這個時候必定要說說兩派的表明框架RequireJS和SeaJs,引用一下github上的專業術語吧,我的也通過一段時間的驗證。
RequireJS 和 Sea.js 都是模塊加載器,倡導模塊化開發理念,核心價值是讓 JavaScript 的模塊化開發變得簡單天然。
二者的主要區別以下:
定位有差別。RequireJS 想成爲瀏覽器端的模塊加載器,同時也想成爲 Rhino / Node 等環境的模塊加載器。Sea.js 則專一於 Web 瀏覽器端,同時經過 Node 擴展的方式能夠很方便跑在 Node 環境中。
遵循的規範不一樣。RequireJS 遵循 AMD(異步模塊定義)規範,Sea.js 遵循 CMD (通用模塊定義)規範。規範的不一樣,致使了二者 API 不一樣。Sea.js 更貼近 CommonJS Modules/1.1 和 Node Modules 規範。
推廣理念有差別。RequireJS 在嘗試讓第三方類庫修改自身來支持 RequireJS,目前只有少數社區採納。Sea.js 不強推,採用自主封裝的方式來「海納百川」,目前已有較成熟的封裝策略。
對開發調試的支持有差別。Sea.js 很是關注代碼的開發調試,有 nocache、debug 等用於調試的插件。RequireJS 無這方面的明顯支持。
插件機制不一樣。RequireJS 採起的是在源碼中預留接口的形式,插件類型比較單一。Sea.js 採起的是通用事件機制,插件類型更豐富。
總之,若是說 RequireJS 是 Prototype 類庫的話,則 Sea.js 致力於成爲 jQuery 類庫。
Seajs我沒怎麼用過項目,因此也就不說了,RequireJS 用過,那時候用的.net的mvc5.0中的一個第三方插件,幫我省去了不少的配置文件,由於若是咱們用nodejs的話通常要本身書寫R.js,用來配置一些處理流程,強大的.net插件幫我省去了好多,但是每一個模塊你都的定義,而且在配置文件中書寫出來,每一個模塊都要寫初始模塊定義,爲何我會這麼去說話一個框架了,由於不斷的學習用到了更好的webpack,如下是個人觀點(有些解釋術語參考了其它博客)
說說一下webpack的優勢吧:
1.require.js的全部功能它都有
2.編繹過程更快,由於require.js會去處理不須要的文件
3.還有一個額外的好處就是你不須要再作一個封裝的函數,require.js中你得這樣
define(['jquery'], function(jquery){})
4.如今你須要一個很大的封裝去定義每一個模塊,而後你須要在在require.js的配製文件中將每一個模塊的路徑都配出來,用過requirejs都會遇到的好繁瑣
require.config({ baseUrl: '/scripts', paths: { 'facebook' : '//connect.facebook.net/en_US/all', // 'facebook' : '//connect.facebook.net/en_US/sdk/debug' 'requirejs' : '../bower_components/requirejs/require', 'react' : '../bower_components/react/react-with-addons', 'underscore' : '../bower_components/lodash/dist/lodash', 'futures-requirejs' : '../bower_components/futures-requirejs/future', 'jquery' : '../bower_components/jquery/jquery', // 'phaser' : '../bower_components/phaser/build/phaser', 'phaser.filters' : '../bower_components/phaser/filters/', 'phaser' : '../thirdParty/phaser/Phaser', 'snap' : '../bower_components/Snap.svg/dist/snap.svg', 'proton' : '../thirdParty/Proton', 'copyProperties' : '../thirdParty/copyProperties', 'flux' : '../bower_components/flux/dist/Flux', 'eventEmitter' : '../bower_components/eventEmitter/EventEmitter', 'pixi' : '../bower_components/pixi/bin/pixi', 'crossroads' : '../bower_components/crossroads/dist/crossroads', 'signals' : '../bower_components/js-signals/dist/signals', 'hasher' : '../bower_components/hasher/dist/js/hasher', 'async' : '../bower_components/async/lib/async', 'socket.io-client' : '../bower_components/socket.io-client/dist/socket.io', 'html2canvas' : '../bower_components/html2canvas/build/html2canvas.min', 'hammer' : '../bower_components/hammerjs/hammer', 'touch-emulator' : '../bower_components/hammer-touchemulator/touch-emulator', 'moment' : '../bower_components/moment/moment', // 'famous' : '../bower_components/famous', 'tinygradient' : '../bower_components/tinygradient/tinygradient', 'page' : '../bower_components/page/index', // 'faker' : '../bower_components/faker/dist/faker', 'faker' : '../thirdParty/Faker', 'perlin' : '../thirdParty/Perlin', 'tinycolor' : '../vendors/tinycolor', // 'flux' : '../../node_modules/flux/index', 'client' : './', 'errors' : './errors', 'server' : '../../server', }, packages: [{ name : 'API2', location : '../bower_components/api2/src/', main : 'API' }], shim: { 'phaser.filters/Fire': { deps: ['phaser'], }, 'page': { exports: 'page' }, 'snap' : { exports: 'Snap' }, 'html2canvas' : { exports: 'html2canvas' }, 'facebook' : { exports: 'FB' }, // 'underscore': { // deps: [], // exports: '_' // }, 'phaser': { exports: 'Phaser' }, 'pixi': { exports: 'PIXI' }, 'hammer': { exports: 'Hammer' }, 'touch-emulator': { exports: 'TouchEmulator' }, 'proton': { exports: 'Proton' }, 'moment': { exports: 'moment' } } });
如下是webpack的一個文件配置,
var path = require("path"); var webpack = require("webpack"); var ExtractTextPlugin = require("extract-text-webpack-plugin") module.exports = { // context: path.join(__dirname), entry: { index: './app/scripts/index.js', page1: './app/scripts/page1.js', page3: './app/scripts/page3.js' }, output: { path: path.join(__dirname, '_dist'), filename: './scripts/[name]-bundle.js', chunkFilename: "./scripts/[id]-chunk.js", // library:'appConfig' //主要應用jsonp命名從新定義 }, module: { loaders: [{ test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") }, { test: /\.less$/, loader: 'style-loader!css-loader!less-loader' }, { test: /\.woff$/, loader: 'url-loader?prefix=font/&limit=5000' }, { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', query: { compact: false } } ] }, 'html-minify-loader': { empty: true, // KEEP empty attributes cdata: true, // KEEP CDATA from scripts comments: true // KEEP comments }, resolve: { root: [path.join(__dirname, "bower_components"), path.join(__dirname, 'app', 'scripts')], }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: "commons", filename: "./scripts/commons.js", chunks: ["page1", "page2", "page3"] }), new ExtractTextPlugin("./styles/[name].css"), new webpack.ResolverPlugin( new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"]) ) ] };
咱們能夠發現少了好多引用模塊js文件路徑引用,可能會有人問,它怎麼知道我要引用那些js,在nodejs裏有一個有趣的插件brower(這東西你若是沒有用到,你老闆可能會說你仍是一個初級菜鳥)
Bower 是twitter 推出的一款包管理工具,基於nodejs的模塊化思想,把功能分散到各個模塊中,讓模塊和模塊之間存在聯繫,經過 Bower 來管理模塊間的這種聯繫
包管理工具通常有如下的功能:
註冊機制:每一個包須要肯定一個惟一的 ID 使得搜索和下載的時候可以正確匹配,因此包管理工具須要維護註冊信息,能夠依賴其餘平臺。
文件存儲:肯定文件存放的位置,下載的時候能夠找到,固然這個地址在網絡上是可訪問的。
上傳下載:這是工具的主要功能,能提升包使用的便利性。好比想用 jquery 只須要 install 一下就能夠了,不用處處找下載。上傳並非必備的,根據文件存儲的位置而定,但須要有必定的機制保障。
依賴分析:這也是包管理工具主要解決的問題之一,既然包之間是有聯繫的,那麼下載的時候就須要處理他們之間的依賴。下載一個包的時候也須要下載依賴的包
可能會有人會問,我雖然將這些包下了下來,那我仍是不知道那些模塊位置,我該若是引用了,webpack一個插件輕鬆解決這個問題:如下是配置文件
resolve: {
root: [path.join(__dirname, "bower_components"), path.join(__dirname, 'app', 'scripts')],
},
plugins: [
new webpack.ResolverPlugin(
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
)
]
那若是調用了
var $ = require("jquery");
是否是感受很方便了,還有一些新手可能會吐槽,js原本就是弱類型語言,框架那麼多,智能提示是否是不好,特別是玩微軟那套玩多了的人必定會問,在此推薦如下webstorm、sublime、atom它們上面的插件仍是不錯的
5.requirejs它是異步依賴加載的,說白了就是,只要你用到了,它絕對會一次性加載完,就算你初始化沒有用到,它也會加載,若是你把它壓縮,文件就好大了,最後就一個文件。你也能夠破壞它的原則,按傳統的寫法單獨加載,不過就總體就不是很美觀了。可能有些解決的插件,我沒用到也是有可能的,這裏也就很少說了。
webpakc就很好解決了,它提供的插件能夠自動分析,根據你提過js文件主入口,自動分析,可合成多個js文件,可是它不會所有加載,按照你的須要一次加載,這樣就不會出現頁面剛初始化就加載沒必要要的js文件,提升頁面速度(雖然能夠靠用體力解決,說白了就是注意寫法,不過好痛苦)
以上是它們的對比,再說說它的私有特性吧
1. 對 CommonJS 、 AMD 、ES6的語法作了兼容
2. 對js、css、圖片等資源文件都支持打包(css均可以合成多個css文件包,好爽,不再是sb似的所有加載了,sass和less雖然也是模塊化的加載合併,但是css和js分離的關聯不大,這裏的css能夠和js有更大的關聯,更細緻區分加載的js)
3. 串聯式模塊加載器以及插件機制,讓其具備更好的靈活性和擴展性,例如提供對CoffeeScript、ES6的支持
4. 有獨立的配置文件webpack.config.js
5. 能夠將代碼切割成不一樣的chunk,實現按需加載,下降了初始化時間
6. 支持 SourceUrls 和 SourceMaps,易於調試
7. 具備強大的Plugin接口,大可能是內部插件,使用起來比較靈活
8.webpack 使用異步 IO 並具備多級緩存。這使得 webpack 很快且在增量編譯上更加快
在補充一個特別的屬性吧
項目開發中,僅有一臺靜態服務器是不能知足需求的,咱們須要另啓一臺web服務器,且將靜態服務器集成到web服務器中,就可使用webpack的打包和加載功能。咱們只須要修改一下配置文件就能夠實現服務器的集成。
entry: [ './src/page/main.js', 'webpack/hot/dev-server', 'webpack-dev-server/client?http://127.0.0.1:8080' ] output: { path: __dirname, filename: '[name].js', publicPath: "http://127.0.0.1:8080/assets/" } plugins: [ new webpack.HotModuleReplacementPlugin() ]
若是在開發中啓動兩個服務器並非一個很好地選擇,webpack提供了一箇中間件webpack-dev-middleware,但其只能在生產環境中使用,能夠實如今內存中實時打包生成虛擬文件,供瀏覽器訪問以及調試。使用方式以下:
var webpackDevMiddleware = require("webpack-dev-middleware"); var webpack = require("webpack"); var compiler = webpack({ // configuration output: { path: '/' } }); app.use(webpackDevMiddleware(compiler, { // options }));
有些好處可能沒有說到,webpack可能過幾年它就會被取代也是有可能,可是如今若是你說你不會,那就請趕快惡補吧,它會帶你飛的。
以上分析結合本身工做經驗之談,有些可能說大呢,說錯了你們就一笑而過,不對的地方也但願誠懇指出。