精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

全棧式JavaScript

開發(fā) 前端
如今,在創(chuàng)建一個(gè)Web應(yīng)用的過程中,你需要做出許多架構(gòu)方面的決策。當(dāng)然,你會(huì)希望做的每一個(gè)決定都是正確的:你想要使用能夠快速開發(fā)的技術(shù),支持持續(xù)的迭代,最高的工作效率,迅速,健壯性強(qiáng)。你想要精益求精并且足夠敏捷。

如今,在創(chuàng)建一個(gè)Web應(yīng)用的過程中,你需要做出許多架構(gòu)方面的決策。當(dāng)然,你會(huì)希望做的每一個(gè)決定都是正確的:你想要使用能夠快速開發(fā)的技術(shù),支持持續(xù)的迭代,最高的工作效率,迅速,健壯性強(qiáng)。你想要精益求精并且足夠敏捷。你希望你選擇的技術(shù)能夠在短期和長(zhǎng)期上都讓你的項(xiàng)目取得成功。但這些技術(shù)都不是輕而易舉就能選出來的。

我的經(jīng)驗(yàn)告訴我,全棧式JavaScript符合了這所有的要求。可能你已經(jīng)發(fā)現(xiàn)了些許端倪,又或許你已經(jīng)在考慮它的實(shí)用性,并且在和朋友討論爭(zhēng)論它的話題。但是你是否親自嘗試過呢?在這篇文章中,我會(huì)對(duì)于全棧式JavaScript給出一個(gè)比較全面的介紹,為什么它會(huì)是正確的選擇,它又是如何施展它的魔法的。

先給出一個(gè)概括預(yù)覽:

toptal-blog-500-opt

接下來我會(huì)一項(xiàng)一項(xiàng)地介紹這些組件。但是在這之前,我們簡(jiǎn)短地回顧一下,我們是如何發(fā)展到現(xiàn)在的這個(gè)階段的。

我為什么選擇用JavaScript

從1998年開始,我就是一個(gè)Web開發(fā)者。當(dāng)時(shí),我們使用Perl進(jìn) 行大多數(shù)的服務(wù)器端的開發(fā);但是從那時(shí)候開始,我們就在客戶端使用JavaScript。Web服務(wù)器端的技術(shù)已經(jīng)發(fā)生了翻天覆地的變化:我們被一波又一 波的技術(shù)潮流推著往前走,PHP,ASP,JSP,.NET,Ruby,Python,這里只列出了幾個(gè)例子。開發(fā)人員們開始意識(shí)到,在服務(wù)器端和客戶端 使用不同的語言使得事情變得復(fù)雜化。

在早期的PHP和ASP的時(shí)代,那個(gè)時(shí)候模板引擎還僅僅是個(gè)設(shè)想,開發(fā)人員們?cè)贖TML中嵌入他們的應(yīng)用代碼。我們經(jīng)常可以看到下面這種腳本嵌入的寫法:

  1. <script> 
  2.     <?php 
  3.         if ($login == true){ 
  4.     ?> 
  5.     alert("Welcome"); 
  6.     <?php 
  7.         } 
  8.     ?> 
  9. </script> 

或者更糟糕:

  1. <script> 
  2.     var users_deleted = []; 
  3.     <?php 
  4.         $arr_ids = array(1,2,3,4); 
  5.         foreach($arr_ids as $value){ 
  6.     ?> 
  7.     users_deleted.push("<php>"); 
  8.     <?php 
  9.         } 
  10.     ?> 
  11. </script> 

對(duì)于新手來說,很容易被不同語言之間的用法而混淆,犯下一些很典型的錯(cuò)誤,比如for和foreach。更為不爽的是,以這樣的方式來寫代碼,使得服務(wù)器 端和客戶端很難以非常和諧的方式處理相同的數(shù)據(jù)結(jié)構(gòu),即使是今天也是如此(當(dāng)然除非你的開發(fā)團(tuán)隊(duì)有專職的前端和后端工程師 — 但即使他們之間能夠共享信息,但仍然不能僅僅基于對(duì)方的代碼進(jìn)行合作)。

  1. <?php 
  2.     $arr = array("apples""bananas""oranges""strawberries"), 
  3.     $obj = array(); 
  4.     $i = 10; 
  5.     foreach($arr as $fruit){ 
  6.         $obj[$fruit] = $i; 
  7.         $i += 10; 
  8.     } 
  9.     echo json_encode(obj); 
  10. ?> 
  11. <script> 
  12.     $.ajax({ 
  13.         url:"/json.php"
  14.         success: function(data){ 
  15.             var x; 
  16.             for(x in data){ 
  17.                 alert("fruit:" + x + " points:" + data[x]); 
  18.             } 
  19.         } 
  20.     }); 
  21. </script> 

最初,對(duì)于統(tǒng)一使用一種編程語言的嘗試是使用后臺(tái)的語言編寫客戶端的組件,然后編譯成JavaScript。但這種方式并沒有如期望的一樣很好地工作,許多相關(guān)的項(xiàng)目都失敗了(比如被ASP MVC取代了的ASP.NET Web forms, 又比如正在逐步被Polymer取代的GWT)。當(dāng)然這些想法都是偉大的,從本質(zhì)上講,都是想在服務(wù)器端和客戶端使用同一種語言,讓我們可以重用一些組件和資源(注意這里的關(guān)鍵詞:資源)。

