SlideShare uma empresa Scribd logo
1 de 89
Baixar para ler offline
Clean JavaScript


http://www.flickr.com/photos/hoshikowolrd/5151171470/




                                                         Sapporo.js
SaCSS vol.29 - 2011.11.26                              (Ryunosuke SATO)
Community for people who like JavaScript.




      Sapporo.js
Sapporo.js




http://sapporojs.org
Sapporo.js




Now learning
I’m a programmer
@tricknotes
Clean JavaScript


http://www.flickr.com/photos/hoshikowolrd/5151171470/




                                                         Sapporo.js
SaCSS vol.29 - 2011.11.26                              (Ryunosuke SATO)
JavaScript
JavaScript
about JavaScript
Works in everywhere!
http://www.flickr.com/photos/peco-sunnyday/2752403413/




                interesting!
I like
JavaScript is most popular!
but...
http://www.flickr.com/photos/maynard/6105929170/




                              difficult
Now training...
?
                     ?
How to face the difficulty
Oops... :(
some ideas
with

DOM
point
HTML   JavaScript
HTML   JavaScript
here!




HTML       JavaScript
practice
- Attach events from outer -

problem


   JavaScript
- Attach events from outer -

solution


HTML
 JavaScript
- Attach events from outer -




<a onclick=”showMessage()”>Click me</a>




                                    code smell
- Attach events from outer -




<a id=”showMessage”>Click me</a>


var a = document.getElementById(‘showMessage’);
a.addEventListener(‘click’, showMessage);



                                       improvement
- Separate from Selector -

problem


HTML   id   class
- Separate from Selector -

solution



HTML   id   class
- Separate from Selector -




function showPhoto(photoId) {
  var photo = document.getElementById(‘photo-’ + photoId);
  // do ...
}
- Separate from Selector -




function showPhoto(photoId) {
  var photo = document.getElementById(‘photo-’ + photoId);
  // do ...
}




                                              code smell
- Separate from Selector -


var showPhoto = function(element) {
  // do ...
}

var photo = document.getElementById(‘photo-12’);
showPhoto(photo);




                                      improvement
- modulized functions -

problem
- modulized functions -

solution
- modulized functions -

// users.js
var showUserName = function() {
  // do somethig
}

var showUserAge = function(){
  // do somethig
}

var validateUserForm = function() {
  // do somethig
}                                   code smell
- modulized functions -

// users.js
var showUserName = function() {
  // do somethig
}                             global

var showUserAge = function(){
  // do somethig
}

var validateUserForm = function() {
  // do somethig
}
- modulized functions -
// users.js
var users = {};
                               global
users.showName = function () {
  // do somethig
}

users.showAge = function (){
  // do somethig
}

users.validateForm = function () {
  // do somethig
}
- modulized functions -
// users.js
(function(global) {
  global.users = {};            global

 users.showName = function () {
   // do somethig
 }

  // ...
)(this);


                                    improvement
overwrite behavior -

problem


     JavaScript
 DOM
overwrite behavior -
solution


 DOM
           DOM
overwrite behavior -

// using jQuery

$(‘a#showDialog’).click(function() {
  $.ajax(‘/about’, {
    success: function(html) {
      // do something...
    }
  });
});




                                       code smell
overwrite behavior -

// using jQuery

$(‘a#showDialog’).click(function() {
  $.ajax($(this).attr(‘href’), {
    success: function(html) {
      // do something...
    }
  });
});




                                   improvement
shallow scope -

problem
shallow scope -

solution


        2            function


    →         this
shallow scope -


// using jQuery

