CoffeeScript CoffeeScript 是個能夠編譯成 JavaScript 的簡易語言 。受到 Ruby、Python 與 Haskell 等語言的啟發,CoffeeScript 增強了 JavaScript 的簡潔性與可讀性。
直接來個簡單的概觀看看 賦值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 number = 42 opposite = true number = -42 if oppositesquare = (x) -> x * x list = [1 , 2 , 3 , 4 , 5 ] math = root: Math .sqrt square: square cube: (x) -> x * square xrace = (winner, runners...) -> print winner, runners alert "I knew it!" if elvis? cubes = (math.cube num for num in list)
編譯成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 var cubes, list, math, num, number, opposite, race, square; number = 42 ; opposite = true ;if (opposite) { number = -42 ; } square = function (x ) { return x * x; }; list = [1 , 2 , 3 , 4 , 5 ]; math = { root: Math .sqrt, square: square, cube: function (x ) { return x * square(x); } }; race = function (winner, ...runners ) { return print(winner, runners); };if (typeof elvis !== "undefined" && elvis !== null ) { alert("I knew it!" ); } cubes = (function ( ) { var i, len, results; results = []; for (i = 0 , len = list.length; i < len; i++) { num = list[i]; results.push(math.cube(num)); } return results; })();
CoffeeScript 2 在 CoffeeScript 2 中,最大的改變莫過於輸出的 JavaScript 程式碼格式(現在會輸出成較新的 ES6 或 ES2015 風格)。
而 CoffeeScript 中的 =>
亦會變成 JS 中的 =>
,且 CoffeeScript 的 class 也會等同於 JS 的 class 類別標籤…等。還有主要追加的新功能,像是:非同步函式和 JSX。
非同步函式 ES2017 的非同步函式現在能夠透過 await
關鍵字進行使用,不需要額外使用 async
,使得非同步函式在 CoffeeScript 中寫起來就像一般的函式。
yield return
可以強迫函式成為一個產生器函式,而 await return
則能夠強迫讓一個函式成為非同步函式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 new Promise (resolve) ->window .setTimeout resolve, mssay = (text) -> window .speechSynthesis.cancel() window .speechSynthesis.speak new SpeechSynthesisUtterance textcountdown = (seconds) -> for i in [seconds..1 ] say i await sleep 1000 say "Blastoff!" countdown 3
編譯成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 var countdown, say, sleep; sleep = function (ms ) { return new Promise (function (resolve ) { return window .setTimeout(resolve, ms); }); }; say = function (text ) { window .speechSynthesis.cancel(); return window .speechSynthesis.speak(new SpeechSynthesisUtterance(text)); }; countdown = async function (seconds ) { var i, j, ref; for (i = j = ref = seconds; (ref <= 1 ? j <= 1 : j >= 1 ); i = ref <= 1 ? ++j : --j) { say(i); await sleep(1000 ); } return say("Blastoff!" ); }; countdown(3 );
JSX JSX 是能夠帶有類 XML 元素結構的 JavaScript。雖然初期是為了 React 所設計的,但這並不是一個框架或者函式庫。
CoffeeScript 不需要任何的額外擴充套件或設定,就能夠支援類 XML 元素。XML 元素會被編譯並輸出成一般的 JSX 結果,就像 Babel 與 React JSX 的轉化。不過 CoffeeScript 並不會輸出用以呼叫 React.createElement
的函式,亦不會有任何與 React 和其他框架有關的程式碼。
就像 JSX 和 HTML 那樣,你可以使用 <
與 >
符號。你也能在 { 和 } 標籤中使用 CoffeeScript。為了避免編譯器錯誤,當 <
和 >
是用作「小於」或「大於」符號時,你應該透過空白來避免它們被誤認為 XML 標籤。所以你該使用 i < len
而不是 i<len
。
1 2 3 4 5 6 7 8 9 renderStarRating = ({ rating, maxStars }) -> <aside title={"Rating: #{rating} of #{maxStars} stars" }> {for wholeStar in [0. ..Math .floor(rating)] <Star className="wholeStar" key={wholeStar} />} {if rating % 1 isnt 0 <Star className="halfStar" />} {for emptyStar in [Math .ceil(rating)...maxStars] <Star className="emptyStar" key={emptyStar} />} </aside>
編譯成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 var renderStarRating; renderStarRating = function ({rating, maxStars} ) { var emptyStar, wholeStar; return <aside title ={ `Rating: ${rating } of ${maxStars } stars `}> {(function() { var i, ref, results; results = []; for (wholeStar = i = 0, ref = Math.floor(rating); (0 <= ref ? i < ref : i > ref); wholeStar = 0 <= ref ? ++i : --i) { results.push(<Star className ="wholeStar" key ={wholeStar} /> ); } return results; })()} {(rating % 1 !== 0 ? <Star className ="halfStar" /> : void 0)} {(function() { var i, ref, ref1, results; results = []; for (emptyStar = i = ref = Math.ceil(rating), ref1 = maxStars; (ref <= ref1 ? i < ref1 : i > ref1); emptyStar = ref <= ref1 ? ++i : --i) { results.push(<Star className ="emptyStar" key ={emptyStar} /> ); } return results; })()} </aside > ; };