最終得出的答案很簡(jiǎn)單:將JavaScript放到服務(wù)端

其實(shí)JavaScript誕生之初是在網(wǎng)景公司的企業(yè)及服務(wù)器的 服務(wù)端,只是當(dāng)時(shí)它還沒有完全準(zhǔn)備好。經(jīng)過數(shù)年的磨煉和錯(cuò)失,最終Node.js出現(xiàn)了,它不僅將JavaScript放到了服務(wù)器端,同時(shí)也推廣了非阻 塞式編程(non-blocking programming)的思想,這種思想來自于nginx的世界。感謝Node的創(chuàng)始者們nginx的技術(shù)背景,并且繼續(xù)(聰明地)保持了它的簡(jiǎn)單性, 也感謝JavaScript天生的事件輪詢機(jī)制。

#p#

(一句話概括,非阻塞式編程目的在于將消耗時(shí)間的任務(wù)放到一邊,通過指定在這些任務(wù)結(jié)束時(shí)需要做的操作,這樣可以在同一時(shí)刻讓處理器去處理其他的請(qǐng)求。)

Node.js永久性地改變了我們處理I/O訪問的方式。作為Web開發(fā)者,我們過去一直使用如下的方式訪問數(shù)據(jù)庫(I/O):

  1. var resultset = db.query("SELECT * FROM 'table'"); 
  2. drawTable(resultset); 

這里的第一行代碼本質(zhì)上已經(jīng)阻塞了你的代碼,因?yàn)槟愕拇a停止下來等待數(shù)據(jù)庫驅(qū)動(dòng)返回一個(gè)結(jié)果集(resultset)。而與此同時(shí),你的平臺(tái)架構(gòu)其實(shí)給你提供了并發(fā)的方法,通常是通過線程(threads)和派生(forks)。

在Node.js和非阻塞式編程的幫助下,我們可以更多的控制我們程序的執(zhí)行流。現(xiàn)在(盡管在數(shù)據(jù)庫I/O驅(qū)動(dòng)器的背后可能已經(jīng)有并行執(zhí)行),你可以定義你的程序在I/O操作期間并行做的事情,以及在接收到結(jié)果集之后做的操作。

  1. db.query("SELECT * FROM 'table'"function(resultset){ 
  2.    drawTable(resultset); 
  3. }); 
  4. doSomeThingElse(); 

上面的代碼片段中,我們定義了兩個(gè)程序流:第一個(gè)在我們發(fā)出數(shù)據(jù)庫查詢之后執(zhí)行的操作,第二個(gè)是以回調(diào)的方式在我們接收到結(jié)果集之后做的操作。這是一個(gè)非常優(yōu)雅并且強(qiáng)大的處理并發(fā)的方式。正如他們所說的,“一切都在并行執(zhí)行——除了你的代碼。(Evetything runs in parallel — except your code.)”這樣,你的代碼會(huì)更易寫,有更高的可讀性,容易理解,也便于維護(hù),這些都基于你找回了對(duì)程序流的控制。

這些觀點(diǎn)早就不是很新的觀點(diǎn),那為什么他們隨著Node.js變得如此流行起來。很簡(jiǎn)單:非阻塞式編程可以有多重實(shí)現(xiàn)的方式。但可能最簡(jiǎn)單的就是使用回調(diào)和事件輪詢。在大多數(shù)于語言里,做到這點(diǎn)并不是一個(gè)簡(jiǎn)單的事情。回調(diào)機(jī)制在其他的一些于語言里是一個(gè)比較常見的功能,但是事件輪詢卻不是。你會(huì)經(jīng)常發(fā)現(xiàn)自己還需要在一些擴(kuò)展庫上做掙扎(比如,Python中使用Tornado)。

但是在JavaScript中,回調(diào)機(jī)制已經(jīng)被內(nèi)建在語言中, 事件輪詢也是如此。而對(duì)JavaScript稍有了解的程序員對(duì)它們也非常熟悉(或者至少使用過它們,即使他們有可能并不完全理解什么是事件輪詢)。突然之間,地球上所有的創(chuàng)業(yè)公司都可以在客戶端和服務(wù)器端重用開發(fā)人員(或者資源),解決了“需要Python大師(Python Guru Needed)”的招聘發(fā)布問題。

因此,現(xiàn)在我們有了一個(gè)發(fā)展迅速的平臺(tái)(感謝于非阻塞式編程),和一個(gè)非常易于使用的語言(感謝JavaScript)。但是這就足夠了嗎?它是可持續(xù)的嗎?我確信,JavaScript在將來會(huì)有一個(gè)非常重要的地位。下面我來告訴你為什么。

函數(shù)式編程

JavaScript是第一個(gè)將函數(shù)式范式帶給民眾的語言(當(dāng)然,Lisp第一個(gè)出現(xiàn),但是大多數(shù)的程序員都沒有使用它開發(fā)過一個(gè)可以作為產(chǎn)品的應(yīng)用)。Lisp和Self,這兩個(gè)深深影響了JavaScript的語言,充滿了創(chuàng)新的理念,它們解放了我們的思想,去挖掘新的技術(shù),模式和規(guī)范。這些都延續(xù)到了JavaScript上。看一下mondas, Church number, 或者甚至(作為更有實(shí)踐性的例子)Underscore的Collections functions,這些可以節(jié)約你一行又一行的代碼。

