coffeescript小書CoffeeScript原是Github上一個(gè)開源項(xiàng)目采用_第1頁
coffeescript小書CoffeeScript原是Github上一個(gè)開源項(xiàng)目采用_第2頁
coffeescript小書CoffeeScript原是Github上一個(gè)開源項(xiàng)目采用_第3頁
coffeescript小書CoffeeScript原是Github上一個(gè)開源項(xiàng)目采用_第4頁
coffeescript小書CoffeeScript原是Github上一個(gè)開源項(xiàng)目采用_第5頁
免費(fèi)預(yù)覽已結(jié)束,剩余32頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

CoffeeScirpt這本書是完全開源的,作者是AlexMacCaw@maccman),DavidGriffiths、SatoshiMurakami和JeremyAshkenas也做了不小的貢獻(xiàn)。如果你有任何勘誤和建議,千萬別到本書的page發(fā)個(gè)ticket?;蛟S還對(duì)我的另外一本書JavaScriptWebApplicationsbyO’Reilly感,我在該書中對(duì)富JavaScript更重要的是,JavaScript有很多不為人知的,這些往往讓無經(jīng)驗(yàn)的開發(fā)者摔跤。Cfeecrip的劣勢(shì)是什么?是的,在你和JavaScrip之間了編譯這一步。Cfeecript也在嘗試盡力通過產(chǎn)生優(yōu)雅的可讀性強(qiáng)的JavaScrip,以及在服務(wù)器端集成自動(dòng)編譯來彌補(bǔ)feeScrip發(fā)展迅猛,相關(guān)的IRC列表也是人才濟(jì)濟(jì),如果你有什么問題的話,都會(huì)得到迅速的解答。說在Node.js上。還有,CoffeeScript越來越廣泛,有的集成,比方說它已經(jīng)是Rails3.1 點(diǎn)擊TryCoffeeScript。這個(gè)使用瀏覽器版的CoffeeScript編譯器,把在左邊面板任意<scriptsrc=" coffee-script.js"type="text/javascript"charset="utf-8"></script><scripttype="text/coffeescript">#SomeCoffeeScriptnpminstall-gcoffee- pilemy-CoffeeScript語#AAmultilinecomment,perhapsa不的話,就很容易在定義變量時(shí)遺漏var關(guān)鍵字導(dǎo)致產(chǎn)生全局變量。CoffeeScript通過myVariable= exports=exports.MyVariable="foo-func=->func=-#Anextratimes=(a,b)->a*times=(a=1,b=2)->a*你還可以使用參數(shù)槽(splats)接收多個(gè)參數(shù),使用...sum=(nums...)->result=0nums.forEach(n)->result+=ntrigger=(events...)->events.splice(1,0,this)a="Howdy!"alerta#Equivalentalertinspect#Equivalentalert如果在調(diào)用一個(gè)函數(shù)時(shí)你沒有傳遞參數(shù),CfeeScript就沒有辦法判斷出你打算調(diào)用這個(gè)函數(shù),還是只是把它當(dāng)作一個(gè)變量。從這點(diǎn)來看,CfeeSript的行為與Ruby有些差異,后者總是會(huì)調(diào)用函數(shù)的變量,CfeeScript更像Pythn。這已經(jīng)變成了我的feeScrip中常見的錯(cuò)誤。因此,在你打算無參數(shù)調(diào)用函數(shù)時(shí)多留個(gè)心眼,別忘了加上括號(hào)。this.clickHandler=->alert"clicked"element.addEventListener"click",(e)=>this.clickHandler(e)的object1={one:1,two:#Withoutobject2=one:1,two:#Usingnewlinesinsteadofobject3one:two:User.create(name:"John同樣的,數(shù)組可以使用空格來代替分隔作用的逗號(hào),但是方括號(hào)([])還是需要的array1=[1,2,array2=[23]array3=iftrue=="We'reiftrue!=truethen#Equivalent#(1>0)?"Ok":if1>0then"Ok"elsealert"It'scold!"ifheat<ifnottruethenunless與not類似的風(fēng)格,CoffeeScript還為大家提供了is語句,編譯過去就是===iftrueis"Typecoercion你可以使用isnt代替isnotiftrueisntalert"Opposite在上面的例子中你可以已經(jīng)注意到了,CoffeeScript會(huì)把==操作符轉(zhuǎn)化為===,把!=轉(zhuǎn)化為favourite_color="Blue.No,question="Bridgekeeper:What...isyourfavouriteGalahad:#{favourite_color}Bridgekeeper:Wrong!"就上例所示,多行字符串是允許的,不需要在沒一行前添加+fornamein["Roger","Roderick","Brian"]alert"Release#{name}"forname,iin["Rogerthepickpocket","Rodericktherobber"]alert"#{i}-Release#{name}"releaseprisonerforprisonerin["Roger","Roderick",prisoners=["Roger","Roderick",releaseprisonerforprisonerinprisonerswhenprisoner[0]names=sam:seaborn,donna:alert("#{first}#{last}")forfirst,lastofnum=minstrel=whilenum-=num+"BraveSirRobinranrange=firstTwo=["one","two",numbers=numbers[3..5]=[-3,-4,-my="mywords=["rattled","roudy","rebbles","ranks"]alert"Stopwaggingme"if"ranks"inwordsCoffeeScript采用了一些有用的別名來減少輸入量。其中一個(gè)就是@,是this@saviour=另外一個(gè)是::,prototype的別名User::first=->praiseif你還能用它來替換||velocity=southern?類classanimal=new init類似。classAnimalconstructor:(name)->@name=classAnimalconstructor:(@name)->animal=newAnimal("Parrot")alert"Animalisa#{}"classAnimalprice:5sell:(customer)-animal=newAnimalanimal.sell(newCustomer)classprice:sell:alert"Giveme#{@price}animal=newclassthis.find=(name)-classAnimal@find:(name)->繼承與classAnimalconstructor:(@name)->alive:-classParrotextendsAnimalconstructor:->dead:-notParrot.super.constructor.call(this"Parrot");。實(shí)際上,這與classAnimalconstructor:(@name)->classParrotextendsAnimalAnimal::rip=trueparrot=newalert("Thisparrotisnomore")ifextend=(obj,mixin)-obj[name]=methodforname,methodofmixininclude=(klass,mixin)->totype,mixin#includeParrot,isDeceased:true(new =['extended',classModule@extend:(obj)->forkey,valueofobjwhenkeynotinmodule@[key]=value@include:(obj)-forkey,valueofobjwhenkeynotinmodule#Assignpropertiestotheprototype@::[key]=value classProperties=find:(id)->create:(attrs)-instanceProperties=save:->classUserextendsModule@extendclassProperties@includeinstanceProperties#user=user=newUserORMfind:(id)->create:(attrs)->extended:->save:->classUserextendsModule@extendORMCoffeeScript慣用在JavaScript中可以使用新加入的forEach()也可以使用老的C語言風(fēng)格的for循環(huán)來迭代一個(gè)數(shù)組。如果你打算使用一些在ECMAScript5提到的JavaScript新特性的話,我推薦你把這個(gè)shim(薄層)來模擬這些特性以便支持老的瀏覽器。for(vari=0;i<array.length;i++)i){myFunction(item)myFunction(item)foritemin這種語法易讀簡潔(你也這么認(rèn)為),而且更棒的是這在背后會(huì)被編譯為for循環(huán)。換varresult=for(vari=0;i<array.length;i++)varresult=array.map(function(item,returnresult=(foriteminvarresult=for(vari=0;i<array.length;if(array[i].name=="test")result=array.filter(function(item,==result=(ispassed=[]failed=(ifscore>60thenpassedelsefailed).pushscoreforin[49,58,76,82,88,#passed=(scoreforscoreinscoreswhenscore>passed=[]failed=forscorein[49,58,76,82,88,(ifscore>60thenpassedelsefailed).push通常使用indexOf()來測試一個(gè)數(shù)組中是否包含某個(gè)值。不過真讓人驚訝Internetvarincluded=(array.indexOf("test")!=-included="test"inincluded="alongteststring".indexOf("test")isnt-或者更好一點(diǎn),借助于位操作符我們就不用與-1進(jìn)行比較 ="alongteststring"included=!!~string.indexOf"test"varobject={one:1,two:for(varkeyinobject)alert(key+"="+object={one:1,two:alert("#{key}=#{value}")forkey,valueof這個(gè)技巧雖然不是CoffeeScript的專利,但是我覺得它非常有用,值得一提。Math.max和Math.max[14,35,-7,46,98]...#Math.min[14,35,-7,46,98]...#-Loglog:->LoglogPrefix:log:(args...)->args.unshift(@logPrefix)if@logPrefix偏愛英語風(fēng)格的代碼的話,也可以使用is代替==,isnt代替!=string="migratingcoconuts"string==string#truestringisstring#trueCoffeeScript還有另外一個(gè)非常好的擴(kuò)展,Ruby程序員可將其看作像是||=這樣的模式hashor=hash?=someObject={a:'valuefora',b:'valueforb'{a,b}=console.log"ais'#{a}',bis{join,resolve}=join('/Users',沒有什么差別。在CoffeeScript中使用jQuery顯得非常優(yōu)雅,因?yàn)閖Query的API中有很多回#Uselocal$=$-#$(".el").click->既然CoffeeScript編譯輸出的所有代碼都被包裹在一個(gè)函數(shù)中,因此我們可以使用一個(gè)局部變量$來代替jQuery。就算在jQuery的noconfict模式或者$被重定義的情況下,我 #Executefunction type=do->classToType={}fornamein"BooleanNumberStringFunctionArrayDateRegExpUndefinedNull".split("")classToType["[object"+name+"]"]=#Returna(obj)-strType=CoffeeScriptt如第一章所說,我們可以使用coffee命令來編譯CoffeeScript pile--outputlibCake是一個(gè)超級(jí)簡單的與Make和Rake類似的構(gòu)建工具。該庫被在coffee-script你可以使用在一個(gè)名為Cakefile的文件中使用CoffeeScript來定義任務(wù)。Cake可以去 創(chuàng)建一個(gè)名為Cakefile的文件,還有兩個(gè)——lib和src。把下面的代碼添加到Cakefs=require{print}=require{spawn}=requirebuild=(callback)-coffee=spawn'coffee',['-c','-o','lib','src']coffee.stderr.on'data',(data)->process.stderr.writedata.toString()coffee.stdout.on'data',(data)->printdata.toString()coffee.on'exit',(code)->callback?()ifcodeistask'build','Buildlib/fromsrc/',-><!DOCTYPE<scriptsrc="lib/app.js"type="text/javascript"我們?cè)贑offeeScript代碼變了之后還需要手動(dòng)的運(yùn)行cakebuild命令,這很不理想。幸運(yùn)的是,coffee命令接受另外一個(gè)--watch參數(shù),指示它監(jiān)視一個(gè)的變化并且按需重新task'watch','Watchsrc/forchanges',-coffee=spawn'coffee',['-w','-c','-o','lib','src']coffee.stderr.on'data',(data)->process.stderr.writedata.toString()coffee.stdout.on'data',(data)->printtask'open','Openindex.html',-#Firstopen,thenwatchspawn'open','index.html'invoke'watch'option'-o','--output[DIR]','outputdir'task'build','Buildlib/fromsrc/',->#Nowwehaveaccesstoa`options`coffee=spawn'coffee',['-c','-o',options.outputor'lib','src']coffee.stderr.on'data',(data)->process.stderr.writedata.toString()coffee.stdout.on'data',(data)->printdata.toString()Rails3.1通過Sprockets&theassetpipeline實(shí)現(xiàn)了對(duì)CoffeeScript的支持。的Rack服務(wù)器是其他可選方案之一,比如說37signal的Pow和JoshuaPeek的Nack都是。如果既然你基本已經(jīng)了解了CoffeeScript的語法,那現(xiàn)在讓我們來探索下如何使用它來實(shí)彈了本章的范圍,需要的話我建議你到JavaScriptWebApplications翻看我的書,或者使用像Backbone或者Spine這類框架?,F(xiàn)在先不管那些,在這里我們使用CommonJS模塊來構(gòu)建結(jié)構(gòu)&那什么CommonJS模塊到底是什么呢?好的,如果你用過NodeJS的話,你大概沒有 有的JavaScript實(shí)現(xiàn)。目標(biāo)是寫一個(gè)給Rhino的類庫也可以用于Node。終于這種思想被移植 User=##SomemyFineProperty=我采用Stitch這個(gè)不太有名的類庫作為解決方案。Stitch的作者是SamStephenson,其思想賴。噢,我差點(diǎn)忘記說,它還能編譯CoffeeScript、JS模板、LESSCSS和Sass。首先,如果你必須安裝 :stitch=require("stitch")express=require("express") =package=#SpecifythepathsyouwantStitchtoautomaticallypaths: dirname+"/app"#Specifyyourbase dirname+])app=app.configure-app.set"views", dirname+"/views"app.useapp.routerapp.useexpress.static(dirname+"/public")app.get"/application.js",package.createServer()port=argv[0]orprocess.env.PORTorconsole.log"Startingserveronport:#{port}"app.listenport{"name":"version":"0.0.1","dependencies":{"stitch":"express":}}npminstallnpminstall-gcoffee-coffee module.exports=App=init:->#Bootstrapthe <!DOCTYPE<!--RequirethemainStitchfile--<scriptsrc="/application.js"type="text/javascript"<scripttype="text/javascript"charset="utf-.addEventListener("DOMContentLoaded",function(){varApp=require("app");},#module.exports=classUserconstructor:(@name)->#User=JavaScript模<%if@projects.length:<%forprojectin@projects:<ahref="<%=project.url%>"><%=<p><%=project.description<%end<%else:%>Noprojects<%end<%expression<%=expression<%-expression <%end%>來表示縮進(jìn)塊<%if@project.isOnHold():%>OnHold<%end<%if@project.isOnHold():%>OnHold<%end<%="OnHold"if@project.isOnHold()<label>Name:<%=@namerequire("views/users/show")(newUser=require("models/user")App=init:-template=require("views/users/show") =template(new#ObviouslythiscouldbesprucedupbyjQueryelement=.createElement("div")element.innerHTML=viewmodule.exports=echo"web:coffeeindex.coffee">gitinitgitaddgitcommit-m"FirstherokucreatemyAppName--stackcedargitpushherokumasterherokuMustache、Jade或者CoffeeKup(使用純集成了CoffeeScriptMVC框架Spine。node-browsify是另外一個(gè)類似的項(xiàng)目。如果你想使用express集成的更底層的東西,TrevorBurnham的connect-assets不錯(cuò)。JavaScript的子 ={=}化。還有,with語句并不能被像uglify-js這樣的壓縮工具壓縮掉。因此它在將來的usersCount= //vargroupsCount= //pagesCount= //varpostsCount=4;//outerScope=do-innerScope=varouterScope;outerScope=true;(function(){varreturninnerScope=注意CfeeScrip是如何自動(dòng)的在上下文中第一次使用時(shí)自動(dòng)的初始化變量(使用),覆用,以你心package=classHembuild:->#Overwritesouterpackage hemPackage:->classwindow.Assetconstructor:->function()(window.options||function(){}(window.options||myObj=delete:"Iama}myObj.class=-varmyObj;myObj={"delete":"IamamyObj["class"]=function()來自JavaScriptGarden’sequalitysection,對(duì)這個(gè)問題進(jìn)行過深入的研究。00"0alert("EmptyArray")unless[].lengthalert("EmptyString")unless""alert("Number0") unless0alert("Thisisnotcalled")unlessfunctionwem()if(true)functiondeclaration()return}}elsefunctiondeclaration()return}}如果你想更加深入的了解函數(shù)定義式的話,你可以JuriyZaytsev的指南,他對(duì)標(biāo)準(zhǔn)進(jìn)varwem= token錯(cuò)誤。既可以使用括號(hào)也可以多加一個(gè)點(diǎn)來解決這個(gè)問使用99%的時(shí)間中,應(yīng)該有更好更安全的替代方式(比方說方括號(hào))#Don'tdomodel=#Usesquarebracketsmodel=使用typeofundefinedVaris為了說明問題所在,這是從JavaScriptGarden拿來的表格,該表格展示了這個(gè)類型檢測的關(guān)newnewnewnewnew

newArray(1,2,3) new newRegExp("meow") new 那在JavaScript中我們?nèi)绾巫鲱愋蜋z查呢?還好有Ototype.toString()來解type=do->classToType={}fornamein"BooleanNumberStringFunctionArrayDateRegExpUndefinedNul

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論