Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again

CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again

FOWA 2011

Sam Stephenson

October 05, 2011
Tweet

Transcript

  1. var names = []; for (var i = 0, l

    = people.length; i < l; i++) { var person = people[i]; var name = person.name. slice(0, 1).toUpperCase() + person.name.slice(1); names.push(name); }
  2. package com.example.gwt.helloworld.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.Window;

    import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.RootPanel; public class HelloWorld implements EntryPoint { @Override public void onModuleLoad() { Label label = new Label("Hello world"); Button button = new Button("Say something"); button.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { Window.alert("Hello again"); } }); RootPanel.get().add(label); RootPanel.get().add(button); } }
  3. <?xml version="1.0" encoding="UTF-8"?> <module rename-to='com_example_gwt_helloworld'> <!-- Inherit the core Web

    Toolkit stuff. --> <inherits name='com.google.gwt.user.User'/> <inherits name='com.google.gwt.user.theme.standard.Standard'/> <!-- Specify the app entry point class. --> <entry-point class='com.example.gwt.helloworld.client.HelloWorld'/> </module> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- Default page to serve --> <welcome-file-list> <welcome-file>Com_example_gwt_helloworld.html</welcome-file> </welcome-file-list> </web-app>
  4. function hello(){var l='',F='" for "gwt:onLoadErrorFn"',D='" for "gwt:onPropert yErrorFn"',n='"><\/script>',p='#',r='/',vb='02EDD05CEF7D978C649BF91CC66AB635.ca che.html',sb='28600060343BDDEB1FD83487846D090C.cache.html',ub='9EDF9C067C3A475F 6EA7A16003CA4979.cache.html',Fb='<script

    defer="defer">hello.onInjectionDone(\' hello\')<\/script>',dc='<script id="',A='=',q='?',C='Bad handler "',tb='D69BADE 681FFFC6071DFA4FC25EF1DC5.cache.html',Eb='DOMContentLoaded',wb='F26BFE33DA14C23 176C7BC08D58AA43F.cache.html',o='SCRIPT',cc='__gwt_marker_hello',s='base',nb='b egin',cb='bootstrap',u='clear.cache.gif',z='content',bc='end',lb='gecko',mb='ge cko1_8',yb='gwt.hybrid',xb='gwt/standard/standard.css',E='gwt:onLoadErrorFn',B= 'gwt:onPropertyErrorFn',y='gwt:property',Db='head',qb='hosted.html?hello',Cb='h ref',kb='ie6',ab='iframe',t='img',bb="javascript:''",zb='link',pb='loadExternal Refs',v='meta',eb='moduleRequested',ac='moduleStartup',jb='msie',w='name',gb='o pera',db='position:absolute;width:0;height:0;border:none',Ab='rel',ib='safari', rb='selectingPermutation',x='startup',m='hello',Bb='stylesheet',ob='unknown',fb ='user.agent',hb='webkit';var fc=window,k=document,ec=fc.__gwtStatsEvent?functi on(a){return fc.__gwtStatsEvent(a)}:null,zc,pc,kc,jc=l,sc={},Cc=[],yc=[],ic=[], vc,xc;ec&&ec({moduleName:m,subSystem:x,evtGroup:cb,millis:(new Date()).getTime( ),type:nb});if(!fc.__gwt_stylesLoaded){fc.__gwt_stylesLoaded={}}if(!fc.__gwt_sc riptsLoaded){fc.__gwt_scriptsLoaded={}}function oc(){var b=false;try{b=fc.exter nal&&(fc.external.gwtOnLoad&&fc.location.search.indexOf(yb)==-1)}catch(a){}oc=f unction(){return b};return b}function rc(){if(zc&&pc){var c=k.getElementById(m) ;var b=c.contentWindow;if(oc()){b.__gwt_getProperty=function(a){return lc(a)}}h ello=null;b.gwtOnLoad(vc,m,jc);ec&&ec({moduleName:m,subSystem:x,evtGroup:ac,mil lis:(new Date()).getTime(),type:bc})}};function mc(){var j,h=cc,i;k.write(dc+h+ n);i=k.getElementById(h);j=i&&i.previousSibling;while(j&&j.tagName!=o){j=j.prev iousSibling}function f(b){var a=b.lastIndexOf(p);if(a==-1){a=b.length}var c=b.i ndexOf(q);if(c==-1){c=b.length}var d=b.lastIndexOf(r,Math.min(c,a));return d>=0 ?b.substring(0,d+1):l};if(j&&j.src){jc=f(j.src)}if(jc==l){var e=k.getElementsBy TagName(s);if(e.length>0){jc=e[e.length-1].href}else{jc=f(k.location.href)}}els e if(jc.match(/^\w+:\/\//)){}else{var g=k.createElement(t);g.src=jc+u;jc=f(g.sr
  5. import pyjd # this is dummy in pyjs. from pyjamas.ui.RootPanel

    import RootPanel from pyjamas.ui.Button import Button from pyjamas.ui.HTML import HTML from pyjamas.ui.Label import Label from pyjamas import Window import pygwt def greet(fred): fred.setText("No, really click me!") Window.alert("Hello, AJAX!") if __name__ == '__main__': pyjd.setup("public/Hello.html?fred=foo#me") b = Button("Click me", greet, StyleName='teststyle') h = HTML("<b>Hello World</b> (html)", StyleName='teststyle') l = Label("Hello World (label)", StyleName='teststyle') base = HTML("Hello from %s" % pygwt.getModuleBaseURL(), StyleName='teststyle') RootPanel().add(b) RootPanel().add(h) RootPanel().add(l) RootPanel().add(base) pyjd.run()
  6. I love/prefer {insert AJAX / Javascript framework here}, how do

    I use it? Not being funny or anything, but unless you have the resources of google or lots of money or lots of time, or you can gather enough people to make it so that everyone has less work to do: you don't. huh? why?? Some of the widgets in DojoX / Ext-JS are really cute! I want them! waaah! You are not in Kansas any more. Pyjamas is declarative- style programming, using a "real" programming language. All those widget-sets were designed to be driven from inside HTML (a style of web development which, using Pyjamas, you have just left far behind) and by inserting javascript snippets into the HTML. If you try that with a Pyjamas app, you are not only likely to get yourself into an
  7. I love/prefer {insert AJAX / Javascript framework here}, how do

    I use it? Not being funny or anything, but unless you have the resources of google or lots of money or lots of time, or you can gather enough people to make it so that everyone has less work to do: you don't. huh? why?? Some of the widgets in DojoX / Ext-JS are really cute! I want them! waaah! You are not in Kansas any more. Pyjamas is declarative- style programming, using a "real" programming language. All those widget-sets were designed to be driven from inside HTML (a style of web development which, using Pyjamas, you have just left far behind) and by inserting javascript snippets into the HTML. If you try that with a Pyjamas app, you are not only likely to get yourself into an
  8. I love/prefer {insert AJAX / Javascript framework here}, how do

    I use it? Not being funny or anything, but unless you have the resources of google or lots of money or lots of time, or you can gather enough people to make it so that everyone has less work to do: you don't. huh? why?? Some of the widgets in DojoX / Ext-JS are really cute! I want them! waaah! You are not in Kansas any more. Pyjamas is declarative- style programming, using a "real" programming language. All those widget-sets were designed to be driven from inside HTML (a style of web development which, using Pyjamas, you have just left far behind) and by inserting javascript snippets into the HTML. If you try that with a Pyjamas app, you are not only likely to get yourself into an
  9. @implementation AppController : CPObject { } - (void)applicationDidFinishLaunching:(CPNotification)note { theWindow

    = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask]; contentView = [theWindow contentView]; var label = [[CPTextField alloc] initWithFrame:CGRectMakeZero()]; [label setStringValue:@"Hello World!"]; [label setFont:[CPFont boldSystemFontOfSize:24.0]]; [label sizeToFit]; [label setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin]; [label setFrameOrigin:CGRectMake(100,100)]; [contentView addSubview:label]; [theWindow orderFront:self]; } @end
  10. CoffeeScript is a little language that compiles into JavaScript. Underneath

    all of those embarrassing braces and semicolons, JavaScript has always had a gorgeous object model at its heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way. The golden rule of CoffeeScript is: “It’s just JavaScript”. The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime.
  11. CoffeeScript is a little language that compiles into JavaScript. Underneath

    all of those embarrassing braces and semicolons, JavaScript has always had a gorgeous object model at its heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way. The golden rule of CoffeeScript is: “It’s just JavaScript”. The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime.
  12. CoffeeScript is a little language that compiles into JavaScript. Underneath

    all of those embarrassing braces and semicolons, JavaScript has always had a gorgeous object model at its heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way. The golden rule of CoffeeScript is: “It’s just JavaScript”. The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime.
  13. Good Part: No more var lastClick = 0 $("a").click ->

    now = new Date().getTime() if now - lastClick > 100 $("#message").show() lastClick = now
  14. Good Part: No more var var lastClick = 0 $("a").click

    -> var now = new Date().getTime() if now - lastClick > 100 $("#message").show() lastClick = now
  15. Good Part: Strict comparisons "true" == true // true "true"

    === true // false "0" == false // true "0" == 0 // true 0 === false // false "" == false // true
  16. Good Part: Strict comparisons "true" is true // false "true"

    is "true" // true "0" is false // false "0" is 0 // false 0 is 0 // true "" is false // false
  17. 2. Significant Whitespace if (url) { $.get(url, function(data) { return

    $("#result").html(data); }); } else { $("#error").show(); }
  18. 2. Significant Whitespace var readConfiguration = function(callback) { return path.exists(filename,

    function(err, exists) { if (exists) { return fs.readFile(filename, callback); } else { return callback(false); } }); };
  19. 2. Significant Whitespace readConfiguration = (callback) -> path.exists filename, (err,

    exists) -> if exists fs.readFile filename, callback else callback false
  20. 3. Bare Objects $.ajax({ url: path, timeout: 5, data: {

    from: "workspace" }, dataType: "html", success: function(data) { return $("#result").html(data); } });
  21. 3. Bare Objects $.ajax url: path, timeout: 5, data: from:

    "workspace", dataType: "html", success: (data) -> $("#result").html data
  22. 4. Everything’s an Expression switch keyCode when 38 command =

    "previous" when 40 command = "next" when 13 command = "select"
  23. 4. Everything’s an Expression command = switch keyCode when 38

    then "previous" when 40 then "next" when 13 then "select"
  24. 4. Everything’s an Expression getCommand = (keyCode) -> switch keyCode

    when 38 then "previous" when 40 then "next" when 13 then "select"
  25. 5. Comprehensions var names, person; names = (function() { var

    _i, _len, _results; _results = []; for (_i = 0, _len = people.length; _i < _len; _i++) { person = people[_i]; if (age > 27) { _results.push(capitalize(person.name)); } } return _results; })();
  26. 6. Classes & Inheritance class Photo constructor: (url) -> this.url

    = url createElement: -> $("<img>").attr "src", this.url
  27. 6. Classes & Inheritance class Photo constructor: (url) -> this.url

    = url createElement: -> $("<img>").attr "src", this.url
  28. 6. Classes & Inheritance class Photo constructor: (url) -> @url

    = url createElement: -> $("<img>").attr "src", @url
  29. 6. Classes & Inheritance var Thumbnail; var __hasProp = Object.prototype.hasOwnProperty,

    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; Thumbnail = (function() { __extends(Thumbnail, Photo); function Thumbnail() { Thumbnail.__super__.constructor.apply(this, arguments); } Thumbnail.prototype.createElement = function() { var $el; $el = Thumbnail.__super__.createElement.apply(this, arguments); return $el.height(100); }; return Thumbnail; })();
  30. 7. Bound Functions class PersonView constructor: (@person, @el) -> request:

    -> $.get @person.url, (data) -> $(@el).html data
  31. 7. Bound Functions class PersonView constructor: (@person, @el) -> request:

    -> $.get @person.url, (data) -> $(@el).html data
  32. 7. Bound Functions class PersonView constructor: (@person, @el) -> request:

    -> $.get @person.url, (data) => $(@el).html data
  33. 7. Bound Functions class PersonView constructor: (@person, @el) -> $(@el).bind

    "click", @showName showName: => $(@el).html @person.name
  34. 10. String Syntax render = (person) -> """ <div class="person">

    <a href="#{person.url}">#{person.name}</a> <span>#{person.profession}</span> </div> """