動(dòng)態(tài)對(duì)象以及原型繼承

沒有類(Classes),也沒有無窮無盡的類層次結(jié)構(gòu)的面向?qū)ο螅∣bject-oriented)編程是提供了更快速的編程體驗(yàn)——只要?jiǎng)?chuàng)建對(duì) 象,添加方法然后使用他們。更重要的是,它大大減少了維護(hù)時(shí)重構(gòu)的成本,因?yàn)樗试S程序員直接修改對(duì)象的實(shí)例,而不需要修改類。這種速度和靈活的方式為快 速開發(fā)鋪平了道路。

JavaScript就是互聯(lián)網(wǎng)

JavaScript是因互聯(lián)網(wǎng)而生的。它從一開始就出現(xiàn)了,并且伴隨到現(xiàn)在。任何想要摧毀它的嘗試都以失敗而告終,比如Java Applets的衰落,VBScript被微軟的TypeScript(它最終會(huì)被編譯成JavaScript)所取代,以及Flash在手機(jī)市場(chǎng)以及HTML5上的一敗涂地。如果想不破壞成千上萬個(gè)Web頁面而取代JavaScript是不可能的,所以我們接下來的目標(biāo)應(yīng)該是提高和完善它。這個(gè)工作,沒有誰比ECMA的Technical Committee 39更適合了。

當(dāng)然,JavaScript的替代者們每天都在誕生,比如CoffeeScript,TypeScript,以及成千上萬能被編譯成JavaScript的語言。這些替代者們?cè)陂_發(fā)過程中也許是有用的(通過source maps), 但是他們最終都不可能成功地代替JavaScript,兩個(gè)主要原因:他們的社區(qū)永遠(yuǎn)不會(huì)比JavaScript更大,他們中的優(yōu)秀特性會(huì)被 ECMAScript(也就是JavaScript)所吸收。JavaScript不是匯編語言,它是一個(gè)你能理解代碼的高級(jí)編程語言——所以你應(yīng)該理解 它。

端到端(End-to-End)JavaScript:Node.js和MongoDB

我們已經(jīng)介紹了為什么要使用JavaScript。接著,我們來看看使用Node.js和MongoDB的理由。

NODE.JS

Node.js是 一個(gè)搭建快速和可擴(kuò)展的網(wǎng)絡(luò)應(yīng)用的平臺(tái)——正如Node.js網(wǎng)站上所說。但是Node.js遠(yuǎn)不止這些:它是如今最火的JavaScript運(yùn)行環(huán)境, 被大量的應(yīng)用和程序庫所使用——甚至是瀏覽器的庫代碼也運(yùn)行在Node.js上。更重要的是,這種服務(wù)器端的快速執(zhí)行讓程序員可以專注于更復(fù)雜的問題,比 如做自然語言處理的Natural。即使你并沒有計(jì)劃用Node.js來寫你的服務(wù)器端應(yīng)用,你也有可能使用基于Node.js的工具來改進(jìn)你的開發(fā)流程。舉例來說:用Bower來做前端包依賴管理,Mocha做單元測(cè)試,Grunt做自動(dòng)化打包,甚至用Brachets做全文代碼編輯。

因此,如果你正準(zhǔn)備開發(fā)服務(wù)器端活客戶端的JavaScript應(yīng)用,你就需要對(duì)Node.js更加熟悉,因?yàn)槟阍谌粘9ぷ髦袝?huì)需要他。有一些很有趣的代替的選擇,但是它們中的任何一個(gè)的社區(qū)都不及Node.js的10%。

MONGODB

MongoDB是一個(gè)基于文檔(Document-based)NoSQL數(shù)據(jù)庫,它使用JavaScript作為它的查詢語言(但是它不是用JavaScript寫的),它完善了我們端到端的JavaScript平臺(tái)。但是這個(gè)并不是我們選擇MonoDB的主要原因。

MongoDB 是無模式的(schema-less),允許你以非常靈活的方式把對(duì)象持久化,因此能夠迅速的應(yīng)對(duì)需求變更。此外,它具有高度可擴(kuò)展性,并且基于map-reduce,讓它非常適合于大數(shù)據(jù)的應(yīng)用。MongoDB如此靈活,以至于它既可以用作無模式的文檔數(shù)據(jù)庫,也可以用作關(guān)系數(shù)據(jù)存儲(chǔ)(盡管它缺少事務(wù),只能通過模擬來實(shí)現(xiàn)),甚至是用來緩存結(jié)果的鍵值對(duì)存儲(chǔ),就像Memcached和Redis。

#p#

基于Express的服務(wù)器端組件化

服務(wù)器端的組件化開發(fā)一直不是一件容易的是。但是 Express(和Connect)帶來了“中間件(middleware)的思想”。在我看來,中間件是服務(wù)器端定義組件最好的方式。如果你想找個(gè)熟悉 的模式來對(duì)比一下的話,那它非常接近于管道和過濾器(pipes and filters)。

