JavaScript - Make the right choices

Preview:

DESCRIPTION

 

Citation preview

JavaScriptmake the right choices

Damian Wielgosik

about me ;-)

ferrante.plvarjs.com

http://twitter.com/varjs

1. Begin with ECMAScript

ECMAScript

sometimes it’s difficult...

... to speak in a human language

... znaleźć ludzki językDmitry Soshnikov

your personal ECMAScript teacher

Participate in the future!

Harmony - the next ECMAScript standard

mail-archive.com/es-discuss@mozilla.org/info.html

they need your feedback!

mail-archive.com/es-discuss@mozilla.org/info.html

where is your name?

2. Know your tools

Yes, we all know Firebug and Web Inspector

Hurt your feelings with jslint.com

Yes, we all know Firebug and Web Inspector

Aardwolf - mobile debugging made easy

Memory stats?

Memory?

WebKit Inspector

Memory leaks?

Memory leak checker

Performance?

sIEeve

home.orange.nl/jsrosman/

Memory leaks?

people.mozilla.com/~dbaron/leak-screencasts/

Performance?

var start = +new Date();for (var i = 0; i < 100000; i++);console.log("Result is: ", +new Date() - start);

Better?

console.time("My test"); for (var i = 0; i < 100000; i++); console.timeEnd("My test");

Still better?

console.profile("My test"); runApp();console.profileEnd("My test");

The best?

jsperf.com

jsperf.com

jsperf measures operations per second!

Get rid of jQuery if it’s not neccessary - there is http://microjs.com

Hunt on new stuff!

http://js.gd might be a good start!

3. Tips and tricks

it has to be said...

do not optimize prematurely!

do not optimize prematurely!

flickr.com/photos/paulmartincampbell/3583176306/sizes/o/in/photostream/

JavaScript !== Java

var obj = {}; // not new Object()var arr = []; // not new Array();

forget about your old habits!

do not port bad solutions to JavaScript!(aka I don’t need yet another class system in JS)

otherwise they’re gonna find you! ;-)

http://www.fotofaza.pl/podglad_zdjecia,15,ludzie,chuligani.html

4. Real tips and tricks

function calls cost time!

use JS asynchronously when needed

var arr = [ function() { console.log("A"); }, function() { throw new Error("boom!"); }, function() { console.log("B"); }, function() { console.log("C"); } ];

for (var i = 0, ilen = arr.length; i < ilen; i++) { arr[i]();}

oops?

var arr = [ function() { console.log("A"); }, function() { throw new Error("boom!"); }, function() { console.log("B"); }, function() { console.log("C"); } ];

for (var i = 0, ilen = arr.length; i < ilen; i++) { window.setTimeout(arr[i], 0);}

more interesting results

var fn = function() { console.log("a"); fn();};fn();

stack overflow?

let’s write own scheduler

var scheduler;(function() { var events = []; scheduler = { add : function(fn, delay) { for (var i = 0, ilen = events.length; i < ilen; i++) { if (events[i].fn === fn) { throw new Error("The event exists in the main event loop"); } } events.push({ fn : fn, delay: delay }); }, run: function() { for (var i = 0, ilen = events.length; i < ilen; i++) { (function(callback, delay) { var fn = function() { callback(); window.setTimeout(fn, delay); }; window.setTimeout(fn, delay); })(events[i].fn, events[i].delay); } } };})();

scheduler.add(function() { console.log("A"); }, 500); // it will call a function every 500msscheduler.add(function() { console.log("B"); }, 1000); // like above with 1000ms delayscheduler.run();

one loop to handle similar events

var eventLoop;(function() { var events = {}; eventLoop = { add : function(fn, delay) { if (!(delay in events)) { events[delay] = []; } else { for (var i = 0, ilen = events[delay].length; i < ilen; i++) { if (events[delay][i].fn === fn) { throw new Error("The event exists in the main event loop"); } } } events[delay].push(fn); }, run: function() { for (var delay in events) { (function(stack, delay) { var fn = function() { for (var i = 0, ilen = stack.length; i < ilen; i++) { stack[i](); } window.setTimeout(fn, delay); }; window.setTimeout(fn, delay); })(events[delay], delay); } } };})();