var $elements = $(‘a#remote’);
$elements.click(function() {
  var url = $(this).attr(‘href’);
  $.ajax(url, {
    success: function(html) {
      var text = $(html).text();
      $element.text(text);
    }
  });
  return false;
});
shallow scope -


// using jQuery

var $elements = $(‘a#remote’);
$elements.click(function() {         deep
  var url = $(this).attr(‘href’);
  $.ajax(url, {
    success: function(html) {
      var text = $(html).text();
      $element.text(text);
    }
  });
  return false;
});

                                            code smell
shallow scope -


// using jQuery

var $elements = $(‘a#remote’);
$elements.click(function() {
  var url = $(this).attr(‘href’);
  $.ajax(url, {
    success: function(html) {
       var text = $(html).text();
       $(this).text(text);
    },
    context: this
  });
  return false;
});
                                           improvement
DOM       - DOM to model -

problem


DOM
DOM        - DOM to model -

solution


DOM
DOM                                     - DOM to model -


var element = document.getElementById(‘message’);
element.addEventListener(‘click’, function() {
  // this == element
  if (this.getAttribute(‘data-is-checked’)) {
    this.setAttribute(‘data-is-checked’, true);
    this.innerText = ‘clicked!’;
  }
});




                                                code smell
DOM                                                        - DOM to model -


var domToModel = function(element, Model) {
  var method, name, object, parent, proto;
  model = Object.create(element);
  proto = Model.prototype;
  for (name in proto) {
    method = proto[name];
    model[name] = method;
  }
  Model.apply(model);
  return model;
};

var CustomElement = function() {};
CustomElement.prototype.showText = function() {
   if (!this.getAttribute(‘data-is-checked’)) {   var element = document.getElementById(‘message’);
    this.setAttribute(‘data-is-checked’, true);   var model = domToModel(element, CustomElement);
    this.innerText = ‘clicked!’;                  model.addEventListener(‘click’, function() {
  }                                                 model.showText();
};                                                });
DOM                                                        - DOM to model -


var domToModel = function(element, Model) {
  var method, name, object, parent, proto;
  model = Object.create(element);
  proto = Model.prototype;
  for (name in proto) {
    method = proto[name];
    model[name] = method;
  }
  Model.apply(model);
  return model;
};

var CustomElement = function() {};
CustomElement.prototype.showText = function() {
   if (!this.getAttribute(‘data-is-checked’)) {   var element = document.getElementById(‘message’);
    this.setAttribute(‘data-is-checked’, true);   var model = domToModel(element, CustomElement);
    this.innerText = ‘clicked!’;                  model.addEventListener(‘click’, function() {
  }                                                 model.showText();
};                                                });
DOM                                                        - DOM to model -


var domToModel = function(element, Model) {
  var method, name, object, parent, proto;
  model = Object.create(element);
  proto = Model.prototype;
  for (name in proto) {
    method = proto[name];
    model[name] = method;
  }
  Model.apply(model);
  return model;
};

var CustomElement = function() {};
CustomElement.prototype.showText = function() {
   if (!this.getAttribute(‘data-is-checked’)) {   var element = document.getElementById(‘message’);
    this.setAttribute(‘data-is-checked’, true);   var model = domToModel(element, CustomElement);
    this.innerText = ‘clicked!’;                  model.addEventListener(‘click’, function() {
  }                                                 model.showText();
};                                                });

                                                                   improvement
- separate logic with view -

problem
- separate logic with view -
solution
- separate logic with view -

function createTimer() {
  var timerId;
  var startTimer = function(millisec) {
    timerId = setTimeout(function() {
      $(‘.timeout’).text(‘finished’);
    }, millisec);
  }
  var stopTimer = function() {
    clearTimeout(timerId);
  }
  return {
    startTimer: startTimer,
    stopTimer: stopTimer
  }
}
- separate logic with view -

function createTimer() {
  var timerId;
  var startTimer = function(millisec) {
    timerId = setTimeout(function() {
      $(‘.timeout’).text(‘finished’);      view
    }, millisec);
  }
  var stopTimer = function() {
    clearTimeout(timerId);
  }
  return {
    startTimer: startTimer,
    stopTimer: stopTimer
  }
}
                                                   code smell
- separate logic with view -
function Timer(millisec) {
  this. millisec = millisec;
  this.callbacks = [];
  this.timerId = null;
}

Timer.prototype.afterFinish = function(callback) {
  return this.callbacks.push(callback);
};

Timer.prototype.start = function() {
  var callbacks = this.callbacks;
  this.timerId = setTimeout(function() {
    var callback, i, length;
    for (i = 0, length = callbacks.length; i < length; i++) {   var timer = new Timer(1000);
      callback = callbacks[i];                                  timer.afterFinish(function() {
      callback();                                                 $('.timer .message').text('Finished!!');
    }                                                           });
  }, this. millisec);                                           timer.start();
};

Timer.prototype.stop = function() {
  clearTimeout(this.timerId);
}
- separate logic with view -
function Timer(millisec) {
  this. millisec = millisec;
  this.callbacks = [];

}
  this.timerId = null;
                                                                  model
Timer.prototype.afterFinish = function(callback) {
  return this.callbacks.push(callback);
};

Timer.prototype.start = function() {                                      view
  var callbacks = this.callbacks;
  this.timerId = setTimeout(function() {
    var callback, i, length;
    for (i = 0, length = callbacks.length; i < length; i++) {   var timer = new Timer(1000);
      callback = callbacks[i];                                  timer.afterFinish(function() {
      callback();                                                 $('.timer .message').text('Finished!!');
    }                                                           });
  }, this. millisec);                                           timer.start();
};

Timer.prototype.stop = function() {
  clearTimeout(this.timerId);
}                                                                      improvement
A tiny fraction
others...
Pure JavaScript
Application
https://gist.github.com/1362110
http://documentcloud.github.com/backbone/
http://www.sproutcore.com/
interest




http://www.flickr.com/photos/bonguri/4610536789/
reading
Good text
writing
Shall we learn
      about
Clean JavaScript?

Mais conteúdo relacionado

Mais procurados

The Many Ways to Build Modular JavaScript
The Many Ways to Build Modular JavaScriptThe Many Ways to Build Modular JavaScript
The Many Ways to Build Modular JavaScript
Tim Perry
 

Mais procurados (20)

Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Integrating Angular js & three.js
Integrating Angular js & three.jsIntegrating Angular js & three.js
Integrating Angular js & three.js
 
Developing large scale JavaScript applications
Developing large scale JavaScript applicationsDeveloping large scale JavaScript applications
Developing large scale JavaScript applications
 
Javascript MVVM with Vue.JS
Javascript MVVM with Vue.JSJavascript MVVM with Vue.JS
Javascript MVVM with Vue.JS
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widget
 
jQuery Internals + Cool Stuff
jQuery Internals + Cool StuffjQuery Internals + Cool Stuff
jQuery Internals + Cool Stuff
 
VueJS Introduction
VueJS IntroductionVueJS Introduction
VueJS Introduction
 
JavaScript Library Overview
JavaScript Library OverviewJavaScript Library Overview
JavaScript Library Overview
 
MVC pattern for widgets
MVC pattern for widgetsMVC pattern for widgets
MVC pattern for widgets
 
Client Side MVC & Angular
Client Side MVC & AngularClient Side MVC & Angular
Client Side MVC & Angular
 
Modern frontend development with VueJs
Modern frontend development with VueJsModern frontend development with VueJs
Modern frontend development with VueJs
 
Vue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMRVue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMR
 
Vue js 大型專案架構
Vue js 大型專案架構Vue js 大型專案架構
Vue js 大型專案架構
 
AngularJS - Overcoming performance issues. Limits.
AngularJS - Overcoming performance issues. Limits.AngularJS - Overcoming performance issues. Limits.
AngularJS - Overcoming performance issues. Limits.
 
The Many Ways to Build Modular JavaScript
The Many Ways to Build Modular JavaScriptThe Many Ways to Build Modular JavaScript
The Many Ways to Build Modular JavaScript
 
Js unit testing
Js unit testingJs unit testing
Js unit testing
 
Zukunftssichere Anwendungen mit AngularJS 1.x entwickeln (GDG DevFest Karlsru...
Zukunftssichere Anwendungen mit AngularJS 1.x entwickeln (GDG DevFest Karlsru...Zukunftssichere Anwendungen mit AngularJS 1.x entwickeln (GDG DevFest Karlsru...
Zukunftssichere Anwendungen mit AngularJS 1.x entwickeln (GDG DevFest Karlsru...
 
An introduction to Vue.js
An introduction to Vue.jsAn introduction to Vue.js
An introduction to Vue.js
 
Test slideshare document
Test slideshare documentTest slideshare document
Test slideshare document
 
Basic Tutorial of React for Programmers
Basic Tutorial of React for ProgrammersBasic Tutorial of React for Programmers
Basic Tutorial of React for Programmers
 

Semelhante a Clean Javascript

international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
smueller_sandsmedia
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
Jarod Ferguson
 
Javascript Frameworks for Joomla
Javascript Frameworks for JoomlaJavascript Frameworks for Joomla
Javascript Frameworks for Joomla
Luke Summerfield
 

Semelhante a Clean Javascript (20)

Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgets
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
Building Robust jQuery Plugins
Building Robust jQuery PluginsBuilding Robust jQuery Plugins
Building Robust jQuery Plugins
 
BVJS
BVJSBVJS
BVJS
 
Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2
 
JavaScript Refactoring
JavaScript RefactoringJavaScript Refactoring
JavaScript Refactoring
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Secrets of JavaScript Libraries
Secrets of JavaScript LibrariesSecrets of JavaScript Libraries
Secrets of JavaScript Libraries
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Building complex User Interfaces with Sitecore and React
Building complex User Interfaces with Sitecore and ReactBuilding complex User Interfaces with Sitecore and React
Building complex User Interfaces with Sitecore and React
 
Javascript Frameworks for Joomla
Javascript Frameworks for JoomlaJavascript Frameworks for Joomla
Javascript Frameworks for Joomla
 
jQuery
jQueryjQuery
jQuery
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 

Mais de Ryunosuke SATO

How to relaunch "sapporojs.org" ~Introduction to middleman~
How to relaunch "sapporojs.org" ~Introduction to middleman~How to relaunch "sapporojs.org" ~Introduction to middleman~
How to relaunch "sapporojs.org" ~Introduction to middleman~
Ryunosuke SATO
 

Mais de Ryunosuke SATO (17)

片手間JS on Rails
片手間JS on Rails片手間JS on Rails
片手間JS on Rails
 
Ember コミュニティとわたし
Ember コミュニティとわたしEmber コミュニティとわたし
Ember コミュニティとわたし
 
gem の探し方
gem の探し方gem の探し方
gem の探し方
 
Rails あるある
Rails あるあるRails あるある
Rails あるある
 
Node.js を選ぶとき 選ばないとき
Node.js を選ぶとき 選ばないときNode.js を選ぶとき 選ばないとき
Node.js を選ぶとき 選ばないとき
 
もっとはじめる Ember.js !! ~ Getting started with Ember.js more ~
もっとはじめる Ember.js !! ~ Getting started with Ember.js more ~もっとはじめる Ember.js !! ~ Getting started with Ember.js more ~
もっとはじめる Ember.js !! ~ Getting started with Ember.js more ~
 
はじめる Ember.js!! ~ Getting started with ember.js ~
はじめる Ember.js!! ~ Getting started with ember.js ~はじめる Ember.js!! ~ Getting started with ember.js ~
はじめる Ember.js!! ~ Getting started with ember.js ~
 
How to relaunch "sapporojs.org" ~Introduction to middleman~
How to relaunch "sapporojs.org" ~Introduction to middleman~How to relaunch "sapporojs.org" ~Introduction to middleman~
How to relaunch "sapporojs.org" ~Introduction to middleman~
 
Introduction for Browser Side MVC
Introduction for Browser Side MVCIntroduction for Browser Side MVC
Introduction for Browser Side MVC
 
コミュニティのある風景
コミュニティのある風景コミュニティのある風景
コミュニティのある風景
 
capybara で快適なテスト生活を
capybara で快適なテスト生活をcapybara で快適なテスト生活を
capybara で快適なテスト生活を
 
Social coding をもっと楽しみたいあなたへ
Social coding をもっと楽しみたいあなたへSocial coding をもっと楽しみたいあなたへ
Social coding をもっと楽しみたいあなたへ
 
Node.jsってどうなの?
Node.jsってどうなの?Node.jsってどうなの?
Node.jsってどうなの?
 
アジャイル的アプローチから見えてきたこと
アジャイル的アプローチから見えてきたことアジャイル的アプローチから見えてきたこと
アジャイル的アプローチから見えてきたこと
 
脱レガシー化計画
脱レガシー化計画脱レガシー化計画
脱レガシー化計画
 
Pusherとcanvasで作るリアルタイムグラフ
Pusherとcanvasで作るリアルタイムグラフPusherとcanvasで作るリアルタイムグラフ
Pusherとcanvasで作るリアルタイムグラフ
 
ServerSideJavaScript
ServerSideJavaScriptServerSideJavaScript
ServerSideJavaScript
 

Último

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Último (20)

What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 

Clean Javascript

  • 1. Clean JavaScript http://www.flickr.com/photos/hoshikowolrd/5151171470/ Sapporo.js SaCSS vol.29 - 2011.11.26 (Ryunosuke SATO)
  • 2. Community for people who like JavaScript. Sapporo.js
  • 5.
  • 8.
  • 9. Clean JavaScript http://www.flickr.com/photos/hoshikowolrd/5151171470/ Sapporo.js SaCSS vol.29 - 2011.11.26 (Ryunosuke SATO)
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 23. JavaScript is most popular!
  • 27. ? ? How to face the difficulty
  • 28.
  • 29.
  • 33. point
  • 34. HTML JavaScript
  • 35. HTML JavaScript
  • 36. here! HTML JavaScript
  • 38. - Attach events from outer - problem JavaScript
  • 39. - Attach events from outer - solution HTML JavaScript
  • 40. - Attach events from outer - <a onclick=”showMessage()”>Click me</a> code smell
  • 41. - Attach events from outer - <a id=”showMessage”>Click me</a> var a = document.getElementById(‘showMessage’); a.addEventListener(‘click’, showMessage); improvement
  • 42. - Separate from Selector - problem HTML id class
  • 43. - Separate from Selector - solution HTML id class
  • 44. - Separate from Selector - function showPhoto(photoId) { var photo = document.getElementById(‘photo-’ + photoId); // do ... }
  • 45. - Separate from Selector - function showPhoto(photoId) { var photo = document.getElementById(‘photo-’ + photoId); // do ... } code smell
  • 46. - Separate from Selector - var showPhoto = function(element) { // do ... } var photo = document.getElementById(‘photo-12’); showPhoto(photo); improvement
  • 48. - modulized functions - solution
  • 49. - modulized functions - // users.js var showUserName = function() { // do somethig } var showUserAge = function(){ // do somethig } var validateUserForm = function() { // do somethig } code smell
  • 50. - modulized functions - // users.js var showUserName = function() { // do somethig } global var showUserAge = function(){ // do somethig } var validateUserForm = function() { // do somethig }
  • 51. - modulized functions - // users.js var users = {}; global users.showName = function () { // do somethig } users.showAge = function (){ // do somethig } users.validateForm = function () { // do somethig }
  • 52. - modulized functions - // users.js (function(global) { global.users = {}; global users.showName = function () { // do somethig } // ... )(this); improvement
  • 55. overwrite behavior - // using jQuery $(‘a#showDialog’).click(function() { $.ajax(‘/about’, { success: function(html) { // do something... } }); }); code smell
  • 56. overwrite behavior - // using jQuery $(‘a#showDialog’).click(function() { $.ajax($(this).attr(‘href’), { success: function(html) { // do something... } }); }); improvement
  • 58. shallow scope - solution 2 function → this
  • 59. shallow scope - // using jQuery var $elements = $(‘a#remote’); $elements.click(function() { var url = $(this).attr(‘href’); $.ajax(url, { success: function(html) { var text = $(html).text(); $element.text(text); } }); return false; });
  • 60. shallow scope - // using jQuery var $elements = $(‘a#remote’); $elements.click(function() { deep var url = $(this).attr(‘href’); $.ajax(url, { success: function(html) { var text = $(html).text(); $element.text(text); } }); return false; }); code smell
  • 61. shallow scope - // using jQuery var $elements = $(‘a#remote’); $elements.click(function() { var url = $(this).attr(‘href’); $.ajax(url, { success: function(html) { var text = $(html).text(); $(this).text(text); }, context: this }); return false; }); improvement
  • 62. DOM - DOM to model - problem DOM
  • 63. DOM - DOM to model - solution DOM
  • 64. DOM - DOM to model - var element = document.getElementById(‘message’); element.addEventListener(‘click’, function() { // this == element if (this.getAttribute(‘data-is-checked’)) { this.setAttribute(‘data-is-checked’, true); this.innerText = ‘clicked!’; } }); code smell
  • 65. DOM - DOM to model - var domToModel = function(element, Model) { var method, name, object, parent, proto; model = Object.create(element); proto = Model.prototype; for (name in proto) { method = proto[name]; model[name] = method; } Model.apply(model); return model; }; var CustomElement = function() {}; CustomElement.prototype.showText = function() { if (!this.getAttribute(‘data-is-checked’)) { var element = document.getElementById(‘message’); this.setAttribute(‘data-is-checked’, true); var model = domToModel(element, CustomElement); this.innerText = ‘clicked!’; model.addEventListener(‘click’, function() { } model.showText(); }; });
  • 66. DOM - DOM to model - var domToModel = function(element, Model) { var method, name, object, parent, proto; model = Object.create(element); proto = Model.prototype; for (name in proto) { method = proto[name]; model[name] = method; } Model.apply(model); return model; }; var CustomElement = function() {}; CustomElement.prototype.showText = function() { if (!this.getAttribute(‘data-is-checked’)) { var element = document.getElementById(‘message’); this.setAttribute(‘data-is-checked’, true); var model = domToModel(element, CustomElement); this.innerText = ‘clicked!’; model.addEventListener(‘click’, function() { } model.showText(); }; });
  • 67. DOM - DOM to model - var domToModel = function(element, Model) { var method, name, object, parent, proto; model = Object.create(element); proto = Model.prototype; for (name in proto) { method = proto[name]; model[name] = method; } Model.apply(model); return model; }; var CustomElement = function() {}; CustomElement.prototype.showText = function() { if (!this.getAttribute(‘data-is-checked’)) { var element = document.getElementById(‘message’); this.setAttribute(‘data-is-checked’, true); var model = domToModel(element, CustomElement); this.innerText = ‘clicked!’; model.addEventListener(‘click’, function() { } model.showText(); }; }); improvement
  • 68. - separate logic with view - problem
  • 69. - separate logic with view - solution
  • 70. - separate logic with view - function createTimer() { var timerId; var startTimer = function(millisec) { timerId = setTimeout(function() { $(‘.timeout’).text(‘finished’); }, millisec); } var stopTimer = function() { clearTimeout(timerId); } return { startTimer: startTimer, stopTimer: stopTimer } }
  • 71. - separate logic with view - function createTimer() { var timerId; var startTimer = function(millisec) { timerId = setTimeout(function() { $(‘.timeout’).text(‘finished’); view }, millisec); } var stopTimer = function() { clearTimeout(timerId); } return { startTimer: startTimer, stopTimer: stopTimer } } code smell
  • 72. - separate logic with view - function Timer(millisec) { this. millisec = millisec; this.callbacks = []; this.timerId = null; } Timer.prototype.afterFinish = function(callback) { return this.callbacks.push(callback); }; Timer.prototype.start = function() { var callbacks = this.callbacks; this.timerId = setTimeout(function() { var callback, i, length; for (i = 0, length = callbacks.length; i < length; i++) { var timer = new Timer(1000); callback = callbacks[i]; timer.afterFinish(function() { callback(); $('.timer .message').text('Finished!!'); } }); }, this. millisec); timer.start(); }; Timer.prototype.stop = function() { clearTimeout(this.timerId); }
  • 73. - separate logic with view - function Timer(millisec) { this. millisec = millisec; this.callbacks = []; } this.timerId = null; model Timer.prototype.afterFinish = function(callback) { return this.callbacks.push(callback); }; Timer.prototype.start = function() { view var callbacks = this.callbacks; this.timerId = setTimeout(function() { var callback, i, length; for (i = 0, length = callbacks.length; i < length; i++) { var timer = new Timer(1000); callback = callbacks[i]; timer.afterFinish(function() { callback(); $('.timer .message').text('Finished!!'); } }); }, this. millisec); timer.start(); }; Timer.prototype.stop = function() { clearTimeout(this.timerId); } improvement
  • 75.
  • 78.
  • 83.
  • 88.
  • 89. Shall we learn about Clean JavaScript?