基本思想就是將你的組件作為管道的一部分。管道處理一個(gè)請(qǐng)求(也叫輸入),生成一個(gè)結(jié)果(也叫輸出),但是你的組件并不負(fù)責(zé)整個(gè)響應(yīng)結(jié)果。相反,它只做它需要做的修改,然后將委派給下管道的下一節(jié)點(diǎn)。當(dāng)管道的最后的節(jié)點(diǎn)處理完之后,這個(gè)結(jié)果再返回給客戶端。

我們稱這些管道的節(jié)點(diǎn)為中間件。很明顯,我們可以創(chuàng)建兩種類型的中間件:

  • 中間型(Intermediates)
  • 一個(gè)中間型節(jié)中間件理請(qǐng)求和響應(yīng),但是它不負(fù)全權(quán)責(zé)整個(gè)響應(yīng),而是繼續(xù)將它們分派給下一個(gè)中間件。
  • 終結(jié)型(Finals)
  • 一個(gè)結(jié)束型中間件負(fù)責(zé)最終的響應(yīng)結(jié)果。它對(duì)請(qǐng)求和響應(yīng)進(jìn)行處理,之后不會(huì)分派給下一個(gè)中間件。但實(shí)踐中,繼續(xù)分派給一個(gè)中間件可以給架構(gòu)帶來更高的靈活性(比如,之后需要增加其他的中間件),即使下一個(gè)中間件并不存在(這種情況下,結(jié)果會(huì)直接被傳遞到客戶端)。

user-manager-500-opt
(Large view)

取一個(gè)具體的例子,假設(shè)服務(wù)器端有一個(gè)“用戶管理”的組件。根據(jù)中間件的方式,我們最好能有終結(jié)型和中間型的中間件。對(duì)于終結(jié)節(jié)點(diǎn),我們要有創(chuàng)建用 戶和列出用戶的功能。但是在我們做這些操作之前,我們需要使用中間節(jié)點(diǎn)來做認(rèn)證(因?yàn)槲覀儾幌M麤]有認(rèn)證過的請(qǐng)求能進(jìn)來,甚至創(chuàng)建用戶)。一旦我們創(chuàng)建好 了這些認(rèn)證中間件,當(dāng)我們想要把一個(gè)原先不需要認(rèn)證的功能改變成認(rèn)證功能的時(shí)候,我們只需要將這個(gè)中間件安插在相應(yīng)的位置。

單頁面(Single-Page)應(yīng)用

當(dāng)你使用全棧式JavaScript的時(shí)候,多數(shù)情況下你會(huì)專注開發(fā)單頁面應(yīng)用。大多數(shù)的Web開發(fā)者們都禁不住不止一次地嘗試著著手于單頁面應(yīng)用。我已經(jīng)創(chuàng)建了幾個(gè)(多數(shù)為個(gè)人的),我相信他們就是Web應(yīng)用的未來。你是否在移動(dòng)鏈接上對(duì)比過單頁面應(yīng)用和通常的Web應(yīng)用?他們?cè)陧憫?yīng)速度的差距有數(shù)十秒之多。

(注意:有些人可能不同意我的觀點(diǎn)。比如Twitter,回滾了他們的單頁面途徑。與此同時(shí),很多大的網(wǎng)站正在步入單頁面時(shí)代,比如Zendesk。我已經(jīng)看到足夠的證據(jù)證明單頁面應(yīng)用帶來的好處,并且對(duì)此深信不疑。但是具體還是因情況而異。)

如果單頁面應(yīng)用如此強(qiáng)大,那為什么還是要選擇老土的方式來創(chuàng)建你的應(yīng)用呢?我經(jīng)常聽到的一種爭(zhēng)論就是他們擔(dān)心SEO(Search Engine Optimization)。但是如果你對(duì)此做了正確的處理,這將不是一個(gè)問題:你可以有多種解決方式,從使用無界面的瀏覽器(headless browser),比如PhantomJS,在檢測(cè)到網(wǎng)絡(luò)爬蟲的時(shí)候渲染HTML,到使用一些現(xiàn)有框架執(zhí)行服務(wù)器端渲染。

基于Backbones.js,Marionette和Twitter Bootstrap的客戶端MV*模式

關(guān)于使用MV*框架開發(fā)單頁面應(yīng)用已經(jīng)有太多的討論了。盡管很難選擇,但是我想說排名前三的是Backbone.js, Ember和AngularJS。

這三個(gè)都是非常被推崇的,但哪個(gè)是最適合你的?

不幸的是,我必須得承認(rèn)我在AngularJS上的經(jīng)驗(yàn)有限,所以我就把它放在討論范圍之外。那么,Ember和Backbone.js代表了解決同一問題的兩種不同方式。

Backbone.js很小,但是恰到好處的提供了創(chuàng)建一個(gè)簡(jiǎn)單的單頁面應(yīng)用所需要的功能。另一方面,Ember是一個(gè)創(chuàng)建單頁面應(yīng)用的完整且專業(yè)的框架。它有更多的輔助工具,但是也有更加陡峭的學(xué)習(xí)曲線。(你可以閱讀更多關(guān)于Ember.js的內(nèi)容。)

基于你的應(yīng)用的大小,可以簡(jiǎn)單地通過比較“需要的功能”占“可用的功能”的比例來做出決定,它會(huì)給你很大的提示。