eventLoop.add(function() { console.log("A"); }, 500);eventLoop.add(function() { console.log("B"); }, 500);eventLoop.run();

var eventLoop;(function() { var events = {}; eventLoop = { add : function(fn, delay) { if (!(delay in events)) { events[delay] = []; } else { for (var i = 0, ilen = events[delay].length; i < ilen; i++) { if (events[delay][i].fn === fn) { throw new Error("The event exists in the main event loop"); } } } events[delay].push(fn); }, run: function() { for (var delay in events) { (function(stack, delay) { var fn = function() { for (var i = 0, ilen = stack.length; i < ilen; i++) { stack[i](); } window.setTimeout(fn, delay); }; window.setTimeout(fn, delay); })(events[delay], delay); } } };})();

eventLoop.add(function() { console.log("A"); }, 500);eventLoop.add(function() { console.log("B"); }, 500);eventLoop.run();

we don’t want to end up with big array indexes - we use the object instead of array

we have never added events for this delay so let’s make an array to store them

let’s store a single event by that

yep, you have to implement stop() method

Timers can be useful with AJAX requests

var throttle = function(fn, delay) { var timer = null; return function () { var context = this; var args = arguments; clearTimeout(timer); timer = setTimeout(function () { fn.apply(context, args); }, delay); };};

$('input.username').keypress(throttle(function (event) { // do the Ajax request}, 250));

http://remysharp.com/2010/07/21/throttling-function-calls/

parseInt(„09”) === 0

JS thinks „09” is an octal number because it starts with 0

parseInt(„09”, 10) === 9

However,parseFloat(„09”) === 9

However,parseFloat(„09”) === 9

document.querySelectorAll("div")returns a NodeList

not an array

var nodes = document.querySelectorAll("div");nodes = [].slice.apply(nodes);

However:„Whether the slice function can be applied successfully to a host object is

implementation-dependent.” - ECMAScript

Speaking of which, how to check if it’s an array?

var arr = [];arr instanceof Array;

Really?

var Array = function() {};var arr = [];arr instanceof Array; // FALSE!

Next?

var arr = [];if ("length" in arr) { // we deal with an array}

Really?

var arr = { "length": 2 };if ("length" in arr) { // we deal with an array... wait a moment!}

Next?

var arr = [];if (Object.prototype.toString.call(arr) === "[object Array]") { // Houston, we have an array}

Ok, but well, you can still modify a toString fn...

Object.prototype.toString = function() { return "";};

Here we go... ECMAScript 5!

var arr = [];if (Array.isArray(arr)) { // w00t!}

Hey, I can still replace it with my own stuff!

Array.isArray = function() { return false;}

Cache the most important functions at the very beginning!

(function() { var isArray = Array.isArray;})();

Or.. if you can, use ECMAScript 5 again

Object.defineProperty(Array, "isArray", { writable: false, configurable: false, enumerable: false, value: Array.isArray}); // thx to @marcoos

Hey, what is that ECMAScript 5 actually?

Hey, what is that ECMAScript actually?

Hey, we’re on mobile, do you have something for us?

yes, I can! Oh, I do.

Use window.scrollTo(0, 1) to get rid of the browser address bar on iOS!

/mobile/i.test(navigator.userAgent) && !location.hash && setTimeout(function () { if (!pageYOffset) window.scrollTo(0, 1);}, 1000);

thanks to amazing work by Remy Sharphttp://remysharp.com/2010/08/05/doing-it-right-skipping-

the-iphone-url-bar/

More?

Visit JSNews on Facebook for more awesomenesshttp://tinyurl.com/jsnewspl

or attend Front-Trends 2012 conferencehttp://front-trends.com

http://lanyrd.com/2012/ft2012/

but first of all, be smart and listen to smart people - there is a lot on the web

Thanks!Slides at:

http://varjs.com/make-right-choices

Recommended