樣式設(shè)計(jì)也同樣是一個(gè)挑戰(zhàn),但是再次,我們也可以列舉出一些可以助我們一臂之力的框架。對(duì)于CSS,Twitter Bootstrap是一個(gè)非常好的選擇,它提供了一套完整的樣式,它們可以立即使用,也非常便于自定義。

Bootstrap是使用LESS語言創(chuàng)建的,它是開源的,我們可以根據(jù)我們的需要來修改它。伴隨它的還有一大堆用戶友好的組件,它們也有非常完善的文檔。此外,一個(gè)定制化模式讓你很方便地創(chuàng)建你自己的。毫無疑問,它正是這個(gè)工作所需要的正確的工具。

最佳實(shí)踐:Grunt,Mocha,Chai,RequireJS 和 CoverJS

最后,我們將定義一些最佳實(shí)踐,同時(shí)談?wù)勗撊绾螌?shí)現(xiàn)和維護(hù)它們。具有代表性的,我的解決方案,最終聚焦到幾個(gè)工具上,他們本身都是基于Node.js。

MOCHA 和 CHAI

這些工具能幫助你使用測(cè)試驅(qū)動(dòng)開發(fā)模式(test-driven development)或者行為驅(qū)動(dòng)開發(fā)模式(behavior-driven development)來改進(jìn)你的開發(fā)流程,創(chuàng)建一些基礎(chǔ)架構(gòu)來管理你的單元測(cè)試,并且自動(dòng)運(yùn)行這些測(cè)試。

現(xiàn)在有大量的JavaScript單元測(cè)試框架,為什么要用Mocha?簡(jiǎn)短的回答就是它即靈活又完善。我來解釋一下:

  • 用戶界面(Interfaces)
  • 也許你習(xí)慣于測(cè)試驅(qū)動(dòng)的程序組和單元測(cè)試的概念,又或許傾向于行為驅(qū)動(dòng)測(cè)試的使用describle和should來定義行為定義的理念。Mocha讓你可以同時(shí)使用這兩種方式。
  • 報(bào)表生成器(reporter)
  • 運(yùn)行你的測(cè)試代碼會(huì)生成測(cè)試結(jié)果的報(bào)表,你可以使用各式各樣的reporter來格式化這些結(jié)果。舉例來說,如果你需要提供一個(gè)持續(xù)集成服務(wù)器信息,你可以找到一個(gè)report來做這些。
  • 沒有指定斷言庫(Lack of an assertion library)
  • 這幾乎不是一個(gè)問題,Mocha決定讓你選擇自己要使用的斷言庫,從而給你更多的靈活性。你有很多的選擇,這正是Chai施展身手的地方。

Chai 是一個(gè)非常靈活的斷言庫,它可以讓你使用如下三中主要斷言方式的任何一種:

  • assert

這是來自老派測(cè)試驅(qū)動(dòng)開發(fā)的經(jīng)典的assert方式。比如:

  1. assert.equal(variable, "value"); 
  • expect

這種鏈?zhǔn)降臄嘌燥L(fēng)格在行為驅(qū)動(dòng)開發(fā)中最為常見。比如:

  1. expect(variable).to.equal("value"); 

should

這也是用在測(cè)試驅(qū)動(dòng)開發(fā)中,但是我更推薦expect,因?yàn)閟hould經(jīng)常聽起來比較反復(fù)(比如,定義一個(gè)行為規(guī)范,”it (should do something…)”)。舉例:

  1. variable.should.equal("value"); 

Chai和Mocha可以無縫集成。使用這兩個(gè)程序庫,你可以使用測(cè)試驅(qū)動(dòng),行為驅(qū)動(dòng)活任何想得到的方式來寫你的測(cè)試代碼。

#p#

GRUNT

Grunt是你能夠自動(dòng)化你的build任務(wù),包含簡(jiǎn)單的復(fù)制粘貼和文件拼接,模板預(yù)編譯,style語言(SASS和LESS)編譯,單元測(cè)試(使用Mocha),代碼檢查,以及代碼最小化(比如,使用UglifyJS或者Closure Compiler)。你可以添加你自己的自動(dòng)化任務(wù)到Grunt中或者搜索registry,那里數(shù)百個(gè)插件可供使用(再次提醒,選擇使用有良好的社區(qū)支持的工具)。Grunt也可以監(jiān)控你的文件,當(dāng)發(fā)生更改時(shí)觸發(fā)一些操作。

REQUIREJS

RequireJS 聽起來是基于AMD API的另一種加載模塊的方式,但是我敢保證地告訴你,它遠(yuǎn)遠(yuǎn)不止這個(gè)功能。使用RequireJS,你可以定義你的模塊之間的依賴和層次結(jié)構(gòu),讓 RequireJS庫幫你來加載他們。它還提供了一種非常簡(jiǎn)便的方式來避免全局變量污染,通過在函數(shù)體中定義你的模塊。這讓模塊可以重用,不像命名空間模塊(namespaced modules)。試想一下:如果定義了一個(gè)類似于Demoapp.helloWorlModule的模塊,你想把他改成Firstapp.helloWorldModule,那么你需要把所有引用到Demoapp命名空間的地方都做修改,才能讓它變得可移植。

RequireJS還能讓你擁抱依賴注入模式。假設(shè)你有一個(gè)模塊需要用到主應(yīng)用對(duì)象(單例)的一個(gè)實(shí)例。通過使用RequireJS,你意識(shí)到你不 需要使用全局變量來存儲(chǔ)它,你也不能使用一個(gè)實(shí)例作為RequireJS的依賴。所以,你需要在你的模塊構(gòu)造器中加載這個(gè)依賴。讓我們看一個(gè)例子:

在main.js:

  1. define( 
  2.       ["App","module"], 
  3.       function(App, Module){ 
  4.           var app = new App(); 
  5.   
  6.           var module = new Module({ 
  7.               app: app 
  8.           }) 
  9.   
  10.           return app; 
  11.       } 
  12.   ); 

在module.js:

  1. define([], 
  2.       function(){ 
  3.           var module = function(options){ 
  4.               this.app = options.app; 
  5.           }; 
  6.           module.prototype.useApp = function(){ 
  7.               this.app.performAction(); 
  8.           }; 
  9.           return module 
  10.       } 
  11.   ); 

注意,我們不能在module的定義中加入對(duì)main.js的依賴,否則我們會(huì)創(chuàng)建出一個(gè)循環(huán)引用。

COVERJS

代碼覆蓋率(Code coverage)是你測(cè)試的一個(gè)度量標(biāo)準(zhǔn)。正如它的名字所示,它能告訴你當(dāng)前的測(cè)試集覆蓋了你代碼的多少部分。CoverJS通過檢測(cè)你代碼中的語句 (而不是像JSCoverage那樣看代碼行)并生成一個(gè)檢測(cè)過的版本的代碼來測(cè)量你的測(cè)試代碼的覆蓋率。它也可以支持對(duì)持續(xù)集成服務(wù)器提供持續(xù)報(bào)表生 成。

總結(jié)

全棧式JavaScript并不能解決所有的問題。但是它的社區(qū)和技術(shù)會(huì)帶領(lǐng)你走很長(zhǎng)一段路。使用JavaScript,你可以創(chuàng)建基于統(tǒng)一的語言的可擴(kuò)展的,可維護(hù)的應(yīng)用。毫無疑問,這是絕對(duì)值得我們關(guān)注的。

原文鏈接:http://blog.jobbole.com/52745/

譯文鏈接:http://blog.jobbole.com/52745/

責(zé)任編輯:陳四芳 來源: 伯樂在線
相關(guān)推薦

2017-04-06 10:27:01

JavaScript基礎(chǔ)Java

2022-07-06 11:21:11

JHipsterJavaJavaScript

2015-08-04 09:40:10

Python大數(shù)據(jù)全棧式

2018-10-15 10:22:51

2023-08-21 09:51:57

全棧軟件開發(fā)

2022-05-25 23:25:17

低代碼數(shù)字化軟件

2015-05-04 09:23:38

JavaScript全棧開發(fā)員云計(jì)算

2020-07-20 08:23:04

Redis分布式系統(tǒng)

2017-06-13 15:10:02

大數(shù)據(jù)Log日志

2017-06-13 08:55:29

Log日志MySQL

2018-11-06 15:34:18

AWS云計(jì)算Dynatrace

2014-02-20 13:46:30

C++JavaScript

2021-06-01 07:16:21

C語言基礎(chǔ)代碼

2022-07-26 07:47:14

架構(gòu)

2017-10-12 14:24:24

2022-12-15 08:44:52

2018-11-19 11:16:46

Dynatrace人工智能運(yùn)維

2021-10-06 05:04:47

監(jiān)控

2020-08-10 14:46:30

JavaScriptStack

2019-07-23 15:04:54

JavaScript調(diào)用棧事件循環(huán)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

高清shemale亚洲人妖| 亚洲国产一成人久久精品| 色综合久久88色综合天天| 亚洲精品无人区| 国产香蕉在线观看| 美女性感视频久久| 欧美精品激情视频| 精品人体无码一区二区三区| 午夜电影一区| 欧洲视频一区二区| 丝袜人妻一区二区三区| 国产剧情在线观看| 国产.欧美.日韩| 国产精品夜色7777狼人| 国产一级特黄视频| 首页国产精品| 亚洲精品视频网上网址在线观看| 亚洲第一天堂久久| 日韩成人影音| 亚洲成人av福利| 久久观看最新视频| 国产美女视频一区二区三区| 粉嫩av一区二区三区| 国产欧美日韩免费看aⅴ视频| 日韩精品视频免费播放| 91精品99| 色先锋资源久久综合5566| 久久偷拍免费视频| 综合伊人久久| 日韩一区和二区| 欧美成人三级在线播放| 亚洲成人短视频| 黑人巨大精品欧美一区二区一视频 | 97成人在线| 欧美一区二区在线观看| 亚洲va在线va天堂va偷拍| 日韩国产网站| 91官网在线观看| 男人靠女人免费视频网站| 欧美xxxx黑人又粗又长| 亚洲激情欧美激情| 国产手机视频在线观看| 欧美69xxx| 国产精品视频线看| 亚洲图片在线观看| 99免在线观看免费视频高清| 久久精品欧美一区二区三区不卡| 国产一区免费在线| 国产成人手机在线| caoporn国产精品| 国产一区高清视频| 五月天激情开心网| 91小视频免费看| 久久精品99久久| 欧美新色视频| 久久久久久久久久电影| 欧美精品二区三区四区免费看视频| 日本黄色一区二区三区| www.成人网.com| 久久久水蜜桃| 国产特黄在线| 国产精品久久久久久久久搜平片 | 国产精品日韩欧美一区| 欧美一级黄色网| 日韩电影在线观看一区二区| 老司机久久99久久精品播放免费| 国产成人一区二区三区小说| 在线观看亚洲黄色| 激情六月婷婷久久| yellow视频在线观看一区二区| www.xxx国产| 不卡av在线网| 欧美一区国产一区| 免费**毛片在线| 亚洲一区在线观看视频| 久草热视频在线观看| 黑人巨大精品| 欧美老女人第四色| 不许穿内裤随时挨c调教h苏绵| 激情小说一区| 在线播放国产一区中文字幕剧情欧美 | 中文字幕国产传媒| 久久一级大片| 国产丝袜精品第一页| 国产白丝一区二区三区| 欧美日韩p片| 国产成人免费av电影| 国产精品久久久久久久成人午夜| 高清不卡一区二区| 日韩性感在线| 俄罗斯一级**毛片在线播放| 欧美伊人久久大香线蕉综合69| 亚洲第一区第二区第三区| 黄色欧美网站| 精品国产一区二区三区久久狼5月| 久久无码精品丰满人妻| 日本午夜精品一区二区三区电影 | 成人欧美一区二区三区| 国产av天堂无码一区二区三区| 欧美精品总汇| 欧美精品一区二区三| 一级黄色毛毛片| 亚洲啪啪91| 91亚洲永久免费精品| 男人的天堂在线视频| 亚洲女厕所小便bbb| 欧美激情成人网| 亚洲精品一区二区三区在线| 精品粉嫩aⅴ一区二区三区四区| 91在线无精精品白丝| 在线欧美福利| 91天堂在线视频| 成人欧美亚洲| 精品久久久免费| 日韩欧美中文视频| 日韩在线观看一区 | www.久久久久久.com| 中文字幕在线观看视频网站| 国产精品一区二区免费不卡| 色涩成人影视在线播放| 性欧美freesex顶级少妇| 日韩精品在线网站| 神马久久精品综合| 免费国产亚洲视频| 日产国产精品精品a∨ | 国产精品老女人视频| 熟妇高潮一区二区高潮| 亚洲精品国产a久久久久久 | 久久男人资源站| 亚洲欧美久久精品| 自拍偷拍亚洲在线| 中文字幕av第一页| 日本一区二区三区四区在线视频| 久久久久久久中文| 欧美三级电影在线| 91国产精品91| 日本人妻熟妇久久久久久| 一区二区三区在线观看欧美| 男女污污视频网站| 久久久久久久久久久9不雅视频| 国产精品高潮呻吟久久av野狼 | 中文字幕字幕中文在线中不卡视频| 成熟老妇女视频| 久久成人高清| 国产成人精品视| 啊v在线视频| 精品视频在线免费看| 91禁男男在线观看| 捆绑调教美女网站视频一区| 一区二区三区的久久的视频| 日韩有码欧美| 欧美成人亚洲成人日韩成人| 国产成人精品一区二区无码呦| 亚洲精品视频在线观看网站| 国产伦理在线观看| 日韩一区二区久久| 欧美12av| 欧美高清影院| 伊人性伊人情综合网| 欧美性色欧美a在线播放| 高清中文字幕mv的电影| 亚洲国产日韩欧美一区二区三区| 国产另类自拍| 惠美惠精品网| 最新91在线视频| 国产黄色一区二区| 午夜日韩在线电影| 日韩精品电影一区二区| 日本人妖一区二区| 99re8这里只有精品| 成人福利一区| 国产成人精品优优av| 黄网页免费在线观看| 日韩免费看网站| 看片网址国产福利av中文字幕| 国产亚洲欧美一区在线观看| 国内自拍第二页| 在线成人av| 五月天丁香综合久久国产 | 在线国产视频一区| 狠狠色伊人亚洲综合成人| 欧美 亚洲 视频| 亚欧日韩另类中文欧美| 国产精品视频久久久| 色呦呦呦在线观看| 亚洲日本中文字幕| 成人1区2区3区| 色综合 综合色| 黑人狂躁日本娇小| 91在线丨porny丨国产| 欧美激情第3页| 一本色道88久久加勒比精品| 亚洲成人av动漫| 老牛影视av一区二区在线观看| 国产精品久久av| 182在线播放| 日韩中文字幕亚洲| 欧美巨乳在线| 日韩欧美一区二区视频| 自拍偷拍18p| 亚洲自拍欧美精品| 一本一本久久a久久| 99re视频精品| 午夜不卡福利视频| 国产亚洲福利| 蜜臀av性久久久久蜜臀av| 久久成人av| 精品久久久久久综合日本| 天天综合在线观看| 日韩免费在线看| 9765激情中文在线| 欧美插天视频在线播放| www免费网站在线观看| 日韩精品免费综合视频在线播放| 国产精品一区二区三区在线免费观看| 色综合久久综合网| 日韩av免费网址| 一区二区三区日韩在线观看| 无码熟妇人妻av| 成人精品鲁一区一区二区| 国内av免费观看| 秋霞午夜鲁丝一区二区老狼| 无罩大乳的熟妇正在播放| 欧美午夜国产| 特级黄色录像片| 精品美女在线视频| 欧美重口乱码一区二区| 日韩激情毛片| 国内精品久久久久久久果冻传媒| 成人网av.com/| 国产深夜精品福利| 欧美91在线|欧美| 国产精品久久久久久久久久东京| 欧美黑人粗大| 国产97在线观看| 蜜桃视频成人m3u8| 日本亚洲欧洲色| 欧美韩国亚洲| 国产精品久久9| 国产精品99精品一区二区三区∴| 国产精品88a∨| 日韩高清在线| 国产欧美一区二区三区在线看 | 国产a一区二区| 99香蕉久久| 精品无人区一区二区三区竹菊| 999久久久精品一区二区| 风间由美久久久| 精品人人人人| 麻豆精品蜜桃一区二区三区| 亚洲人成网站77777在线观看| 九九99久久| 美日韩中文字幕| 日韩午夜视频在线观看| 欧美wwwww| 国内自拍中文字幕| 一区二区三区导航| 东京热加勒比无码少妇| 日韩福利电影在线观看| 五月婷婷之综合激情| 久久97超碰色| 9191在线视频| proumb性欧美在线观看| 亚洲av无码成人精品国产| 国产欧美一区二区在线观看| 午夜时刻免费入口| 综合色中文字幕| 青青草在线观看视频| 精品国产精品自拍| 少妇一级淫片日本| 91精品国产欧美一区二区成人 | 在线观看色网站| 日韩一区二区免费视频| 亚洲人妻一区二区| 日韩中文理论片| xxxcom在线观看| 国产精品色视频| 福利欧美精品在线| 亚洲欧洲一区二区| 黄色精品网站| 日日干夜夜操s8| 成人美女在线观看| 波多野结衣家庭教师在线观看| 亚洲综合成人网| 欧美激情一区二区三区免费观看 | 亚洲视频天天射| 久久久国产精华| 农村妇女精品一区二区| 欧美视频在线观看免费网址| 亚洲天堂视频在线| 亚洲激情视频网站| 91网在线播放| 国外成人免费在线播放| 日本少妇一区| 国产精品手机视频| 久久伦理在线| 午夜肉伦伦影院| 国产69精品久久久久毛片| 精品国产aaa| 亚洲成人精品一区二区| 一区二区三区黄色片| 日韩精品免费观看| www视频在线看| 国产精品女人网站| 日韩av字幕| japanese在线播放| 免费人成黄页网站在线一区二区 | 国产精品不卡一区二区三区| 久久一区二区三区视频| 日韩一区二区三区四区| 成年人在线观看| 欧美一区二区.| 国产香蕉精品| 国产91视频一区| 激情五月播播久久久精品| 在线观看日本中文字幕| 精品高清美女精品国产区| 成人av手机在线| 久久人人爽人人爽人人片亚洲| 欧美xo影院| 激情五月综合色婷婷一区二区| 欧美一区亚洲| 欧美激情第一区| 国产精品美女www爽爽爽| 日日骚av一区二区| 精品香蕉一区二区三区| 6699嫩草久久久精品影院| 999精品在线观看| 国产精品久久久久久久免费观看| 免费涩涩18网站入口| 国产欧美一区二区三区鸳鸯浴 | 国产又粗又猛又爽又黄91精品| 日本一道本视频| 欧美在线观看视频一区二区三区| 男人的天堂在线免费视频| 欧美在线视频观看免费网站| 久久悠悠精品综合网| 国产 日韩 亚洲 欧美| 成人午夜伦理影院| 亚洲 欧美 视频| 日韩av网址在线观看| 蜜桃av在线播放| 久久精品magnetxturnbtih| 国产免费成人| 国产小视频自拍| 欧美日韩性生活| 看黄网站在线| 99在线看视频| 一本一道久久综合狠狠老精东影业| 喷水视频在线观看| 精品日韩视频在线观看| 欧洲伦理片一区 二区 三区| 国产精品91久久| 999国产精品| 丰满少妇中文字幕| 亚洲高清三级视频| 欧美男男激情freegay| 国产精品成人av在线| 成人羞羞网站入口| 超碰在线资源站| 婷婷丁香激情综合| 黑人与亚洲人色ⅹvideos| 国产精品视频免费在线观看| 91精品亚洲| 在线视频 日韩| 在线观看日韩电影| 国产原创在线观看| 国产精品久久九九| 久久男女视频| 久久福利免费视频| 欧美精品一区二区三区在线| 暖暖成人免费视频| 亚洲最新免费视频| 成人动漫一区二区在线| 波多野结衣 久久| 久久精品国产99国产精品澳门| 8848成人影院| 亚洲黄色a v| 一区二区成人在线观看| 三级视频网站在线| 成人久久一区二区三区| 1024日韩| 亚洲图片第一页| 亚洲成色999久久网站| 欧美日韩视频免费观看| 毛片av在线播放| 国产欧美综合在线观看第十页 | 欧美韩国日本| 欧美日韩性生活片| 国产精品白丝在线| 天堂a中文在线| 亚洲伊人一本大道中文字幕| 一区二区三区国产盗摄| 亚洲少妇xxx| 亚洲男人天堂2019| 亚洲三级av| 日韩不卡一二三| 午夜精品久久久久| а√天堂8资源在线官网| 欧美综合激情|